[dart2wasm] Avoid using _Closure as a type

`_Closure` is the implementation class for function objects. When used
as a type, it translated to the same Wasm type as the `Function` type,
but in the type system it missed the special property of `Function`
that it is a supertype of all functions. Instead, it was translated
into an interface type, leading to incorrect type check results.

Thus, we must always use the `Function` type when referring to any
function.

The problem was hidden by the type check specialization for simple
interface type checks and exposed by `--verify-type-checks`.

Change-Id: I384d35506c0c8cd932ba789e977f8257e684b8d7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/336423
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Aske Simon Christensen <askesc@google.com>
This commit is contained in:
Aske Simon Christensen 2023-11-16 15:04:58 +00:00 committed by Commit Queue
parent c605dfc4e8
commit 4b880aec60
2 changed files with 6 additions and 3 deletions

View file

@ -734,6 +734,9 @@ class ConstantCreator extends ConstantVisitor<ConstantInfo?>
ConstantInfo? _makeInterfaceType(
TypeLiteralConstant constant, InterfaceType type, ClassInfo info) {
// Don't use `_Closure` as a type. Use `Function` instead, as this is
// properly recognized as the abstract function type.
assert(type.classNode != translator.closureClass);
InstanceConstant typeArgs = constants.makeTypeArray(type.typeArguments);
ensureConstant(typeArgs);
return createConstant(constant, info.nonNullableType, (function, b) {

View file

@ -14,13 +14,13 @@ final class _Closure implements Function {
@override
bool operator ==(Object other) {
if (other is! _Closure) {
if (other is! Function) {
return false;
}
return _equals(this, other);
}
external static bool _equals(_Closure a, _Closure b);
external static bool _equals(Function a, Function b);
// Simple hash code for now, we can optimize later
@override
@ -28,7 +28,7 @@ final class _Closure implements Function {
// Support dynamic tear-off of `.call` on functions
@pragma("wasm:entry-point")
_Closure get call => this;
Function get call => this;
@override
String toString() => 'Closure: $runtimeType';