HaxeFoundation / haxe

Haxe - The Cross-Platform Toolkit
https://haxe.org
6.04k stars 648 forks source link

[eval] Instance prototype not found: haxe.iterators.MapKeyValueIterator #9712

Closed Antriel closed 3 years ago

Antriel commented 4 years ago

Breaks on --interp, JS seems to work, didn't test others. Last working build https://github.com/HaxeFoundation/haxe/commit/fea3d93846bcef95538f06ad9e6c466befc83bb0. From https://github.com/HaxeFoundation/haxe/commit/dfcfd34e1aae24586f7da4cc160cf9de85ba2038 all to way to latest I get is [0] Instance prototype not found: haxe.iterators.MapKeyValueIterator.

function main() {
    var map = (['a' => 10]:Map<AbstractString, Int>);
    for (key => val in map) trace(key, val);
}

abstract AbstractString(String) from String { }

Oddly enough the project I extracted the issue from works with https://github.com/HaxeFoundation/haxe/commit/ef4098b78aaef6f0ae49402c6a5b1666640556cf, even though this sample does not. Still breaks on latest though.

RealyUniqueName commented 3 years ago

This happens because here https://github.com/HaxeFoundation/haxe/blob/82fd973277939006d32f34d728c295578c5c5831/src/context/abstractCast.ml#L272 underlying type cannot be figured out. Adding to String to AbstractString fixes it.

I think Map<AbstractString, Int> should not compile in the first place because Map has no @:from method, which returns something compatible with Map<AbstractString,Int>. @Simn what do you think?

Gama11 commented 3 years ago

Adding to String to AbstractString fixes it.

I think Map<AbstractString, Int> should not compile in the first place because Map has no @:from method, which returns something compatible with Map<AbstractString,Int>.

But what if you want to use an abstract as a map key without weakening its type safety for other uses? :/

nadako commented 3 years ago

But what if you want to use an abstract as a map key without weakening its type safety for other uses? :/

I share that concern. We discussed this issue somewhere else before. From the current type system rules standpoint, you should indeed add to String, but it's often undesired. Instead we should have some separate and/or explicit way to make such abstracts work for map implementation selection. One option could be to MapKey<String> or something, but I'm not sure if it's a good idea to require abstacts to define this just to be able to be used as a map key. I guess this is again goes into discussion about re-designing @:multiType.