COMMUNITY

Erase-generics screws up IMap casting in C#

Hi guys, today I encountered a strange problem. When working with colorMap of type Map<Int,UInt> like this:

var color:UInt = colorMap.get(index);

it transpiles to C# as

color = (((global::haxe.ds.IntMap) (global::haxe.ds.IntMap.__hx_cast(((global::haxe.ds.IntMap) (((global::haxe.IMap<int, uint>) (this.colorMap) )) ))) ).@get(index)).@value;

which is correct however if I define -D erase-generics it transpiles like this

color = ((uint) (global::haxe.lang.Runtime.toInt(((global::haxe.ds.IntMap) (((global::haxe.IMap) (this.colorMap) )) ).@get(((int) (index) )))) );

which is incorrect as it tries to cast UInt into Int and will fail for large UInts.

Any suggestions?
Thanks.

Well that seems to be a bug, tho are you sure it doesn’t work? I.e. is there an actual failing case? Because int and uint should have the same in-memory representation. If that’s not the case - please report an issue. C# target is a bit undermaintained at the moment, but we still want to be aware of all the casting cases for the potential CIL target ^^

1 Like

It actually fails in C# when I send a -1 there for some reason, which was surprising due to the as you said same memory representation. It fails with overflow

onUncaughtError : [{ id : 0, message : OverflowException: Value was either too large or too small for an Int32., stackTrace : System.Convert.ToInt32 (System.UInt32 value) (at <437ba245d8404784b9fbab9b439ac908>:0)
System.UInt32.System.IConvertible.ToInt32 (System.IFormatProvider provider) (at <437ba245d8404784b9fbab9b439ac908>:0)
haxe.lang.Runtime.toInt (System.Object obj) (at C:/HaxeToolkit/haxe/std/cs/internal/Runtime.hx:146)