HaxeFoundation / haxe

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

An EitherType constraint causes oddities when used as a map key #11401

Open YellowAfterlife opened 10 months ago

YellowAfterlife commented 10 months ago

Sample:

import haxe.extern.EitherType;

@:keep class Test {
    static function main() {
        var tc = new Impl<ETest>();
        trace(tc.labels[One]);
    }
}
abstract class Base<T:EitherType<EnumValue, String>> {
    public var labels:Map<T, String> = new Map();
    public function new() {}
}
class Impl<T:EnumValue> extends Base<T> {

}
enum ETest {
    One;
    Two;
}

So, two things:

  1. Perhaps this should not compile unless there's a multitype that can accept both key types.
  2. On JS with -dce full, this results in compiler picking StringMap but culling its get() method, causing a runtime error.
kLabz commented 10 months ago

EitherType is meant to be used to describe types when writing externs (hence the package name), but won't provide good typing for actual code.

It is useful for interfacing with external code on dynamic platforms such as JavaScript or Python. Otherwise, use of this type is discouraged.

YellowAfterlife commented 10 months ago

That is true - I was a little too quick trying to retrofit existing code (which, for the most part, passes values to external JS) to also accept strings/arrays of strings (instead of Haxe enums) coming from external JS, and did not think about the implications until I got the code to run.