Open waneck opened 9 years ago
I'm not sure what you want from me here, type parameters have always been invariant and Dynamic is no exception there.
You're right. It has always been like that, my bad. But there's something weird going on with the typer. See the following case:
class Main
{
static function main()
{
var vec = new haxe.ds.Vector<Dynamic>(10);
var t:NotArray<{}> = test(vec.toData());
}
inline public static function test<T>(arr:cs.NativeArray<T>):NotArray<T>
{
return new NotArray(arr);
}
}
class NotArray<T>
{
public var arr:cs.NativeArray<T>;
public function new(nv:cs.NativeArray<T>)
{
this.arr = nv;
}
}
This when compiled with -D dump
gives the following:
[Var t(2503):NotArray<{ }>]
[New:NotArray<{ }>]
NotArray<{ }>
[Cast:haxe.ds._Vector.VectorData<Dynamic>] [Cast:haxe.ds._Vector.VectorData<Dynamic>] [Local vec(2494):haxe.ds.Vector<Dynamic>]
As you can see, NativeArray<Dynamic>
is used in an argument that was expected to be NativeArray<{}>
. When trying to find which overload was used, the two types don't unify anymore so gencommon can't determine.
Interestingly, if we replace var t:NotArray<{}> = test(vec.toData());
with var t = new NotArray<{}>(vec.toData())
, the error haxe.ds._Vector.VectorData<Dynamic> should be cs.NativeArray<{ }>
pops up as expected
So this is about inlining, right?
This happens because Dynamic is never bound to a monomorph. test.T remains a monomorph throughout the inlining of test because the only unification happening is NativeArray<Unknown<0>>
vs. NativeArray<Dynamic>
(the function argument). This means you get NotArray<Unknown<0>>
as a return type which is ultimately unified with the explicit NotArray<{}>
.
Also I have no idea what to do about that.
Strangely, while tackling #4001 , it seems that the following is invalid:
This fails now with:
Not that I'm advocating for
<Dynamic>
to be how it was. But this was a recent change, wasn't it? Is this intentional?