COMMUNITY

Abstracts must be implicitly cast in Haxe 4.2.0?

It seems that implicit cast for abstracts is not working in 4.2.0, while it is in 4.1.5.
I looked at 4.2.0 changelog and didn’t find a change that might be related to this (maybe the very first one: “implemented ‘classic’ abstracts…” ?).

Is this a bug or did I miss something in the changelog and the Haxe evolution path?

I’d love to submit a TryHaxe link with example here, but TryHaxe uses version 3.4.4 and I don’t see a way to select Haxe version on there, so here is a sample code that reproduces the issue:

typedef SizeBoxType = {
    var width: Int;
    var height: Int;
}

@:forward(width, height)
abstract SizeBox(SizeBoxType) from SizeBoxType to SizeBoxType {

    public inline function new() {
        this = {width: 0, height: 0};
    }

    @:from
    static public function fromSizeBoxType( a : SizeBoxType ) : SizeBox {
        return fromValues( a.width, a.height );
    }
    @:to
    public function toSizeBoxType() : SizeBoxType {
        return { width: this.width, height: this.height };
    }

    public static function fromValues( w : Int, h : Int ) : SizeBox {
        final out = new SizeBox();
        out.width = w;
        out.height = h;
        return out;
    }
}



typedef PositionBoxType = {
    var x : Float;
    var y : Float;
}

@:forward(x, y)
abstract PositionBox(PositionBoxType) from PositionBoxType to PositionBoxType {

    public inline function new() {
        this = {x: 0., y: 0.};
    }

    @:from
    static public function fromPositionBoxType( a : PositionBoxType ) : PositionBox {
        return fromValues( a.x, a.y );
    }
    @:to
    public function toPositionBoxType() : PositionBoxType {
        return { x: this.x, y: this.y };
    }

    @:from
    static public function fromSizeBoxType( a : SizeBoxType ) : PositionBox {
        return fromValues( a.width, a.height );
    }

    public static function fromValues( x : Float, y : Float ) : PositionBox {
        final out = new PositionBox();
        out.x = x;
        out.y = y;
        return out;
    }
}


class Bug {
    public static function main() {
        trace('a cloud? an airplane? a bug?');

        var pb : PositionBox = { x: 5., y: 5.};
        trace( pb );

        var sb : SizeBox = SizeBox.fromValues( 10, 10 );
        // This line won't compile in 4.2.0, it will in 4.1.5
        pb = sb;
        // This compiles in 4.2.0, maybe I need to explicitly cast abstracts from now on?
        // pb = cast sb;
        trace( pb );
    }
}

Haxe 4.2.0:

$ haxe -cp . --run Bug
Bug.hx:74: characters 9-16 : SizeBox should be PositionBox

haxe 4.1.5

haxe -cp . --run Bug
Bug.hx:69: a cloud? an airplane? a bug?
Bug.hx:71: {x: 5, y: 5}
Bug.hx:75: {x: 10, y: 10}

There’s no direct cast from SizeBox to PositionBox. It is a transitive cast as SizeBoxSizeBoxTypePositionBox. For that to work beyond Haxe 4.2 you need to add @:transitive to either SizeBox or PositionBox.

1 Like