COMMUNITY

Hl can't cast ArrayObj to ArrayBytes

haxe-hl

#1
class Bug1 {
    public static function randomChoice( chances:Map<String,Int>):String {
        var keys = [ for ( i in chances.keys() ) i ];
        var values /*:Array<Int>*/ = [ for ( i in keys ) chances[ i ] ];
        return keys[ randomChoiceIndex( values ) ];
    }

    public static function randomChoiceIndex( chances:Array<Int>):Int {
        var dice = Std.random( Lambda.fold( chances, function (x,y) return x + y, 0 ) ) + 1;
        var sum = 0;
        var choice = 0;
        for ( w in chances ) {
            sum += w;
            if ( dice <= sum ) {
                return choice;
            }
            choice++;
        }
        return choice;
    }

    static function main() {
        trace( randomChoice( [ 'test' => 1 ] ) );
    }
}

Produces

Uncaught exception: Can't cast #hl.types.ArrayObj to #hl.types.ArrayBytes_Int
Called from $Bug1.randomChoice(Bug1.hx:6)
Called from $Bug1.main(Bug1.hx:24)
Called from fun$362(?:1)

Uncommenting the comment fixes the issue.
preview 5 with hl is 1.9 from 27.11.2018


(Jens Fischer) #2

Without the Array<Int> type hint, it’s inferred as Array<Null<Int>>:

This is because accessing map elements is typed as Null<T>, since the result can be null even if the map contains basic, non-nullable types:

It’s the same issue as https://github.com/HaxeFoundation/haxe/issues/6785 - HL doesn’t allow assigning Array<Null<T>> to Array<T> (while most / all other targets do).