Using abstract with implicit cast to Int for array access

Hello,

As can be seen in this try haxe snippet, implicitly casting an abstract to Int to access elements of an array only seem to work for direct implicit cast (from Int to Int). If my implicit cast is defined via a method, it won’t compile, as it seems unable to unify my abstract to Int correctly.

I cannot find anything in the doc refering to this, is there a caveat that I missed, like a metadata to add on my method?

That really is weird. It definitely has something to do with the fact that the array access syntax sometimes supports non-integers. So Haxe doesn’t coerce your abstract to Int because it thinks, maybe it doesn’t have to be an Int. Then later on it realizes, no, it does have to be an Int, but by then it’s too late.

This is all educated guesswork, but I also correctly guessed a workaround, so I’d like to think my guesses are pretty good.

That is indeed super weird.
My workaround is similar to yours, in that I defined 2 abstract MapOfMyAbstract and ArrayOfMyAbstract, but in it I used my type explicitly, and explicitly called the .toInt().
It would have never occured to me that what you did would work :confused:

Sometimes all you need to do is explicitly tell the compiler what type to use. Even when it already knows what type to use. (Yet another benefit of always declaring variable types.)

This is probably because you are using Standard Types but still this is unexpected have you filled an issue in Haxe repository?

Welcome PapyGarago,
This seems a limitation of Haxe abstract types, there are many complex edge cases with type conversion that may well be impossible for the compiler to fully reconcile with our individual understanding and wishlist, making changes to the compiler can result if different failures and my guess may well not be worth making.
Details from what we expect may differ from what is possible with the AST or approach used. However Haxe provides tools to work round most of these limitations, either using an intermediate variable such as your i, or via what I will term a compiler type cast hint.

But we can help the compiler to provide what we require by forcing conversion.

trace( array( ( cf: Int ) ) );

or in your specific case we can also use the ‘to’ method directly.

trace( array( cf.toInt() ) );

please do let me know if my solutions do not fully cover your use case I may well not have fully understood your test code and requirements.