Description
As part of the unification of StaticArray
's static and instance methods in #2404, now accounting for both Array<T>
and StaticArray<T>
results via a type parameter in instance methods, code like the following was introduced:
let out!: U;
if (out instanceof Array<T>) {
out = changetype<U>(__newArray(length, alignof<T>(), idof<Array<T>>()));
} else if (out instanceof StaticArray<T>) {
out = changetype<U>(__new(size, idof<StaticArray<T>>()));
} else {
ERROR(...)
}
where U
is also the return type of the respective function. This code is brittle for several reasons:
1) If an U
triggers a dynamic instanceof check, null
is passed to the instanceof helper, exploding with an OOB memory access. This can potentially be addressed with a hack like
let out = changetype<U>(this);
so there is at least some value, which would also work with #2578 (where I noticed this) once merged, BUT will stop working with Wasm GC because the assignment is invalid codegen.
2) Both concat<U>
and slice<U>
return U
, but the actual value returned is either Array<T>
or StaticArray<T>
that is merely changetype'd to U
, which is unsound if U
is a subclass. Not an issue for StaticArray
since it is final, but for Array
. Even if an U
would be __new
ed, the subclass would not always be properly initialized because the constructor isn't called.
3) As mentioned, tricks like these likely won't work forever anyhow.
These seem like reasons to me to revert the PR in question, unless there is a solution I haven't thought of. cc @MaxGraey as the author of the code.