Version 2.14.0-345.0.dev
Merge commit '3b1e83387fe7e1b03df9259d2dae3f6f8207abfa' into 'dev'
diff --git a/pkg/compiler/lib/src/ir/impact.dart b/pkg/compiler/lib/src/ir/impact.dart
index 8339c43..16fbc15 100644
--- a/pkg/compiler/lib/src/ir/impact.dart
+++ b/pkg/compiler/lib/src/ir/impact.dart
@@ -678,7 +678,8 @@
@override
void handleConstantExpression(ir.ConstantExpression node) {
ir.LibraryDependency import = getDeferredImport(node);
- new ConstantImpactVisitor(this, import, node).visitConstant(node.constant);
+ new ConstantImpactVisitor(this, import, node, staticTypeContext)
+ .visitConstant(node.constant);
}
}
@@ -727,8 +728,10 @@
final ImpactRegistry registry;
final ir.LibraryDependency import;
final ir.ConstantExpression expression;
+ final ir.StaticTypeContext staticTypeContext;
- ConstantImpactVisitor(this.registry, this.import, this.expression);
+ ConstantImpactVisitor(
+ this.registry, this.import, this.expression, this.staticTypeContext);
@override
void defaultConstant(ir.Constant node) {
@@ -755,9 +758,7 @@
@override
void visitInstantiationConstant(ir.InstantiationConstant node) {
registry.registerGenericInstantiation(
- node.tearOffConstant.function.computeFunctionType(
- node.tearOffConstant.target.enclosingLibrary.nonNullable),
- node.types);
+ node.tearOffConstant.getType(staticTypeContext), node.types);
visitConstant(node.tearOffConstant);
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index 08e70bf..653af5c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -714,6 +714,11 @@
}
@override
+ TreeNode visitTypedefTearOff(TypedefTearOff node, TreeNode? removalSentinel) {
+ return evaluateAndTransformWithContext(node, node);
+ }
+
+ @override
TreeNode visitInstantiation(Instantiation node, TreeNode? removalSentinel) {
Instantiation result =
super.visitInstantiation(node, removalSentinel) as Instantiation;
@@ -3387,43 +3392,38 @@
new Instantiation(extract(constant),
node.typeArguments.map((t) => env.substituteType(t)).toList()));
}
+ List<TypeParameter>? typeParameters;
if (constant is TearOffConstant) {
Member target = constant.target;
- List<TypeParameter>? typeParameters;
if (target is Procedure) {
typeParameters = target.function.typeParameters;
} else if (target is Constructor) {
typeParameters = target.enclosingClass.typeParameters;
}
- if (typeParameters != null) {
- if (node.typeArguments.length == typeParameters.length) {
- List<DartType>? types = _evaluateDartTypes(node, node.typeArguments);
- if (types == null) {
- AbortConstant error = _gotError!;
- _gotError = null;
- return error;
- }
- assert(_gotError == null);
- // ignore: unnecessary_null_comparison
- assert(types != null);
-
- final List<DartType> typeArguments = convertTypes(types);
- return canonicalize(
- new InstantiationConstant(constant, typeArguments));
- } else {
- // Probably unreachable.
- return createInvalidExpressionConstant(
- node,
- 'The number of type arguments supplied in the partial '
- 'instantiation does not match the number of type arguments '
- 'of the $constant.');
+ } else if (constant is TypedefTearOffConstant) {
+ typeParameters = constant.parameters;
+ }
+ if (typeParameters != null) {
+ if (node.typeArguments.length == typeParameters.length) {
+ List<DartType>? types = _evaluateDartTypes(node, node.typeArguments);
+ if (types == null) {
+ AbortConstant error = _gotError!;
+ _gotError = null;
+ return error;
}
+ assert(_gotError == null);
+ // ignore: unnecessary_null_comparison
+ assert(types != null);
+
+ final List<DartType> typeArguments = convertTypes(types);
+ return canonicalize(new InstantiationConstant(constant, typeArguments));
} else {
// Probably unreachable.
return createInvalidExpressionConstant(
node,
- "Unsupported kind of a torn off member: "
- "'${target.runtimeType}'.");
+ 'The number of type arguments supplied in the partial '
+ 'instantiation does not match the number of type arguments '
+ 'of the $constant.');
}
}
// The inner expression in an instantiation can never be null, since
@@ -3445,7 +3445,23 @@
@override
Constant visitTypedefTearOff(TypedefTearOff node) {
- return defaultExpression(node);
+ final Constant constant = _evaluateSubexpression(node.expression);
+ if (constant is TearOffConstant) {
+ FreshTypeParameters freshTypeParameters =
+ getFreshTypeParameters(node.typeParameters);
+ List<TypeParameter> typeParameters =
+ freshTypeParameters.freshTypeParameters;
+ List<DartType> typeArguments = new List<DartType>.generate(
+ node.typeArguments.length,
+ (int i) => freshTypeParameters.substitute(node.typeArguments[i]),
+ growable: false);
+ return canonicalize(
+ new TypedefTearOffConstant(typeParameters, constant, typeArguments));
+ } else {
+ // Probably unreachable.
+ return createInvalidExpressionConstant(
+ node, "Unexpected typedef tearoff target: ${constant}.");
+ }
}
@override
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 7363aa8..a378dec 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -1403,7 +1403,7 @@
KernelDiagnosticReporter(this.loader);
- void report(Message message, int charOffset, int length, Uri fileUri,
+ void report(Message message, int charOffset, int length, Uri? fileUri,
{List<LocatedMessage>? context}) {
loader.addProblem(message, charOffset, noLength, fileUri, context: context);
}
diff --git a/pkg/front_end/lib/src/testing/id_testing_utils.dart b/pkg/front_end/lib/src/testing/id_testing_utils.dart
index 59a5c83..0067517 100644
--- a/pkg/front_end/lib/src/testing/id_testing_utils.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_utils.dart
@@ -415,7 +415,12 @@
void visitInstantiationConstant(InstantiationConstant node) {
sb.write('Instantiation(');
- sb.write(getMemberName(node.tearOffConstant.target));
+ Constant tearOffConstant = node.tearOffConstant;
+ if (tearOffConstant is TearOffConstant) {
+ sb.write(getMemberName(tearOffConstant.target));
+ } else {
+ visit(tearOffConstant);
+ }
sb.write('<');
typeToText.visitList(node.types);
sb.write('>)');
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart
new file mode 100644
index 0000000..e832879f
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A<T> {
+ A();
+ factory A.fact() => new A();
+ factory A.redirect() = A;
+}
+
+typedef B<T> = A<T>;
+typedef C<T> = A<int>;
+
+const a = A.new;
+const b = A<int>.new;
+const c = A.fact;
+const d = A<int>.fact;
+const e = A.redirect;
+const f = A<int>.redirect;
+const g = B.new;
+const h = B<int>.new;
+const i = B.fact;
+const j = B<int>.fact;
+const k = B.redirect;
+const l = B<int>.redirect;
+const m = C.new;
+const n = C<int>.new;
+const o = C.fact;
+const p = C<int>.fact;
+const q = C.redirect;
+const r = C<int>.redirect;
+
+main() {
+ var a = A.new;
+ var b = A<int>.new;
+ var c = A.fact;
+ var d = A<int>.fact;
+ var e = A.redirect;
+ var f = A<int>.redirect;
+ var g = B.new;
+ var h = B<int>.new;
+ var i = B.fact;
+ var j = B<int>.fact;
+ var k = B.redirect;
+ var l = B<int>.redirect;
+ var m = C.new;
+ var n = C<int>.new;
+ var o = C.fact;
+ var p = C<int>.fact;
+ var q = C.redirect;
+ var r = C<int>.redirect;
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.expect
new file mode 100644
index 0000000..cfec78a
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.expect
@@ -0,0 +1,66 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef B<T extends core::Object? = dynamic> = self::A<T%>;
+typedef C<unrelated T extends core::Object? = dynamic> = self::A<core::int>;
+class A<T extends core::Object? = dynamic> extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[self::A::redirect]/*isLegacy*/;
+ constructor •() → self::A<self::A::T%>
+ : super core::Object::•()
+ ;
+ static factory fact<T extends core::Object? = dynamic>() → self::A<self::A::fact::T%>
+ return new self::A::•<self::A::fact::T%>();
+ static factory redirect<T extends core::Object? = dynamic>() → self::A<self::A::redirect::T%>
+ let dynamic #redirecting_factory = self::A::• in let self::A::redirect::T% #typeArg0 = null in invalid-expression;
+}
+static const field <T extends core::Object? = dynamic>() → self::A<T%> a = #C1;
+static const field () → self::A<core::int> b = #C2;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> c = #C3;
+static const field () → self::A<core::int> d = #C4;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> e = #C5;
+static const field () → self::A<core::int> f = #C6;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> g = #C1;
+static const field () → self::A<core::int> h = #C2;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> i = #C3;
+static const field () → self::A<core::int> j = #C4;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> k = #C5;
+static const field () → self::A<core::int> l = #C6;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> m = #C7;
+static const field () → self::A<core::int> n = #C2;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> o = #C8;
+static const field () → self::A<core::int> p = #C4;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
+static const field () → self::A<core::int> r = #C6;
+static method main() → dynamic {
+ <T extends core::Object? = dynamic>() → self::A<T%> a = #C1;
+ () → self::A<core::int> b = #C2;
+ <T extends core::Object? = dynamic>() → self::A<T%> c = #C3;
+ () → self::A<core::int> d = #C4;
+ <T extends core::Object? = dynamic>() → self::A<T%> e = #C5;
+ () → self::A<core::int> f = #C6;
+ <T extends core::Object? = dynamic>() → self::A<T%> g = #C1;
+ () → self::A<core::int> h = #C2;
+ <T extends core::Object? = dynamic>() → self::A<T%> i = #C3;
+ () → self::A<core::int> j = #C4;
+ <T extends core::Object? = dynamic>() → self::A<T%> k = #C5;
+ () → self::A<core::int> l = #C6;
+ <unrelated T extends core::Object? = dynamic>() → self::A<core::int> m = #C7;
+ () → self::A<core::int> n = #C2;
+ <unrelated T extends core::Object? = dynamic>() → self::A<core::int> o = #C8;
+ () → self::A<core::int> p = #C4;
+ <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
+ () → self::A<core::int> r = #C6;
+}
+
+constants {
+ #C1 = constructor-tearoff self::A::•
+ #C2 = instantiation self::A::• <core::int>
+ #C3 = static-tearoff self::A::fact
+ #C4 = instantiation self::A::fact <core::int>
+ #C5 = redirecting-factory-tearoff self::A::redirect
+ #C6 = instantiation self::A::redirect <core::int>
+ #C7 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
+ #C8 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C3<core::int>)
+ #C9 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C5<core::int>)
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.transformed.expect
new file mode 100644
index 0000000..d84286f
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.transformed.expect
@@ -0,0 +1,66 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef B<T extends core::Object? = dynamic> = self::A<T%>;
+typedef C<unrelated T extends core::Object? = dynamic> = self::A<core::int>;
+class A<T extends core::Object? = dynamic> extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[self::A::redirect]/*isLegacy*/;
+ constructor •() → self::A<self::A::T%>
+ : super core::Object::•()
+ ;
+ static factory fact<T extends core::Object? = dynamic>() → self::A<self::A::fact::T%>
+ return new self::A::•<self::A::fact::T%>();
+ static factory redirect<T extends core::Object? = dynamic>() → self::A<self::A::redirect::T%>
+ let Never #redirecting_factory = self::A::• in let self::A::redirect::T% #typeArg0 = null in invalid-expression;
+}
+static const field <T extends core::Object? = dynamic>() → self::A<T%> a = #C1;
+static const field () → self::A<core::int> b = #C2;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> c = #C3;
+static const field () → self::A<core::int> d = #C4;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> e = #C5;
+static const field () → self::A<core::int> f = #C6;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> g = #C1;
+static const field () → self::A<core::int> h = #C2;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> i = #C3;
+static const field () → self::A<core::int> j = #C4;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> k = #C5;
+static const field () → self::A<core::int> l = #C6;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> m = #C7;
+static const field () → self::A<core::int> n = #C2;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> o = #C8;
+static const field () → self::A<core::int> p = #C4;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
+static const field () → self::A<core::int> r = #C6;
+static method main() → dynamic {
+ <T extends core::Object? = dynamic>() → self::A<T%> a = #C1;
+ () → self::A<core::int> b = #C2;
+ <T extends core::Object? = dynamic>() → self::A<T%> c = #C3;
+ () → self::A<core::int> d = #C4;
+ <T extends core::Object? = dynamic>() → self::A<T%> e = #C5;
+ () → self::A<core::int> f = #C6;
+ <T extends core::Object? = dynamic>() → self::A<T%> g = #C1;
+ () → self::A<core::int> h = #C2;
+ <T extends core::Object? = dynamic>() → self::A<T%> i = #C3;
+ () → self::A<core::int> j = #C4;
+ <T extends core::Object? = dynamic>() → self::A<T%> k = #C5;
+ () → self::A<core::int> l = #C6;
+ <unrelated T extends core::Object? = dynamic>() → self::A<core::int> m = #C7;
+ () → self::A<core::int> n = #C2;
+ <unrelated T extends core::Object? = dynamic>() → self::A<core::int> o = #C8;
+ () → self::A<core::int> p = #C4;
+ <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
+ () → self::A<core::int> r = #C6;
+}
+
+constants {
+ #C1 = constructor-tearoff self::A::•
+ #C2 = instantiation self::A::• <core::int>
+ #C3 = static-tearoff self::A::fact
+ #C4 = instantiation self::A::fact <core::int>
+ #C5 = redirecting-factory-tearoff self::A::redirect
+ #C6 = instantiation self::A::redirect <core::int>
+ #C7 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
+ #C8 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C3<core::int>)
+ #C9 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C5<core::int>)
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..a4b6c13
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.textual_outline.expect
@@ -0,0 +1,26 @@
+class A<T> {
+ A();
+ factory A.fact() => new A();
+ factory A.redirect() = A;
+}
+typedef B<T> = A<T>;
+typedef C<T> = A<int>;
+const a = A.new;
+const b = A<int>.new;
+const c = A.fact;
+const d = A<int>.fact;
+const e = A.redirect;
+const f = A<int>.redirect;
+const g = B.new;
+const h = B<int>.new;
+const i = B.fact;
+const j = B<int>.fact;
+const k = B.redirect;
+const l = B<int>.redirect;
+const m = C.new;
+const n = C<int>.new;
+const o = C.fact;
+const p = C<int>.fact;
+const q = C.redirect;
+const r = C<int>.redirect;
+main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.expect
new file mode 100644
index 0000000..7412c43
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.expect
@@ -0,0 +1,66 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef B<T extends core::Object? = dynamic> = self::A<T%>;
+typedef C<unrelated T extends core::Object? = dynamic> = self::A<core::int>;
+class A<T extends core::Object? = dynamic> extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[self::A::redirect]/*isLegacy*/;
+ constructor •() → self::A<self::A::T%>
+ : super core::Object::•()
+ ;
+ static factory fact<T extends core::Object? = dynamic>() → self::A<self::A::fact::T%>
+ return new self::A::•<self::A::fact::T%>();
+ static factory redirect<T extends core::Object? = dynamic>() → self::A<self::A::redirect::T%>
+ let dynamic #redirecting_factory = self::A::• in let self::A::redirect::T% #typeArg0 = null in invalid-expression;
+}
+static const field <T extends core::Object? = dynamic>() → self::A<T%> a = #C1;
+static const field () → self::A<core::int> b = #C2;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> c = #C3;
+static const field () → self::A<core::int> d = #C4;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> e = #C5;
+static const field () → self::A<core::int> f = #C6;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> g = #C1;
+static const field () → self::A<core::int> h = #C2;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> i = #C3;
+static const field () → self::A<core::int> j = #C4;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> k = #C5;
+static const field () → self::A<core::int> l = #C6;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> m = #C7;
+static const field () → self::A<core::int> n = #C2;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> o = #C8;
+static const field () → self::A<core::int> p = #C4;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
+static const field () → self::A<core::int> r = #C6;
+static method main() → dynamic {
+ <T extends core::Object? = dynamic>() → self::A<T%> a = #C1;
+ () → self::A<core::int> b = #C2;
+ <T extends core::Object? = dynamic>() → self::A<T%> c = #C3;
+ () → self::A<core::int> d = #C4;
+ <T extends core::Object? = dynamic>() → self::A<T%> e = #C5;
+ () → self::A<core::int> f = #C6;
+ <T extends core::Object? = dynamic>() → self::A<T%> g = #C1;
+ () → self::A<core::int> h = #C2;
+ <T extends core::Object? = dynamic>() → self::A<T%> i = #C3;
+ () → self::A<core::int> j = #C4;
+ <T extends core::Object? = dynamic>() → self::A<T%> k = #C5;
+ () → self::A<core::int> l = #C6;
+ <unrelated T extends core::Object? = dynamic>() → self::A<core::int> m = #C7;
+ () → self::A<core::int> n = #C2;
+ <unrelated T extends core::Object? = dynamic>() → self::A<core::int> o = #C8;
+ () → self::A<core::int> p = #C4;
+ <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
+ () → self::A<core::int> r = #C6;
+}
+
+constants {
+ #C1 = constructor-tearoff self::A::•
+ #C2 = instantiation self::A::• <core::int*>
+ #C3 = static-tearoff self::A::fact
+ #C4 = instantiation self::A::fact <core::int*>
+ #C5 = redirecting-factory-tearoff self::A::redirect
+ #C6 = instantiation self::A::redirect <core::int*>
+ #C7 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
+ #C8 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C3<core::int>)
+ #C9 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C5<core::int>)
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.outline.expect
new file mode 100644
index 0000000..8c8090d
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.outline.expect
@@ -0,0 +1,57 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef B<T extends core::Object? = dynamic> = self::A<T%>;
+typedef C<unrelated T extends core::Object? = dynamic> = self::A<core::int>;
+class A<T extends core::Object? = dynamic> extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[self::A::redirect]/*isLegacy*/;
+ constructor •() → self::A<self::A::T%>
+ ;
+ static factory fact<T extends core::Object? = dynamic>() → self::A<self::A::fact::T%>
+ ;
+ static factory redirect<T extends core::Object? = dynamic>() → self::A<self::A::redirect::T%>
+ let dynamic #redirecting_factory = self::A::• in let self::A::redirect::T% #typeArg0 = null in invalid-expression;
+}
+static const field <T extends core::Object? = dynamic>() → self::A<T%> a = self::A::•;
+static const field () → self::A<core::int> b = self::A::•<core::int>;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> c = self::A::fact;
+static const field () → self::A<core::int> d = self::A::fact<core::int>;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> e = self::A::redirect;
+static const field () → self::A<core::int> f = self::A::redirect<core::int>;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> g = self::A::•;
+static const field () → self::A<core::int> h = self::A::•<core::int>;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> i = self::A::fact;
+static const field () → self::A<core::int> j = self::A::fact<core::int>;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> k = self::A::redirect;
+static const field () → self::A<core::int> l = self::A::redirect<core::int>;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> m = <unrelated T extends core::Object? = dynamic>.(self::A::•<core::int>);
+static const field () → self::A<core::int> n = self::A::•<core::int>;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> o = <unrelated T extends core::Object? = dynamic>.(self::A::fact<core::int>);
+static const field () → self::A<core::int> p = self::A::fact<core::int>;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = <unrelated T extends core::Object? = dynamic>.(self::A::redirect<core::int>);
+static const field () → self::A<core::int> r = self::A::redirect<core::int>;
+static method main() → dynamic
+ ;
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///const_tear_off.dart:14:11 -> ConstructorTearOffConstant(A.)
+Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:15:11 -> InstantiationConstant(A.<int*>)
+Evaluated: StaticTearOff @ org-dartlang-testcase:///const_tear_off.dart:16:11 -> StaticTearOffConstant(A.fact)
+Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:17:11 -> InstantiationConstant(A.fact<int*>)
+Evaluated: RedirectingFactoryTearOff @ org-dartlang-testcase:///const_tear_off.dart:18:11 -> RedirectingFactoryTearOffConstant(A.redirect)
+Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:19:11 -> InstantiationConstant(A.redirect<int*>)
+Evaluated: ConstructorTearOff @ org-dartlang-testcase:///const_tear_off.dart:20:11 -> ConstructorTearOffConstant(A.)
+Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:21:11 -> InstantiationConstant(A.<int*>)
+Evaluated: StaticTearOff @ org-dartlang-testcase:///const_tear_off.dart:22:11 -> StaticTearOffConstant(A.fact)
+Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:23:11 -> InstantiationConstant(A.fact<int*>)
+Evaluated: RedirectingFactoryTearOff @ org-dartlang-testcase:///const_tear_off.dart:24:11 -> RedirectingFactoryTearOffConstant(A.redirect)
+Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:25:11 -> InstantiationConstant(A.redirect<int*>)
+Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:26:11 -> TypedefTearOffConstant(A.<T><int>)
+Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:27:11 -> InstantiationConstant(A.<int*>)
+Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:28:11 -> TypedefTearOffConstant(A.fact<T><int>)
+Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:29:11 -> InstantiationConstant(A.fact<int*>)
+Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:30:11 -> TypedefTearOffConstant(A.redirect<T><int>)
+Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:31:11 -> InstantiationConstant(A.redirect<int*>)
+Extra constant evaluation: evaluated: 23, effectively constant: 18
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.transformed.expect
new file mode 100644
index 0000000..0a0394c
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.transformed.expect
@@ -0,0 +1,66 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef B<T extends core::Object? = dynamic> = self::A<T%>;
+typedef C<unrelated T extends core::Object? = dynamic> = self::A<core::int>;
+class A<T extends core::Object? = dynamic> extends core::Object {
+ static final field dynamic _redirecting# = <dynamic>[self::A::redirect]/*isLegacy*/;
+ constructor •() → self::A<self::A::T%>
+ : super core::Object::•()
+ ;
+ static factory fact<T extends core::Object? = dynamic>() → self::A<self::A::fact::T%>
+ return new self::A::•<self::A::fact::T%>();
+ static factory redirect<T extends core::Object? = dynamic>() → self::A<self::A::redirect::T%>
+ let Never #redirecting_factory = self::A::• in let self::A::redirect::T% #typeArg0 = null in invalid-expression;
+}
+static const field <T extends core::Object? = dynamic>() → self::A<T%> a = #C1;
+static const field () → self::A<core::int> b = #C2;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> c = #C3;
+static const field () → self::A<core::int> d = #C4;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> e = #C5;
+static const field () → self::A<core::int> f = #C6;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> g = #C1;
+static const field () → self::A<core::int> h = #C2;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> i = #C3;
+static const field () → self::A<core::int> j = #C4;
+static const field <T extends core::Object? = dynamic>() → self::A<T%> k = #C5;
+static const field () → self::A<core::int> l = #C6;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> m = #C7;
+static const field () → self::A<core::int> n = #C2;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> o = #C8;
+static const field () → self::A<core::int> p = #C4;
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
+static const field () → self::A<core::int> r = #C6;
+static method main() → dynamic {
+ <T extends core::Object? = dynamic>() → self::A<T%> a = #C1;
+ () → self::A<core::int> b = #C2;
+ <T extends core::Object? = dynamic>() → self::A<T%> c = #C3;
+ () → self::A<core::int> d = #C4;
+ <T extends core::Object? = dynamic>() → self::A<T%> e = #C5;
+ () → self::A<core::int> f = #C6;
+ <T extends core::Object? = dynamic>() → self::A<T%> g = #C1;
+ () → self::A<core::int> h = #C2;
+ <T extends core::Object? = dynamic>() → self::A<T%> i = #C3;
+ () → self::A<core::int> j = #C4;
+ <T extends core::Object? = dynamic>() → self::A<T%> k = #C5;
+ () → self::A<core::int> l = #C6;
+ <unrelated T extends core::Object? = dynamic>() → self::A<core::int> m = #C7;
+ () → self::A<core::int> n = #C2;
+ <unrelated T extends core::Object? = dynamic>() → self::A<core::int> o = #C8;
+ () → self::A<core::int> p = #C4;
+ <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
+ () → self::A<core::int> r = #C6;
+}
+
+constants {
+ #C1 = constructor-tearoff self::A::•
+ #C2 = instantiation self::A::• <core::int*>
+ #C3 = static-tearoff self::A::fact
+ #C4 = instantiation self::A::fact <core::int*>
+ #C5 = redirecting-factory-tearoff self::A::redirect
+ #C6 = instantiation self::A::redirect <core::int*>
+ #C7 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
+ #C8 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C3<core::int>)
+ #C9 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C5<core::int>)
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.expect
index 1fc439e..2949323 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.expect
@@ -1,4 +1,21 @@
library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:32:18: Error: Constant evaluation error:
+// test4() => const StaticIdentityTest(A4.new, B4.new); // Error.
+// ^
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:26:43: Context: This assertion failed.
+// const StaticIdentityTest(a, b) : assert(identical(a, b));
+// ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:33:18: Error: Constant evaluation error:
+// test5() => const StaticIdentityTest(A5.new, B5.new); // Error.
+// ^
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:26:43: Context: This assertion failed.
+// const StaticIdentityTest(a, b) : assert(identical(a, b));
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -44,9 +61,9 @@
static method test3() → dynamic
return #C1;
static method test4() → dynamic
- return invalid-expression "Constant evaluation has no support for TypedefTearOff!";
+ return invalid-expression "This assertion failed.";
static method test5() → dynamic
- return invalid-expression "Constant evaluation has no support for TypedefTearOff!";
+ return invalid-expression "This assertion failed.";
static method main() → dynamic {}
constants {
diff --git a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.transformed.expect
index 1fc439e..2949323 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.transformed.expect
@@ -1,4 +1,21 @@
library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:32:18: Error: Constant evaluation error:
+// test4() => const StaticIdentityTest(A4.new, B4.new); // Error.
+// ^
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:26:43: Context: This assertion failed.
+// const StaticIdentityTest(a, b) : assert(identical(a, b));
+// ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:33:18: Error: Constant evaluation error:
+// test5() => const StaticIdentityTest(A5.new, B5.new); // Error.
+// ^
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:26:43: Context: This assertion failed.
+// const StaticIdentityTest(a, b) : assert(identical(a, b));
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -44,9 +61,9 @@
static method test3() → dynamic
return #C1;
static method test4() → dynamic
- return invalid-expression "Constant evaluation has no support for TypedefTearOff!";
+ return invalid-expression "This assertion failed.";
static method test5() → dynamic
- return invalid-expression "Constant evaluation has no support for TypedefTearOff!";
+ return invalid-expression "This assertion failed.";
static method main() → dynamic {}
constants {
diff --git a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.expect
index 1fc439e..2949323 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.expect
@@ -1,4 +1,21 @@
library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:32:18: Error: Constant evaluation error:
+// test4() => const StaticIdentityTest(A4.new, B4.new); // Error.
+// ^
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:26:43: Context: This assertion failed.
+// const StaticIdentityTest(a, b) : assert(identical(a, b));
+// ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:33:18: Error: Constant evaluation error:
+// test5() => const StaticIdentityTest(A5.new, B5.new); // Error.
+// ^
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:26:43: Context: This assertion failed.
+// const StaticIdentityTest(a, b) : assert(identical(a, b));
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -44,9 +61,9 @@
static method test3() → dynamic
return #C1;
static method test4() → dynamic
- return invalid-expression "Constant evaluation has no support for TypedefTearOff!";
+ return invalid-expression "This assertion failed.";
static method test5() → dynamic
- return invalid-expression "Constant evaluation has no support for TypedefTearOff!";
+ return invalid-expression "This assertion failed.";
static method main() → dynamic {}
constants {
diff --git a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.transformed.expect
index 1fc439e..2949323 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.transformed.expect
@@ -1,4 +1,21 @@
library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:32:18: Error: Constant evaluation error:
+// test4() => const StaticIdentityTest(A4.new, B4.new); // Error.
+// ^
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:26:43: Context: This assertion failed.
+// const StaticIdentityTest(a, b) : assert(identical(a, b));
+// ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:33:18: Error: Constant evaluation error:
+// test5() => const StaticIdentityTest(A5.new, B5.new); // Error.
+// ^
+// pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart:26:43: Context: This assertion failed.
+// const StaticIdentityTest(a, b) : assert(identical(a, b));
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -44,9 +61,9 @@
static method test3() → dynamic
return #C1;
static method test4() → dynamic
- return invalid-expression "Constant evaluation has no support for TypedefTearOff!";
+ return invalid-expression "This assertion failed.";
static method test5() → dynamic
- return invalid-expression "Constant evaluation has no support for TypedefTearOff!";
+ return invalid-expression "This assertion failed.";
static method main() → dynamic {}
constants {
diff --git a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.expect
index f1d8c77..218d370 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.expect
@@ -63,36 +63,36 @@
static method test2() → () → self::A
return #C1;
static method test3() → () → self::A
- return <unrelated X extends core::num>.(#C1)<core::num>;
+ return #C3;
static method test4() → () → self::A
- return <unrelated X extends core::num>.(#C1)<core::num>;
+ return #C3;
static method test5() → () → self::A
return #C1;
static method test6() → () → self::A
return #C1;
static method test7() → () → self::B<core::String>
- return #C3;
+ return #C5;
static method test8() → () → self::B<core::String>
- return #C3;
+ return #C5;
static method test9() → () → self::B<core::num>
return let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:33:30: Error: A value of type 'B<String> Function()' can't be returned from a function with return type 'B<num> Function()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<num> Function() test9() => DB1.new; // Error.
- ^" in (#C3) as{TypeError,ForNonNullableByDefault} () → self::B<core::num>;
+ ^" in (#C5) as{TypeError,ForNonNullableByDefault} () → self::B<core::num>;
static method test10() → () → self::B<core::String>
- return #C5;
-static method test11() → () → self::B<core::String>
return #C7;
-static method test12() → () → self::B<core::num>
- return #C8;
-static method test13() → () → self::B<core::num>
+static method test11() → () → self::B<core::String>
return #C9;
-static method test14() → () → self::B<core::num>
+static method test12() → () → self::B<core::num>
return #C10;
+static method test13() → () → self::B<core::num>
+ return #C11;
+static method test14() → () → self::B<core::num>
+ return #C12;
static method test15() → () → self::B<core::num>
- return <X extends core::num>.(#C2<X>)<core::num>;
+ return #C14;
static method test16() → <Y extends core::num = dynamic>() → self::B<Y>
- return <X extends core::num>.(#C2<X>);
+ return #C13;
static method test17() → <Y extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
@@ -100,17 +100,17 @@
^" in (let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y>() test17() => DB2.new; // Error.
- ^" in (<X extends core::num>.(#C2<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
+ ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
static method test18() → () → self::B<core::num>
- return #C8;
-static method test19() → () → self::B<core::num>
- return #C9;
-static method test20() → () → self::B<core::num>
return #C10;
+static method test19() → () → self::B<core::num>
+ return #C11;
+static method test20() → () → self::B<core::num>
+ return #C12;
static method test21() → () → self::B<core::num>
- return <X extends core::num, unrelated Y extends core::String>.(#C2<X>)<core::num, core::String>;
+ return #C16;
static method test22() → <Y extends core::num = dynamic, Z extends core::String = dynamic>() → self::B<Y>
- return <X extends core::num, unrelated Y extends core::String>.(#C2<X>);
+ return #C15;
static method test23() → <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
@@ -118,20 +118,27 @@
^" in (let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
- ^" in (<X extends core::num, unrelated Y extends core::String>.(#C2<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
+ ^" in (#C15) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
static method test24() → () → self::B<core::String>
- return <X extends core::num>.(#C2<X>)<Never>;
+ return #C17;
static method main() → dynamic {}
constants {
#C1 = constructor-tearoff self::A::•
- #C2 = constructor-tearoff self::B::•
- #C3 = instantiation self::B::• <core::String>
- #C4 = constructor-tearoff self::B::foo
- #C5 = instantiation self::B::foo <core::String>
- #C6 = static-tearoff self::B::bar
- #C7 = instantiation self::B::bar <core::String>
- #C8 = instantiation self::B::• <core::num>
- #C9 = instantiation self::B::foo <core::num>
- #C10 = instantiation self::B::bar <core::num>
+ #C2 = typedef-tearoff <unrelated X extends core::num>.(#C1)
+ #C3 = instantiation #C2 <core::num>
+ #C4 = constructor-tearoff self::B::•
+ #C5 = instantiation self::B::• <core::String>
+ #C6 = constructor-tearoff self::B::foo
+ #C7 = instantiation self::B::foo <core::String>
+ #C8 = static-tearoff self::B::bar
+ #C9 = instantiation self::B::bar <core::String>
+ #C10 = instantiation self::B::• <core::num>
+ #C11 = instantiation self::B::foo <core::num>
+ #C12 = instantiation self::B::bar <core::num>
+ #C13 = typedef-tearoff <X extends core::num>.(#C4<X>)
+ #C14 = instantiation #C13 <core::num>
+ #C15 = typedef-tearoff <X extends core::num, unrelated Y extends core::String>.(#C4<X>)
+ #C16 = instantiation #C15 <core::num, core::String>
+ #C17 = instantiation #C13 <Never>
}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.transformed.expect
index b64fd31..8730f3b 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.transformed.expect
@@ -63,36 +63,36 @@
static method test2() → () → self::A
return #C1;
static method test3() → () → self::A
- return <unrelated X extends core::num>.(#C1)<core::num>;
+ return #C3;
static method test4() → () → self::A
- return <unrelated X extends core::num>.(#C1)<core::num>;
+ return #C3;
static method test5() → () → self::A
return #C1;
static method test6() → () → self::A
return #C1;
static method test7() → () → self::B<core::String>
- return #C3;
+ return #C5;
static method test8() → () → self::B<core::String>
- return #C3;
+ return #C5;
static method test9() → () → self::B<core::num>
return let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:33:30: Error: A value of type 'B<String> Function()' can't be returned from a function with return type 'B<num> Function()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<num> Function() test9() => DB1.new; // Error.
- ^" in (#C3) as{TypeError,ForNonNullableByDefault} () → self::B<core::num>;
+ ^" in (#C5) as{TypeError,ForNonNullableByDefault} () → self::B<core::num>;
static method test10() → () → self::B<core::String>
- return #C5;
-static method test11() → () → self::B<core::String>
return #C7;
-static method test12() → () → self::B<core::num>
- return #C8;
-static method test13() → () → self::B<core::num>
+static method test11() → () → self::B<core::String>
return #C9;
-static method test14() → () → self::B<core::num>
+static method test12() → () → self::B<core::num>
return #C10;
+static method test13() → () → self::B<core::num>
+ return #C11;
+static method test14() → () → self::B<core::num>
+ return #C12;
static method test15() → () → self::B<core::num>
- return <X extends core::num>.(#C2<X>)<core::num>;
+ return #C14;
static method test16() → <Y extends core::num = dynamic>() → self::B<Y>
- return <X extends core::num>.(#C2<X>);
+ return #C13;
static method test17() → <Y extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
@@ -100,17 +100,17 @@
^" in let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y>() test17() => DB2.new; // Error.
- ^" in (<X extends core::num>.(#C2<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
+ ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
static method test18() → () → self::B<core::num>
- return #C8;
-static method test19() → () → self::B<core::num>
- return #C9;
-static method test20() → () → self::B<core::num>
return #C10;
+static method test19() → () → self::B<core::num>
+ return #C11;
+static method test20() → () → self::B<core::num>
+ return #C12;
static method test21() → () → self::B<core::num>
- return <X extends core::num, unrelated Y extends core::String>.(#C2<X>)<core::num, core::String>;
+ return #C16;
static method test22() → <Y extends core::num = dynamic, Z extends core::String = dynamic>() → self::B<Y>
- return <X extends core::num, unrelated Y extends core::String>.(#C2<X>);
+ return #C15;
static method test23() → <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
@@ -118,20 +118,27 @@
^" in let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
- ^" in (<X extends core::num, unrelated Y extends core::String>.(#C2<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
+ ^" in (#C15) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
static method test24() → () → self::B<core::String>
- return <X extends core::num>.(#C2<X>)<Never>;
+ return #C17;
static method main() → dynamic {}
constants {
#C1 = constructor-tearoff self::A::•
- #C2 = constructor-tearoff self::B::•
- #C3 = instantiation self::B::• <core::String>
- #C4 = constructor-tearoff self::B::foo
- #C5 = instantiation self::B::foo <core::String>
- #C6 = static-tearoff self::B::bar
- #C7 = instantiation self::B::bar <core::String>
- #C8 = instantiation self::B::• <core::num>
- #C9 = instantiation self::B::foo <core::num>
- #C10 = instantiation self::B::bar <core::num>
+ #C2 = typedef-tearoff <unrelated X extends core::num>.(#C1)
+ #C3 = instantiation #C2 <core::num>
+ #C4 = constructor-tearoff self::B::•
+ #C5 = instantiation self::B::• <core::String>
+ #C6 = constructor-tearoff self::B::foo
+ #C7 = instantiation self::B::foo <core::String>
+ #C8 = static-tearoff self::B::bar
+ #C9 = instantiation self::B::bar <core::String>
+ #C10 = instantiation self::B::• <core::num>
+ #C11 = instantiation self::B::foo <core::num>
+ #C12 = instantiation self::B::bar <core::num>
+ #C13 = typedef-tearoff <X extends core::num>.(#C4<X>)
+ #C14 = instantiation #C13 <core::num>
+ #C15 = typedef-tearoff <X extends core::num, unrelated Y extends core::String>.(#C4<X>)
+ #C16 = instantiation #C15 <core::num, core::String>
+ #C17 = instantiation #C13 <Never>
}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.expect
index 85a026d..ba0758d 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.expect
@@ -63,36 +63,36 @@
static method test2() → () → self::A
return #C1;
static method test3() → () → self::A
- return <unrelated X extends core::num>.(#C1)<core::num>;
+ return #C3;
static method test4() → () → self::A
- return <unrelated X extends core::num>.(#C1)<core::num>;
+ return #C3;
static method test5() → () → self::A
return #C1;
static method test6() → () → self::A
return #C1;
static method test7() → () → self::B<core::String>
- return #C3;
+ return #C5;
static method test8() → () → self::B<core::String>
- return #C3;
+ return #C5;
static method test9() → () → self::B<core::num>
return let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:33:30: Error: A value of type 'B<String> Function()' can't be returned from a function with return type 'B<num> Function()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<num> Function() test9() => DB1.new; // Error.
- ^" in (#C3) as{TypeError,ForNonNullableByDefault} () → self::B<core::num>;
+ ^" in (#C5) as{TypeError,ForNonNullableByDefault} () → self::B<core::num>;
static method test10() → () → self::B<core::String>
- return #C5;
-static method test11() → () → self::B<core::String>
return #C7;
-static method test12() → () → self::B<core::num>
- return #C8;
-static method test13() → () → self::B<core::num>
+static method test11() → () → self::B<core::String>
return #C9;
-static method test14() → () → self::B<core::num>
+static method test12() → () → self::B<core::num>
return #C10;
+static method test13() → () → self::B<core::num>
+ return #C11;
+static method test14() → () → self::B<core::num>
+ return #C12;
static method test15() → () → self::B<core::num>
- return <X extends core::num>.(#C2<X>)<core::num>;
+ return #C14;
static method test16() → <Y extends core::num = dynamic>() → self::B<Y>
- return <X extends core::num>.(#C2<X>);
+ return #C13;
static method test17() → <Y extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
@@ -100,17 +100,17 @@
^" in (let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y>() test17() => DB2.new; // Error.
- ^" in (<X extends core::num>.(#C2<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
+ ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
static method test18() → () → self::B<core::num>
- return #C8;
-static method test19() → () → self::B<core::num>
- return #C9;
-static method test20() → () → self::B<core::num>
return #C10;
+static method test19() → () → self::B<core::num>
+ return #C11;
+static method test20() → () → self::B<core::num>
+ return #C12;
static method test21() → () → self::B<core::num>
- return <X extends core::num, unrelated Y extends core::String>.(#C2<X>)<core::num, core::String>;
+ return #C16;
static method test22() → <Y extends core::num = dynamic, Z extends core::String = dynamic>() → self::B<Y>
- return <X extends core::num, unrelated Y extends core::String>.(#C2<X>);
+ return #C15;
static method test23() → <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
@@ -118,20 +118,27 @@
^" in (let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
- ^" in (<X extends core::num, unrelated Y extends core::String>.(#C2<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
+ ^" in (#C15) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
static method test24() → () → self::B<core::String>
- return <X extends core::num>.(#C2<X>)<Never>;
+ return #C17;
static method main() → dynamic {}
constants {
#C1 = constructor-tearoff self::A::•
- #C2 = constructor-tearoff self::B::•
- #C3 = instantiation self::B::• <core::String*>
- #C4 = constructor-tearoff self::B::foo
- #C5 = instantiation self::B::foo <core::String*>
- #C6 = static-tearoff self::B::bar
- #C7 = instantiation self::B::bar <core::String*>
- #C8 = instantiation self::B::• <core::num*>
- #C9 = instantiation self::B::foo <core::num*>
- #C10 = instantiation self::B::bar <core::num*>
+ #C2 = typedef-tearoff <unrelated X extends core::num>.(#C1)
+ #C3 = instantiation #C2 <core::num*>
+ #C4 = constructor-tearoff self::B::•
+ #C5 = instantiation self::B::• <core::String*>
+ #C6 = constructor-tearoff self::B::foo
+ #C7 = instantiation self::B::foo <core::String*>
+ #C8 = static-tearoff self::B::bar
+ #C9 = instantiation self::B::bar <core::String*>
+ #C10 = instantiation self::B::• <core::num*>
+ #C11 = instantiation self::B::foo <core::num*>
+ #C12 = instantiation self::B::bar <core::num*>
+ #C13 = typedef-tearoff <X extends core::num>.(#C4<X>)
+ #C14 = instantiation #C13 <core::num*>
+ #C15 = typedef-tearoff <X extends core::num, unrelated Y extends core::String>.(#C4<X>)
+ #C16 = instantiation #C15 <core::num*, core::String*>
+ #C17 = instantiation #C13 <Never*>
}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.transformed.expect
index 5146a3b..b9c3245 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.transformed.expect
@@ -63,36 +63,36 @@
static method test2() → () → self::A
return #C1;
static method test3() → () → self::A
- return <unrelated X extends core::num>.(#C1)<core::num>;
+ return #C3;
static method test4() → () → self::A
- return <unrelated X extends core::num>.(#C1)<core::num>;
+ return #C3;
static method test5() → () → self::A
return #C1;
static method test6() → () → self::A
return #C1;
static method test7() → () → self::B<core::String>
- return #C3;
+ return #C5;
static method test8() → () → self::B<core::String>
- return #C3;
+ return #C5;
static method test9() → () → self::B<core::num>
return let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:33:30: Error: A value of type 'B<String> Function()' can't be returned from a function with return type 'B<num> Function()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<num> Function() test9() => DB1.new; // Error.
- ^" in (#C3) as{TypeError,ForNonNullableByDefault} () → self::B<core::num>;
+ ^" in (#C5) as{TypeError,ForNonNullableByDefault} () → self::B<core::num>;
static method test10() → () → self::B<core::String>
- return #C5;
-static method test11() → () → self::B<core::String>
return #C7;
-static method test12() → () → self::B<core::num>
- return #C8;
-static method test13() → () → self::B<core::num>
+static method test11() → () → self::B<core::String>
return #C9;
-static method test14() → () → self::B<core::num>
+static method test12() → () → self::B<core::num>
return #C10;
+static method test13() → () → self::B<core::num>
+ return #C11;
+static method test14() → () → self::B<core::num>
+ return #C12;
static method test15() → () → self::B<core::num>
- return <X extends core::num>.(#C2<X>)<core::num>;
+ return #C14;
static method test16() → <Y extends core::num = dynamic>() → self::B<Y>
- return <X extends core::num>.(#C2<X>);
+ return #C13;
static method test17() → <Y extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
@@ -100,17 +100,17 @@
^" in let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y>() test17() => DB2.new; // Error.
- ^" in (<X extends core::num>.(#C2<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
+ ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
static method test18() → () → self::B<core::num>
- return #C8;
-static method test19() → () → self::B<core::num>
- return #C9;
-static method test20() → () → self::B<core::num>
return #C10;
+static method test19() → () → self::B<core::num>
+ return #C11;
+static method test20() → () → self::B<core::num>
+ return #C12;
static method test21() → () → self::B<core::num>
- return <X extends core::num, unrelated Y extends core::String>.(#C2<X>)<core::num, core::String>;
+ return #C16;
static method test22() → <Y extends core::num = dynamic, Z extends core::String = dynamic>() → self::B<Y>
- return <X extends core::num, unrelated Y extends core::String>.(#C2<X>);
+ return #C15;
static method test23() → <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
@@ -118,20 +118,27 @@
^" in let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
- ^" in (<X extends core::num, unrelated Y extends core::String>.(#C2<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
+ ^" in (#C15) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
static method test24() → () → self::B<core::String>
- return <X extends core::num>.(#C2<X>)<Never>;
+ return #C17;
static method main() → dynamic {}
constants {
#C1 = constructor-tearoff self::A::•
- #C2 = constructor-tearoff self::B::•
- #C3 = instantiation self::B::• <core::String*>
- #C4 = constructor-tearoff self::B::foo
- #C5 = instantiation self::B::foo <core::String*>
- #C6 = static-tearoff self::B::bar
- #C7 = instantiation self::B::bar <core::String*>
- #C8 = instantiation self::B::• <core::num*>
- #C9 = instantiation self::B::foo <core::num*>
- #C10 = instantiation self::B::bar <core::num*>
+ #C2 = typedef-tearoff <unrelated X extends core::num>.(#C1)
+ #C3 = instantiation #C2 <core::num*>
+ #C4 = constructor-tearoff self::B::•
+ #C5 = instantiation self::B::• <core::String*>
+ #C6 = constructor-tearoff self::B::foo
+ #C7 = instantiation self::B::foo <core::String*>
+ #C8 = static-tearoff self::B::bar
+ #C9 = instantiation self::B::bar <core::String*>
+ #C10 = instantiation self::B::• <core::num*>
+ #C11 = instantiation self::B::foo <core::num*>
+ #C12 = instantiation self::B::bar <core::num*>
+ #C13 = typedef-tearoff <X extends core::num>.(#C4<X>)
+ #C14 = instantiation #C13 <core::num*>
+ #C15 = typedef-tearoff <X extends core::num, unrelated Y extends core::String>.(#C4<X>)
+ #C16 = instantiation #C15 <core::num*, core::String*>
+ #C17 = instantiation #C13 <Never*>
}
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index d6b5325..96b0f76 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -8,6 +8,7 @@
dart2js/late_statics: SemiFuzzFailure # dartbug.com/45854
+constructor_tearoffs/const_tear_off: RuntimeError
constructor_tearoffs/redirecting_constructors: RuntimeError
constructor_tearoffs/redirecting_factory_tear_off: RuntimeError
extension_types/extension_on_nullable: ExpectationFileMismatchSerialized # Expected.
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 2fdf4fb..0aa79ba 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -6,6 +6,7 @@
# the round trip for Kernel textual serialization where the initial binary
# Kernel files are produced by compiling Dart code via Fasta.
+constructor_tearoffs/const_tear_off: RuntimeError
constructor_tearoffs/redirecting_constructors: RuntimeError
constructor_tearoffs/redirecting_factory_tear_off: RuntimeError
extension_types/extension_on_nullable: ExpectationFileMismatchSerialized # Expected.
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 690ab74..3f5fe28 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -23,6 +23,7 @@
const_functions/const_functions_const_ctor: FormatterCrash
const_functions/const_functions_const_ctor_error: FormatterCrash
const_functions/const_functions_const_factory: FormatterCrash
+constructor_tearoffs/const_tear_off: FormatterCrash
constructor_tearoffs/explicit_instantiation_errors: FormatterCrash
constructor_tearoffs/explicit_new_as_unnamed: FormatterCrash
constructor_tearoffs/generic_tearoff_with_context: FormatterCrash
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index f69c2ec..b92823f 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -11,6 +11,7 @@
regress/utf_16_le_content.crash: SemiFuzzCrash
dart2js/late_statics: SemiFuzzFailure # dartbug.com/45854
+constructor_tearoffs/const_tear_off: RuntimeError
constructor_tearoffs/redirecting_constructors: RuntimeError
constructor_tearoffs/redirecting_factory_tear_off: RuntimeError
extension_types/extension_on_nullable: ExpectationFileMismatchSerialized # Expected.
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 667092c..2dd4cf9 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -8721,10 +8721,9 @@
FreshTypeParameters freshTypeParameters =
getFreshTypeParameters(typeParameters);
FunctionType type = expression.getStaticType(context) as FunctionType;
- type = Substitution.combine(
- Substitution.fromPairs(type.typeParameters, typeArguments),
- freshTypeParameters.substitution)
- .substituteType(type.withoutTypeParameters) as FunctionType;
+ type = freshTypeParameters.substitute(
+ Substitution.fromPairs(type.typeParameters, typeArguments)
+ .substituteType(type.withoutTypeParameters)) as FunctionType;
return new FunctionType(
type.positionalParameters, type.returnType, type.declaredNullability,
namedParameters: type.namedParameters,
@@ -12903,7 +12902,7 @@
}
class InstantiationConstant extends Constant {
- final TearOffConstant tearOffConstant;
+ final Constant tearOffConstant;
final List<DartType> types;
InstantiationConstant(this.tearOffConstant, this.types);
@@ -13101,6 +13100,8 @@
final TearOffConstant tearOffConstant;
final List<DartType> types;
+ late final int hashCode = _computeHashCode();
+
TypedefTearOffConstant(this.parameters, this.tearOffConstant, this.types);
visitChildren(Visitor v) {
@@ -13110,7 +13111,8 @@
}
R accept<R>(ConstantVisitor<R> v) => v.visitTypedefTearOffConstant(this);
- R acceptReference<R>(Visitor<R> v) => v.visitTypedefTearOffConstant(this);
+ R acceptReference<R>(Visitor<R> v) =>
+ v.visitTypedefTearOffConstantReference(this);
@override
void toTextInternal(AstPrinter printer) {
@@ -13147,13 +13149,26 @@
return true;
}
+ int _computeHashCode() {
+ int hash = 1237;
+ for (int i = 0; i < parameters.length; ++i) {
+ TypeParameter parameter = parameters[i];
+ hash = 0x3fffffff & (hash * 31 + parameter.bound.hashCode);
+ }
+ for (int i = 0; i < types.length; ++i) {
+ hash = 0x3fffffff & (hash * 31 + types[i].hashCode);
+ }
+ hash = 0x3fffffff & (hash * 31 + tearOffConstant.hashCode);
+ return hash;
+ }
+
DartType getType(StaticTypeContext context) {
FunctionType type = tearOffConstant.getType(context) as FunctionType;
FreshTypeParameters freshTypeParameters =
getFreshTypeParameters(parameters);
type = freshTypeParameters.substitute(
- Substitution.fromPairs(parameters, types).substituteType(type))
- as FunctionType;
+ Substitution.fromPairs(type.typeParameters, types)
+ .substituteType(type.withoutTypeParameters)) as FunctionType;
return new FunctionType(
type.positionalParameters, type.returnType, type.declaredNullability,
namedParameters: type.namedParameters,
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 06cd777..42c9b87 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -448,17 +448,17 @@
}
Constant _readInstantiationConstant() {
- final TearOffConstant tearOffConstant =
- readConstantReference() as TearOffConstant;
+ final Constant tearOffConstant = readConstantReference();
final List<DartType> types = readDartTypeList();
return new InstantiationConstant(tearOffConstant, types);
}
Constant _readTypedefTearOffConstant() {
final List<TypeParameter> parameters = readAndPushTypeParameterList();
- final StaticTearOffConstant tearOffConstant =
- readConstantReference() as StaticTearOffConstant;
+ final TearOffConstant tearOffConstant =
+ readConstantReference() as TearOffConstant;
final List<DartType> types = readDartTypeList();
+ typeParameterStack.length -= parameters.length;
return new TypedefTearOffConstant(parameters, tearOffConstant, types);
}
@@ -1988,6 +1988,8 @@
return _readConstructorTearOff();
case Tag.TypedefTearOff:
return _readTypedefTearOff();
+ case Tag.RedirectingFactoryTearOff:
+ return _readRedirectingFactoryTearOff();
case Tag.MethodInvocation:
return _readMethodInvocation();
case Tag.InstanceInvocation:
@@ -2232,6 +2234,13 @@
return new TypedefTearOff(typeParameters, expression, typeArguments);
}
+ Expression _readRedirectingFactoryTearOff() {
+ int offset = readOffset();
+ Reference constructorReference = readNonNullMemberReference();
+ return new RedirectingFactoryTearOff.byReference(constructorReference)
+ ..fileOffset = offset;
+ }
+
Expression _readStaticTearOff() {
int offset = readOffset();
return new StaticTearOff.byReference(readNonNullMemberReference())
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index d0d0343..babe0c6 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -2760,6 +2760,11 @@
}
@override
+ void visitTypedefTearOffConstantReference(TypedefTearOffConstant node) {
+ throw new UnsupportedError('serialization of TypedefTearOffConstants ');
+ }
+
+ @override
void visitTypeLiteralConstant(TypeLiteralConstant node) {
throw new UnsupportedError('serialization of TypeLiteralConstants');
}
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 7c4b76b..bb2aace 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -74,7 +74,7 @@
}
abstract class DiagnosticReporter<M, C> {
- void report(M message, int charOffset, int length, Uri fileUri,
+ void report(M message, int charOffset, int length, Uri? fileUri,
{List<C> context});
}
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index b2666d8..8a2af9b 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -2680,7 +2680,12 @@
writeSpaced('=');
writeWord('instantiation');
writeSpace();
- writeMemberReferenceFromReference(node.tearOffConstant.targetReference);
+ Constant tearOffConstant = node.tearOffConstant;
+ if (tearOffConstant is TearOffConstant) {
+ writeMemberReferenceFromReference(tearOffConstant.targetReference);
+ } else {
+ writeConstantReference(tearOffConstant);
+ }
writeSpace();
writeSymbol('<');
writeList(node.types, writeType);
@@ -2705,6 +2710,26 @@
endLine();
}
+ visitTypedefTearOffConstant(TypedefTearOffConstant node) {
+ writeIndentation();
+ writeConstantReference(node);
+ writeSpaced('=');
+ writeWord('typedef-tearoff');
+ writeSpace();
+ writeTypeParameterList(node.parameters);
+ state = SYMBOL;
+ writeSymbol('.(');
+ writeConstantReference(node.tearOffConstant);
+ if (node.types.isNotEmpty) {
+ writeSymbol('<');
+ writeList(node.types, writeType);
+ writeSymbol('>');
+ }
+ writeSymbol(')');
+ state = WORD;
+ endLine();
+ }
+
visitUnevaluatedConstant(UnevaluatedConstant node) {
writeIndentation();
writeConstantReference(node);
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
index 0232a67..374cfc4 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.dart
@@ -2283,7 +2283,7 @@
TextSerializer<InstantiationConstant> instantiationConstantSerializer =
Wrapped<Tuple2<Constant, List<DartType>>, InstantiationConstant>(
(w) => Tuple2(w.tearOffConstant, w.types),
- (u) => InstantiationConstant(u.first as TearOffConstant, u.second),
+ (u) => InstantiationConstant(u.first, u.second),
Tuple2Serializer(
constantSerializer, ListSerializer(dartTypeSerializer)));
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index 16d4c30..f589e8a 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -72,6 +72,8 @@
bool inUnevaluatedConstant = false;
+ bool inConstant = false;
+
Library? currentLibrary;
Member? currentMember;
@@ -886,6 +888,31 @@
" ${node.typedefNode.typeParameters.length} parameters.");
}
}
+
+ @override
+ void visitConstantExpression(ConstantExpression node) {
+ bool oldInConstant = inConstant;
+ inConstant = true;
+ visitChildren(node);
+ inConstant = oldInConstant;
+ }
+
+ @override
+ void visitTypeParameter(TypeParameter node) {
+ if (inConstant) {
+ // Don't expect the type parameters to have the current parent as parent.
+ node.visitChildren(this);
+ } else {
+ visitChildren(node);
+ }
+ }
+
+ @override
+ void visitTypedefTearOffConstant(TypedefTearOffConstant node) {
+ declareTypeParameters(node.parameters);
+ super.visitTypedefTearOffConstant(node);
+ undeclareTypeParameters(node.parameters);
+ }
}
void verifyGetStaticType(TypeEnvironment env, Component component) {
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
index ebbb991..4a3134f 100644
--- a/pkg/kernel/lib/visitor.dart
+++ b/pkg/kernel/lib/visitor.dart
@@ -903,6 +903,8 @@
R visitRedirectingFactoryTearOffConstantReference(
RedirectingFactoryTearOffConstant node) =>
defaultConstantReference(node);
+ R visitTypedefTearOffConstantReference(TypedefTearOffConstant node) =>
+ defaultConstantReference(node);
R visitTypeLiteralConstantReference(TypeLiteralConstant node) =>
defaultConstantReference(node);
R visitUnevaluatedConstantReference(UnevaluatedConstant node) =>
diff --git a/pkg/kernel/test/constant_equals_test.dart b/pkg/kernel/test/constant_equals_test.dart
index 8674576..80611c6 100644
--- a/pkg/kernel/test/constant_equals_test.dart
+++ b/pkg/kernel/test/constant_equals_test.dart
@@ -8,6 +8,9 @@
if (a != b) {
throw 'Expected $a and $b to be equal.';
}
+ if (a.hashCode != b.hashCode) {
+ throw 'Expected $a and $b hash codes to be equal.';
+ }
}
testNotEquals(Constant a, Constant b) {
diff --git a/pkg/vm/lib/dominators.dart b/pkg/vm/lib/dominators.dart
index f3b71ed..81309d3 100644
--- a/pkg/vm/lib/dominators.dart
+++ b/pkg/vm/lib/dominators.dart
@@ -2,18 +2,16 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
class Vertex<T extends Vertex<T>> {
// Input: vertices directly reachable from this vertex.
final List<T> successors = <T>[];
// Output: the nearest vertex that all paths from the root must go through to
// reach this vertex.
- T dominator;
+ T? dominator;
bool isDominatedBy(T other) {
- var d = this;
+ Vertex<T>? d = this;
while (d != null) {
if (d == other) {
return true;
@@ -26,17 +24,17 @@
// Temporaries. See Lengauer and Tarjan.
final List<T> _predecessors = <T>[];
int _semi = 0;
- T _label;
- T _ancestor;
- T _parent;
- List<T> _bucket;
+ T? _label;
+ T? _ancestor;
+ T? _parent;
+ List<T>? _bucket;
}
// T. Lengauer and R. E. Tarjan. "A Fast Algorithm for Finding Dominators
// in a Flowgraph."
computeDominators<T extends Vertex<T>>(T root) {
// Lengauer and Tarjan Step 1.
- final vertex = <T>[];
+ final vertex = <T?>[];
vertex.add(null);
var n = 0;
@@ -60,33 +58,35 @@
dfs(root);
forestCompress(T v) {
- if (v._ancestor._ancestor != null) {
- forestCompress(v._ancestor);
- if (v._ancestor._label._semi < v._label._semi) {
- v._label = v._ancestor._label;
+ T ancestor = v._ancestor!;
+ if (ancestor._ancestor != null) {
+ forestCompress(ancestor);
+ ancestor = v._ancestor!;
+ if (ancestor._label!._semi < v._label!._semi) {
+ v._label = ancestor._label;
}
- v._ancestor = v._ancestor._ancestor;
+ v._ancestor = ancestor._ancestor;
}
}
- forestEval(T v) {
+ T forestEval(T v) {
if (v._ancestor == null) {
return v;
} else {
forestCompress(v);
- return v._label;
+ return v._label!;
}
}
- forestLink(T v, T w) {
+ forestLink(T? v, T w) {
w._ancestor = v;
}
for (var i = vertex.length - 1; i > 1; i--) {
- Vertex<T> w = vertex[i];
+ final T w = vertex[i]!;
// Lengauer and Tarjan Step 2.
- for (Vertex<T> v in w._predecessors) {
+ for (T v in w._predecessors) {
if (v._semi == 0) continue; // Unreachable
final u = forestEval(v);
@@ -95,7 +95,7 @@
}
}
- Vertex<T> z = vertex[w._semi];
+ Vertex<T> z = vertex[w._semi]!;
var b = z._bucket;
if (b == null) {
z._bucket = b = <T>[];
@@ -104,8 +104,7 @@
forestLink(w._parent, w);
// Lengauer and Tarjan Step 3.
- z = w._parent;
- assert(z != null);
+ z = w._parent!;
b = z._bucket;
z._bucket = null;
if (b != null) {
@@ -118,9 +117,9 @@
// Lengauer and Tarjan Step 4.
for (var i = 2; i < vertex.length; i++) {
- final w = vertex[i];
+ final T w = vertex[i]!;
if (w.dominator != vertex[w._semi]) {
- w.dominator = w.dominator.dominator;
+ w.dominator = w.dominator!.dominator;
}
}
}
diff --git a/pkg/vm/lib/http_filesystem.dart b/pkg/vm/lib/http_filesystem.dart
index 401d859..18ee3e1 100644
--- a/pkg/vm/lib/http_filesystem.dart
+++ b/pkg/vm/lib/http_filesystem.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
import 'dart:async';
import 'dart:io' as io;
@@ -66,7 +64,7 @@
}
Future<T> connectAndRun<T>(Future<T> body(io.HttpClient httpClient)) async {
- io.HttpClient httpClient;
+ io.HttpClient? httpClient;
try {
httpClient = new io.HttpClient();
// Set timeout to be shorter than anticipated OS default
diff --git a/pkg/vm/lib/transformations/deferred_loading.dart b/pkg/vm/lib/transformations/deferred_loading.dart
index ce46af7..b7dd321 100644
--- a/pkg/vm/lib/transformations/deferred_loading.dart
+++ b/pkg/vm/lib/transformations/deferred_loading.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
library vm.transformations.deferred_loading;
import 'package:kernel/ast.dart';
@@ -11,15 +9,15 @@
import '../metadata/loading_units.dart';
class _LoadingUnitBuilder {
- int id;
+ late int id;
final _LibraryVertex root;
final List<Library> members = <Library>[];
final List<_LoadingUnitBuilder> children = <_LoadingUnitBuilder>[];
_LoadingUnitBuilder(this.root);
- _LoadingUnitBuilder get parent => root.dominator?.loadingUnit;
- int get parentId => parent == null ? 0 : parent.id;
+ _LoadingUnitBuilder? get parent => root.dominator?.loadingUnit;
+ int get parentId => parent == null ? 0 : parent!.id;
LoadingUnit asLoadingUnit() {
return new LoadingUnit(
@@ -33,7 +31,7 @@
class _LibraryVertex extends Vertex<_LibraryVertex> {
final Library library;
bool isLoadingRoot = true;
- _LoadingUnitBuilder loadingUnit;
+ _LoadingUnitBuilder? loadingUnit;
_LibraryVertex(this.library);
String toString() => "_LibraryVertex(${library.importUri})";
@@ -47,11 +45,11 @@
}
for (final vertex in map.values) {
for (final dep in vertex.library.dependencies) {
- final target = map[dep.targetLibrary];
+ final target = map[dep.targetLibrary]!;
vertex.successors.add(target);
}
}
- final root = map[component.mainMethod.parent as Library];
+ final root = map[component.mainMethod!.enclosingLibrary]!;
// Fake imports from root library to every core library so they end up in
// the same loading unit attributed to the user's root library.
@@ -73,7 +71,7 @@
if (dep.isDeferred) {
continue;
}
- var importee = map[dep.targetLibrary];
+ var importee = map[dep.targetLibrary]!;
if (importer.isDominatedBy(importee)) {
continue;
}
@@ -82,7 +80,7 @@
}
assert(root.isLoadingRoot);
- var loadingUnits = <_LoadingUnitBuilder>[];
+ final List<_LoadingUnitBuilder> loadingUnits = <_LoadingUnitBuilder>[];
for (var vertex in map.values) {
if (vertex.isLoadingRoot) {
var unit = new _LoadingUnitBuilder(vertex);
@@ -101,11 +99,11 @@
if (dom == null) {
continue; // Unreachable library.
}
- while (dom.loadingUnit == null) {
+ while (dom!.loadingUnit == null) {
dom = dom.dominator;
}
vertex.loadingUnit = dom.loadingUnit;
- vertex.loadingUnit.members.add(vertex.library);
+ vertex.loadingUnit!.members.add(vertex.library);
}
// 4. Sort loading units so parents are before children. Normally this order
@@ -119,7 +117,7 @@
}
var index = 0;
loadingUnits.clear();
- loadingUnits.add(root.loadingUnit);
+ loadingUnits.add(root.loadingUnit!);
while (index < loadingUnits.length) {
var unit = loadingUnits[index];
unit.id = ++index;
diff --git a/pkg/vm/lib/transformations/devirtualization.dart b/pkg/vm/lib/transformations/devirtualization.dart
index 559dcb2..7d82594 100644
--- a/pkg/vm/lib/transformations/devirtualization.dart
+++ b/pkg/vm/lib/transformations/devirtualization.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
library vm.transformations.cha_devirtualization;
import 'package:kernel/ast.dart';
@@ -18,7 +16,8 @@
Component transformComponent(CoreTypes coreTypes, Component component) {
void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
ClosedWorldClassHierarchy hierarchy = new ClassHierarchy(component, coreTypes,
- onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
+ onAmbiguousSupertypes: ignoreAmbiguousSupertypes)
+ as ClosedWorldClassHierarchy;
final hierarchySubtypes = hierarchy.computeSubtypesInformation();
new CHADevirtualization(coreTypes, component, hierarchy, hierarchySubtypes)
.visitComponent(component);
@@ -34,14 +33,14 @@
static const _trace = const bool.fromEnvironment('trace.devirtualization');
final DirectCallMetadataRepository _metadata;
- Set<Name> _objectMemberNames;
+ final Set<Name> _objectMemberNames;
Devirtualization(
CoreTypes coreTypes, Component component, ClassHierarchy hierarchy)
- : _metadata = new DirectCallMetadataRepository() {
- _objectMemberNames = new Set<Name>.from(hierarchy
- .getInterfaceMembers(coreTypes.objectClass)
- .map((Member m) => m.name));
+ : _metadata = new DirectCallMetadataRepository(),
+ _objectMemberNames = new Set<Name>.from(hierarchy
+ .getInterfaceMembers(coreTypes.objectClass)
+ .map((Member m) => m.name)) {
component.addMetadataRepository(_metadata);
}
@@ -51,7 +50,7 @@
(member is Field) || ((member is Procedure) && member.isGetter);
bool isLegalTargetForMethodInvocation(Member target, Arguments arguments) {
- final FunctionNode func = target.function;
+ final FunctionNode func = target.function!;
final positionalArgs = arguments.positional.length;
if ((positionalArgs < func.requiredParameterCount) ||
@@ -84,10 +83,10 @@
directCall.checkReceiverForNull &&
_objectMemberNames.contains(directCall.target.name);
- DirectCallMetadata getDirectCall(TreeNode node, Member interfaceTarget,
+ DirectCallMetadata? getDirectCall(TreeNode node, Member? interfaceTarget,
{bool setter = false});
- makeDirectCall(TreeNode node, Member target, DirectCallMetadata directCall) {
+ makeDirectCall(TreeNode node, Member? target, DirectCallMetadata directCall) {
if (_trace) {
print("[devirt] Resolving ${target} to ${directCall.target}"
" at ${node.location}");
@@ -104,12 +103,12 @@
}
void _handleMethodInvocation(
- TreeNode node, Member target, Arguments arguments) {
+ TreeNode node, Member? target, Arguments arguments) {
if (target != null && !isMethod(target)) {
return;
}
- final DirectCallMetadata directCall = getDirectCall(node, target);
+ final DirectCallMetadata? directCall = getDirectCall(node, target);
// TODO(alexmarkov): Convert _isLegalTargetForMethodInvocation()
// check into an assertion once front-end implements all override checks.
@@ -138,18 +137,18 @@
super.visitEqualsCall(node);
final target = node.interfaceTarget;
- final DirectCallMetadata directCall = getDirectCall(node, target);
+ final DirectCallMetadata? directCall = getDirectCall(node, target);
if (directCall != null && !directCall.checkReceiverForNull) {
makeDirectCall(node, target, directCall);
}
}
- void _handlePropertyGet(TreeNode node, Member target) {
+ void _handlePropertyGet(TreeNode node, Member? target) {
if (target != null && !isFieldOrGetter(target)) {
return;
}
- final DirectCallMetadata directCall = getDirectCall(node, target);
+ final DirectCallMetadata? directCall = getDirectCall(node, target);
if ((directCall != null) &&
isFieldOrGetter(directCall.target) &&
@@ -170,8 +169,8 @@
_handlePropertyGet(node, null);
}
- void _handlePropertySet(TreeNode node, Member target) {
- final DirectCallMetadata directCall =
+ void _handlePropertySet(TreeNode node, Member? target) {
+ final DirectCallMetadata? directCall =
getDirectCall(node, target, setter: true);
if (directCall != null) {
makeDirectCall(node, target, directCall);
@@ -200,12 +199,12 @@
: super(coreTypes, component, hierarchy);
@override
- DirectCallMetadata getDirectCall(TreeNode node, Member interfaceTarget,
+ DirectCallMetadata? getDirectCall(TreeNode node, Member? interfaceTarget,
{bool setter = false}) {
if (interfaceTarget == null) {
return null;
}
- Member singleTarget = _hierarchySubtype
+ Member? singleTarget = _hierarchySubtype
.getSingleTargetForInterfaceInvocation(interfaceTarget, setter: setter);
if (singleTarget == null) {
return null;
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index bc29a1a..93dc309 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -292,7 +292,9 @@
/// Classes corresponding to [NativeType], indexed by [NativeType].
final List<Class> nativeTypesClasses;
- Library? currentLibrary;
+ Library? _currentLibrary;
+ Library get currentLibrary => _currentLibrary!;
+
IndexedLibrary? currentLibraryIndex;
FfiTransformer(this.index, this.coreTypes, this.hierarchy,
@@ -459,11 +461,11 @@
@override
TreeNode visitLibrary(Library node) {
- assert(currentLibrary == null);
- currentLibrary = node;
+ assert(_currentLibrary == null);
+ _currentLibrary = node;
currentLibraryIndex = referenceFromIndex?.lookupLibrary(node);
final result = super.visitLibrary(node);
- currentLibrary = null;
+ _currentLibrary = null;
return result;
}
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index 26cdd5e..2238251 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -2,10 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
-library vm.transformations.ffi_definitions;
-
import 'dart:math' as math;
import 'package:front_end/src/api_unstable/vm.dart'
@@ -71,8 +67,8 @@
ClassHierarchy hierarchy,
List<Library> libraries,
DiagnosticReporter diagnosticReporter,
- ReferenceFromIndex referenceFromIndex,
- ChangedStructureNotifier changedStructureNotifier) {
+ ReferenceFromIndex? referenceFromIndex,
+ ChangedStructureNotifier? changedStructureNotifier) {
final LibraryIndex index = LibraryIndex(component,
const ["dart:core", "dart:ffi", "dart:_internal", "dart:typed_data"]);
if (!index.containsLibrary("dart:ffi")) {
@@ -96,7 +92,7 @@
CompoundDependencyGraph(this.map);
Iterable<T> get vertices => map.keys;
- Iterable<T> neighborsOf(T vertex) => map[vertex];
+ Iterable<T> neighborsOf(T vertex) => map[vertex]!;
}
/// Checks and elaborates the dart:ffi compounds and their fields.
@@ -109,16 +105,14 @@
Set<Class> transformCompoundsInvalid = {};
Map<Class, NativeTypeCfe> compoundCache = {};
- ChangedStructureNotifier changedStructureNotifier;
-
- IndexedLibrary currentLibraryIndex;
+ ChangedStructureNotifier? changedStructureNotifier;
_FfiDefinitionTransformer(
this.index,
CoreTypes coreTypes,
ClassHierarchy hierarchy,
DiagnosticReporter diagnosticReporter,
- ReferenceFromIndex referenceFromIndex,
+ ReferenceFromIndex? referenceFromIndex,
this.changedStructureNotifier)
: super(index, coreTypes, hierarchy, diagnosticReporter,
referenceFromIndex) {}
@@ -185,7 +179,7 @@
report = true;
}
if (component.length == 1) {
- if (dependencyGraph.map[component.single].contains(component.single)) {
+ if (dependencyGraph.map[component.single]!.contains(component.single)) {
// Direct cycle.
report = true;
}
@@ -193,7 +187,7 @@
if (report) {
component.forEach((Class e) {
diagnosticReporter.report(
- templateFfiFieldCyclic.withArguments(e.superclass.name, e.name,
+ templateFfiFieldCyclic.withArguments(e.superclass!.name, e.name,
component.map((e) => e.name).toList()),
e.fileOffset,
e.name.length,
@@ -233,12 +227,6 @@
}
@override
- visitLibrary(Library node) {
- currentLibraryIndex = referenceFromIndex?.lookupLibrary(node);
- return super.visitLibrary(node);
- }
-
- @override
visitExtension(Extension node) {
// The extension and it's members are only metadata.
return node;
@@ -262,9 +250,12 @@
final packing = _checkCompoundClass(node);
- final indexedClass = currentLibraryIndex?.lookupIndexedClass(node.name);
+ final IndexedClass? indexedClass =
+ currentLibraryIndex?.lookupIndexedClass(node.name);
_checkConstructors(node, indexedClass);
- indexedCompoundClasses[node] = indexedClass;
+ if (indexedClass != null) {
+ indexedCompoundClasses[node] = indexedClass;
+ }
final fieldsValid = _checkFieldAnnotations(node, packing);
if (fieldsValid) {
@@ -278,14 +269,14 @@
}
/// Returns packing if any.
- int _checkCompoundClass(Class node) {
+ int? _checkCompoundClass(Class node) {
if (node.typeParameters.length > 0) {
diagnosticReporter.report(
templateFfiStructGeneric.withArguments(
- node.superclass.name, node.name),
+ node.superclass!.name, node.name),
node.fileOffset,
1,
- node.location.file);
+ node.location!.file);
}
if (node.superclass != structClass && node.superclass != unionClass) {
@@ -301,7 +292,7 @@
templateFfiPackedAnnotation.withArguments(node.name),
node.fileOffset,
node.name.length,
- node.location.file);
+ node.location!.file);
}
if (packingAnnotations.isNotEmpty) {
final packing = packingAnnotations.first;
@@ -311,7 +302,7 @@
packing == 8 ||
packing == 16)) {
diagnosticReporter.report(messageFfiPackedAnnotationAlignment,
- node.fileOffset, node.name.length, node.location.file);
+ node.fileOffset, node.name.length, node.location!.file);
}
return packing;
}
@@ -354,14 +345,14 @@
if (member is Field) {
return member.type;
}
- final Procedure p = member;
+ final p = member as Procedure;
if (p.isGetter) {
return p.function.returnType;
}
return p.function.positionalParameters.single.type;
}
- bool _checkFieldAnnotations(Class node, int packing) {
+ bool _checkFieldAnnotations(Class node, int? packing) {
bool success = true;
final membersWithAnnotations =
_compoundFieldMembers(node, includeSetters: false);
@@ -445,9 +436,9 @@
success = false;
} else {
final DartType nativeType = InterfaceType(
- nativeTypesClasses[_getFieldType(nativeTypeAnnos.first).index],
+ nativeTypesClasses[_getFieldType(nativeTypeAnnos.first)!.index],
Nullability.legacy);
- final DartType shouldBeDartType = convertNativeTypeToDartType(
+ final DartType? shouldBeDartType = convertNativeTypeToDartType(
nativeType,
allowCompounds: true,
allowHandle: false);
@@ -455,11 +446,11 @@
!env.isSubtypeOf(type, shouldBeDartType,
SubtypeCheckMode.ignoringNullabilities)) {
diagnosticReporter.report(
- templateFfiTypeMismatch.withArguments(type, shouldBeDartType,
+ templateFfiTypeMismatch.withArguments(type, shouldBeDartType!,
nativeType, node.enclosingLibrary.isNonNullableByDefault),
f.fileOffset,
1,
- f.location.file);
+ f.location!.file);
// This class is invalid, but continue reporting other errors on it.
success = false;
}
@@ -468,7 +459,7 @@
return success;
}
- void _checkPacking(Class outerClass, int outerClassPacking, Class fieldClass,
+ void _checkPacking(Class outerClass, int? outerClassPacking, Class fieldClass,
Member errorNode) {
if (outerClassPacking == null) {
// Outer struct has no packing, nesting anything is fine.
@@ -497,7 +488,7 @@
}
}
- void _checkConstructors(Class node, IndexedClass indexedClass) {
+ void _checkConstructors(Class node, IndexedClass? indexedClass) {
final toRemove = <Initializer>[];
// Constructors cannot have initializers because initializers refer to
@@ -510,13 +501,13 @@
templateFfiFieldInitializer.withArguments(i.field.name.text),
i.fileOffset,
1,
- i.location.file);
+ i.location!.file);
}
}
}
// Remove initializers referring to fields to prevent cascading errors.
for (final Initializer i in toRemove) {
- final Constructor c = i.parent;
+ final c = i.parent as Constructor;
c.initializers.remove(i);
}
@@ -565,7 +556,7 @@
final dartType = _compoundMemberType(m);
// Nullable.
- NativeTypeCfe type;
+ NativeTypeCfe? type;
if (isArrayType(dartType)) {
final sizeAnnotations = _getArraySizeAnnotations(m).toList();
if (sizeAnnotations.length == 1) {
@@ -584,7 +575,7 @@
final nativeTypeAnnos = _getNativeTypeAnnotations(m).toList();
if (nativeTypeAnnos.length == 1) {
final clazz = nativeTypeAnnos.first;
- final nativeType = _getFieldType(clazz);
+ final nativeType = _getFieldType(clazz)!;
type = PrimitiveNativeTypeCfe(nativeType, clazz);
}
}
@@ -635,17 +626,18 @@
///
/// Returns the total size of the compound (for all ABIs).
void _replaceFields(
- Class node, IndexedClass indexedClass, CompoundData compoundData) {
+ Class node, IndexedClass? indexedClass, CompoundData compoundData) {
final compoundType = compoundData.compoundType as CompoundNativeTypeCfe;
final compoundLayout = compoundType.layout;
_annoteCompoundWithFields(node, compoundType.members, compoundData.packing);
if (compoundType.members.isEmpty) {
diagnosticReporter.report(
- templateFfiEmptyStruct.withArguments(node.superclass.name, node.name),
+ templateFfiEmptyStruct.withArguments(
+ node.superclass!.name, node.name),
node.fileOffset,
node.name.length,
- node.location.file);
+ node.location!.file);
}
final unalignedAccess = compoundData.packing != null;
@@ -653,9 +645,9 @@
int i = 0;
for (final compoundField in compoundData.compoundFields) {
NativeTypeCfe type = compoundField.type;
- Field field = compoundField.field;
- Procedure getter = compoundField.getter;
- Procedure setter = compoundField.setter;
+ Field? field = compoundField.field;
+ Procedure? getter = compoundField.getter;
+ Procedure? setter = compoundField.setter;
final fieldOffsets = compoundLayout
.map((Abi abi, CompoundLayout v) => MapEntry(abi, v.offsets[i]));
@@ -693,7 +685,7 @@
static const vmFfiStructFields = "vm:ffi:struct-fields";
// return value is nullable.
- InstanceConstant _compoundAnnotatedFields(Class node) {
+ InstanceConstant? _compoundAnnotatedFields(Class node) {
for (final annotation in node.annotations) {
if (annotation is ConstantExpression) {
final constant = annotation.constant;
@@ -701,7 +693,8 @@
constant.classNode == pragmaClass &&
constant.fieldValues[pragmaName.getterReference] ==
StringConstant(vmFfiStructFields)) {
- return constant.fieldValues[pragmaOptions.getterReference];
+ return constant.fieldValues[pragmaOptions.getterReference]
+ as InstanceConstant?;
}
}
}
@@ -726,7 +719,7 @@
/// Must only be called if all the depencies are already in the cache.
CompoundNativeTypeCfe _compoundAnnotatedNativeTypeCfe(Class compoundClass) {
- final layoutConstant = _compoundAnnotatedFields(compoundClass);
+ final layoutConstant = _compoundAnnotatedFields(compoundClass)!;
final fieldTypes = layoutConstant
.fieldValues[ffiStructLayoutTypesField.getterReference] as ListConstant;
final members = <NativeTypeCfe>[];
@@ -763,7 +756,7 @@
// packing is `int?`.
void _annoteCompoundWithFields(
- Class node, List<NativeTypeCfe> types, int packing) {
+ Class node, List<NativeTypeCfe> types, int? packing) {
List<Constant> constants =
types.map((t) => t.generateConstant(this)).toList();
@@ -782,7 +775,7 @@
}
void _generateMethodsForField(Class node, Field field, NativeTypeCfe type,
- Map<Abi, int> offsets, bool unalignedAccess, IndexedClass indexedClass) {
+ Map<Abi, int> offsets, bool unalignedAccess, IndexedClass? indexedClass) {
// TODO(johnniwinther): Avoid passing [indexedClass]. When compiling
// incrementally, [field] should already carry the references from
// [indexedClass].
@@ -802,7 +795,7 @@
node.addProcedure(getter);
if (!field.isFinal) {
- Reference setterReference =
+ Reference? setterReference =
indexedClass?.lookupSetterReference(field.name) ??
field.setterReference;
assert(setterReference == field.setterReference,
@@ -832,8 +825,8 @@
///
/// If sizes are not supplied still emits a field so that the use site
/// transformer can still rewrite to it.
- void _addSizeOfField(Class compound, IndexedClass indexedClass,
- [Map<Abi, int> sizes = null]) {
+ void _addSizeOfField(Class compound, IndexedClass? indexedClass,
+ [Map<Abi, int>? sizes = null]) {
if (sizes == null) {
sizes = Map.fromEntries(Abi.values.map((abi) => MapEntry(abi, 0)));
}
@@ -859,7 +852,7 @@
compound.addProcedure(getter);
}
- NativeType _getFieldType(Class c) {
+ NativeType? _getFieldType(Class c) {
final fieldType = getType(c);
if (fieldType == NativeType.kVoid) {
@@ -928,10 +921,7 @@
class CompoundData {
final List<CompoundField> compoundFields;
-
- // Nullable.
- final int packing;
-
+ final int? packing;
final NativeTypeCfe compoundType;
CompoundData(this.compoundFields, this.packing, this.compoundType);
@@ -939,15 +929,9 @@
class CompoundField {
final NativeTypeCfe type;
-
- // Nullable.
- final Field field;
-
- // Nullable.
- final Procedure getter;
-
- // Nullable.
- final Procedure setter;
+ final Field? field;
+ final Procedure? getter;
+ final Procedure? setter;
CompoundField(this.type, this.field, this.getter, this.setter);
}
@@ -974,11 +958,11 @@
/// intimately to AST nodes such as [Class].
abstract class NativeTypeCfe {
factory NativeTypeCfe(FfiTransformer transformer, DartType dartType,
- {List<int> arrayDimensions,
+ {List<int>? arrayDimensions,
Map<Class, NativeTypeCfe> compoundCache = const {}}) {
if (transformer.isPrimitiveType(dartType)) {
final clazz = (dartType as InterfaceType).classNode;
- final nativeType = transformer.getType(clazz);
+ final nativeType = transformer.getType(clazz)!;
return PrimitiveNativeTypeCfe(nativeType, clazz);
}
if (transformer.isPointerType(dartType)) {
@@ -987,7 +971,7 @@
if (transformer.isCompoundSubtype(dartType)) {
final clazz = (dartType as InterfaceType).classNode;
if (compoundCache.containsKey(clazz)) {
- return compoundCache[clazz];
+ return compoundCache[clazz]!;
} else {
throw "Class '$clazz' not found in compoundCache.";
}
@@ -1094,8 +1078,8 @@
}
@override
- Map<Abi, int> get alignment => Map.fromEntries(Abi.values.map(
- (abi) => MapEntry(abi, nonSizeAlignment[abi][nativeType] ?? size[abi])));
+ Map<Abi, int> get alignment => Map.fromEntries(Abi.values.map((abi) =>
+ MapEntry(abi, nonSizeAlignment[abi]![nativeType] ?? size[abi]!)));
@override
Constant generateConstant(FfiTransformer transformer) =>
@@ -1107,8 +1091,8 @@
bool isUnaligned(Map<Abi, int> offsets) {
final alignments = alignment;
for (final abi in offsets.keys) {
- final offset = offsets[abi];
- final alignment = alignments[abi];
+ final offset = offsets[abi]!;
+ final alignment = alignments[abi]!;
if (offset % alignment != 0) {
return true;
}
@@ -1131,7 +1115,7 @@
ReturnStatement(StaticInvocation(
(unalignedAccess && isFloat
? transformer.loadUnalignedMethods
- : transformer.loadMethods)[nativeType],
+ : transformer.loadMethods)[nativeType]!,
Arguments([
transformer.getCompoundTypedDataBaseField(
ThisExpression(), fileOffset),
@@ -1155,7 +1139,7 @@
ReturnStatement(StaticInvocation(
(unalignedAccess && isFloat
? transformer.storeUnalignedMethods
- : transformer.storeMethods)[nativeType],
+ : transformer.storeMethods)[nativeType]!,
Arguments([
transformer.getCompoundTypedDataBaseField(
ThisExpression(), fileOffset),
@@ -1176,7 +1160,7 @@
Constant generateConstant(FfiTransformer transformer) => TypeLiteralConstant(
InterfaceType(transformer.pointerClass, Nullability.nonNullable, [
InterfaceType(
- transformer.pointerClass.superclass, Nullability.nonNullable)
+ transformer.pointerClass.superclass!, Nullability.nonNullable)
]));
/// Sample output for `Pointer<Int8> get x =>`:
@@ -1195,7 +1179,7 @@
transformer.fromAddressInternal,
Arguments([
StaticInvocation(
- transformer.loadMethods[NativeType.kIntptr],
+ transformer.loadMethods[NativeType.kIntptr]!,
Arguments([
transformer.getCompoundTypedDataBaseField(
ThisExpression(), fileOffset),
@@ -1221,7 +1205,7 @@
VariableDeclaration argument,
FfiTransformer transformer) =>
ReturnStatement(StaticInvocation(
- transformer.storeMethods[NativeType.kIntptr],
+ transformer.storeMethods[NativeType.kIntptr]!,
Arguments([
transformer.getCompoundTypedDataBaseField(
ThisExpression(), fileOffset),
@@ -1312,10 +1296,10 @@
class StructNativeTypeCfe extends CompoundNativeTypeCfe {
// Nullable int.
- final int packing;
+ final int? packing;
factory StructNativeTypeCfe(Class clazz, List<NativeTypeCfe> members,
- {int packing}) {
+ {int? packing}) {
final layout = Map.fromEntries(Abi.values
.map((abi) => MapEntry(abi, _calculateLayout(members, packing, abi))));
return StructNativeTypeCfe._(clazz, members, packing, layout);
@@ -1328,13 +1312,13 @@
// Keep consistent with runtime/vm/compiler/ffi/native_type.cc
// NativeStructType::FromNativeTypes.
static CompoundLayout _calculateLayout(
- List<NativeTypeCfe> types, int packing, Abi abi) {
+ List<NativeTypeCfe> types, int? packing, Abi abi) {
int offset = 0;
final offsets = <int>[];
int structAlignment = 1;
for (int i = 0; i < types.length; i++) {
- final int size = types[i].size[abi];
- int alignment = types[i].alignment[abi];
+ final int size = types[i].size[abi]!;
+ int alignment = types[i].alignment[abi]!;
if (packing != null && packing < alignment) {
alignment = packing;
}
@@ -1367,8 +1351,8 @@
int unionSize = 1;
int unionAlignment = 1;
for (int i = 0; i < types.length; i++) {
- final int size = types[i].size[abi];
- int alignment = types[i].alignment[abi];
+ final int size = types[i].size[abi]!;
+ int alignment = types[i].alignment[abi]!;
unionSize = math.max(unionSize, size);
unionAlignment = math.max(unionAlignment, alignment);
}
diff --git a/pkg/vm/lib/transformations/ffi_native.dart b/pkg/vm/lib/transformations/ffi_native.dart
index 76c25d0..54bdcb6 100644
--- a/pkg/vm/lib/transformations/ffi_native.dart
+++ b/pkg/vm/lib/transformations/ffi_native.dart
@@ -14,7 +14,9 @@
/// Transform @FfiNative annotated functions into FFI native function pointer
/// functions.
-void transformLibraries(Component component, List<Library> libraries,
+void transformLibraries(
+ Component component,
+ List<Library> libraries,
DiagnosticReporter diagnosticReporter,
ReferenceFromIndex? referenceFromIndex) {
final index = LibraryIndex(component, ['dart:ffi']);
@@ -22,8 +24,8 @@
if (index.tryGetClass('dart:ffi', 'FfiNative') == null) {
return;
}
- final transformer = FfiNativeTransformer(index, diagnosticReporter,
- referenceFromIndex);
+ final transformer =
+ FfiNativeTransformer(index, diagnosticReporter, referenceFromIndex);
libraries.forEach(transformer.visitLibrary);
}
@@ -41,8 +43,8 @@
final Procedure asFunctionProcedure;
final Procedure fromAddressInternal;
- FfiNativeTransformer(LibraryIndex index, this.diagnosticReporter,
- this.referenceFromIndex)
+ FfiNativeTransformer(
+ LibraryIndex index, this.diagnosticReporter, this.referenceFromIndex)
: ffiNativeClass = index.getClass('dart:ffi', 'FfiNative'),
nativeFunctionClass = index.getClass('dart:ffi', 'NativeFunction'),
ffiNativeNameField =
@@ -169,11 +171,8 @@
}
if (!node.isStatic) {
- diagnosticReporter.report(
- messageFfiNativeAnnotationMustAnnotateStatic,
- node.fileOffset,
- 1,
- node.location!.file);
+ diagnosticReporter.report(messageFfiNativeAnnotationMustAnnotateStatic,
+ node.fileOffset, 1, node.location!.file);
}
node.isExternal = false;
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi_use_sites.dart
index 7ee4ecc..49281ed 100644
--- a/pkg/vm/lib/transformations/ffi_use_sites.dart
+++ b/pkg/vm/lib/transformations/ffi_use_sites.dart
@@ -2,10 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
-library vm.transformations.ffi_use_sites;
-
import 'package:front_end/src/api_unstable/vm.dart'
show
messageFfiExceptionalReturnNull,
@@ -46,7 +42,7 @@
ClassHierarchy hierarchy,
List<Library> libraries,
DiagnosticReporter diagnosticReporter,
- ReferenceFromIndex referenceFromIndex) {
+ ReferenceFromIndex? referenceFromIndex) {
final index = new LibraryIndex(
component, ["dart:ffi", "dart:_internal", "dart:typed_data"]);
if (!index.containsLibrary("dart:ffi")) {
@@ -66,7 +62,7 @@
/// Checks and replaces calls to dart:ffi compound fields and methods.
class _FfiUseSiteTransformer extends FfiTransformer {
- StaticTypeContext _staticTypeContext;
+ StaticTypeContext? _staticTypeContext;
bool get isFfiLibrary => currentLibrary == ffiLibrary;
@@ -79,7 +75,7 @@
CoreTypes coreTypes,
ClassHierarchy hierarchy,
DiagnosticReporter diagnosticReporter,
- ReferenceFromIndex referenceFromIndex)
+ ReferenceFromIndex? referenceFromIndex)
: super(index, coreTypes, hierarchy, diagnosticReporter,
referenceFromIndex) {}
@@ -176,7 +172,7 @@
_ensureNativeTypeValid(nativeType, node, allowCompounds: true);
if (nativeType is InterfaceType) {
- Expression inlineSizeOf = _inlineSizeOf(nativeType);
+ Expression? inlineSizeOf = _inlineSizeOf(nativeType);
if (inlineSizeOf != null) {
return inlineSizeOf;
}
@@ -206,7 +202,7 @@
return replacement;
} else if (target == asFunctionMethod) {
final dartType = node.arguments.types[1];
- final DartType nativeType = InterfaceType(
+ final InterfaceType nativeType = InterfaceType(
nativeFunctionClass, Nullability.legacy, [node.arguments.types[0]]);
_ensureNativeTypeValid(nativeType, node);
@@ -214,10 +210,9 @@
_ensureIsLeafIsConst(node);
_ensureLeafCallDoesNotUseHandles(nativeType, node);
- final DartType nativeSignature =
- (nativeType as InterfaceType).typeArguments[0];
+ final DartType nativeSignature = nativeType.typeArguments[0];
- bool isLeaf = _getIsLeafBoolean(node);
+ bool? isLeaf = _getIsLeafBoolean(node);
if (isLeaf == null) {
isLeaf = false;
}
@@ -243,7 +238,7 @@
final DartType nativeType = InterfaceType(
nativeFunctionClass, Nullability.legacy, [node.arguments.types[0]]);
final Expression func = node.arguments.positional[0];
- final DartType dartType = func.getStaticType(_staticTypeContext);
+ final DartType dartType = func.getStaticType(_staticTypeContext!);
_ensureIsStaticFunction(func);
@@ -257,7 +252,7 @@
((node.arguments.types[0] as FunctionType).returnType
as InterfaceType)
.classNode;
- final NativeType expectedReturn = getType(expectedReturnClass);
+ final NativeType? expectedReturn = getType(expectedReturnClass);
if (expectedReturn == NativeType.kVoid ||
expectedReturn == NativeType.kPointer ||
@@ -309,7 +304,7 @@
}
final DartType returnType =
- exceptionalReturn.getStaticType(_staticTypeContext);
+ exceptionalReturn.getStaticType(_staticTypeContext!);
if (!env.isSubtypeOf(returnType, funcType.returnType,
SubtypeCheckMode.ignoringNullabilities)) {
@@ -339,7 +334,7 @@
// Inline the body to get rid of a generic invocation of sizeOf.
// TODO(http://dartbug.com/39964): Add `allignmentOf<T>()` call.
- Expression sizeInBytes = _inlineSizeOf(nativeType);
+ Expression? sizeInBytes = _inlineSizeOf(nativeType as InterfaceType);
if (sizeInBytes != null) {
if (node.arguments.positional.length == 2) {
sizeInBytes = multiply(node.arguments.positional[1], sizeInBytes);
@@ -401,9 +396,9 @@
.distinct()
.fold(nestedExpression, _invokeCompoundConstructor);
- Expression _inlineSizeOf(InterfaceType nativeType) {
+ Expression? _inlineSizeOf(InterfaceType nativeType) {
final Class nativeClass = nativeType.classNode;
- final NativeType nt = getType(nativeClass);
+ final NativeType? nt = getType(nativeClass);
if (nt == null) {
// User-defined compounds.
final Procedure sizeOfGetter = nativeClass.procedures
@@ -457,7 +452,7 @@
.substituteType(lookupFunctionType.withoutTypeParameters)
as FunctionType);
- bool isLeaf = _getIsLeafBoolean(node);
+ bool? isLeaf = _getIsLeafBoolean(node);
if (isLeaf == null) {
isLeaf = false;
}
@@ -518,7 +513,7 @@
pointer,
offsetByMethod.name,
Arguments([
- multiply(node.arguments.positional[1], _inlineSizeOf(dartType))
+ multiply(node.arguments.positional[1], _inlineSizeOf(dartType)!)
]),
interfaceTarget: offsetByMethod,
functionType:
@@ -536,8 +531,8 @@
final typedDataBasePrime = typedDataBaseOffset(
getArrayTypedDataBaseField(NullCheck(node.arguments.positional[0])),
- multiply(node.arguments.positional[1], _inlineSizeOf(dartType)),
- _inlineSizeOf(dartType),
+ multiply(node.arguments.positional[1], _inlineSizeOf(dartType)!),
+ _inlineSizeOf(dartType)!,
dartType,
node.fileOffset);
@@ -600,7 +595,7 @@
type: coreTypes.intNonNullableRawType)
..fileOffset = node.fileOffset;
final singleElementSizeVar = VariableDeclaration("#singleElementSize",
- initializer: _inlineSizeOf(elementType),
+ initializer: _inlineSizeOf(elementType as InterfaceType),
type: coreTypes.intNonNullableRawType)
..fileOffset = node.fileOffset;
final elementSizeVar = VariableDeclaration("#elementSize",
@@ -684,12 +679,12 @@
try {
if (target == elementAtMethod) {
final DartType pointerType =
- node.receiver.getStaticType(_staticTypeContext);
- final DartType nativeType = _pointerTypeGetTypeArg(pointerType);
+ node.receiver.getStaticType(_staticTypeContext!);
+ final DartType nativeType = _pointerTypeGetTypeArg(pointerType)!;
_ensureNativeTypeValid(nativeType, node, allowCompounds: true);
- Expression inlineSizeOf = _inlineSizeOf(nativeType);
+ Expression? inlineSizeOf = _inlineSizeOf(nativeType as InterfaceType);
if (inlineSizeOf != null) {
// Generates `receiver.offsetBy(inlineSizeOfExpression)`.
return InstanceInvocation(
@@ -714,7 +709,7 @@
return node;
}
- DartType _pointerTypeGetTypeArg(DartType pointerType) {
+ DartType? _pointerTypeGetTypeArg(DartType pointerType) {
return pointerType is InterfaceType ? pointerType.typeArguments[0] : null;
}
@@ -724,7 +719,7 @@
final DartType correspondingDartType = convertNativeTypeToDartType(
nativeType,
allowCompounds: true,
- allowHandle: allowHandle);
+ allowHandle: allowHandle)!;
if (dartType == correspondingDartType) return;
if (env.isSubtypeOf(correspondingDartType, dartType,
SubtypeCheckMode.ignoringNullabilities)) {
@@ -787,7 +782,7 @@
/// Returns the class that should not be implemented or extended.
///
/// If the superclass is not sealed, returns `null`.
- Class _extendsOrImplementsSealedClass(Class klass) {
+ Class? _extendsOrImplementsSealedClass(Class klass) {
// Classes in dart:ffi themselves can extend FFI classes.
if (klass == arrayClass ||
klass == arraySizeClass ||
@@ -824,7 +819,7 @@
}
void _ensureNotExtendsOrImplementsSealedClass(Class klass) {
- final Class extended = _extendsOrImplementsSealedClass(klass);
+ final Class? extended = _extendsOrImplementsSealedClass(klass);
if (extended != null) {
diagnosticReporter.report(
templateFfiExtendsOrImplementsSealedClass
@@ -840,7 +835,7 @@
// - `true` if leaf
// - `false` if not leaf
// - `null` if the expression is not valid (e.g. non-const bool, null)
- bool _getIsLeafBoolean(StaticInvocation node) {
+ bool? _getIsLeafBoolean(StaticInvocation node) {
for (final named in node.arguments.named) {
if (named.name == 'isLeaf') {
final expr = named.value;
@@ -893,8 +888,8 @@
}
}
// Check if any of the argument types are Handle.
- for (InterfaceType param in functionType.positionalParameters) {
- if (param.classNode == handleClass) {
+ for (DartType param in functionType.positionalParameters) {
+ if ((param as InterfaceType).classNode == handleClass) {
diagnosticReporter.report(messageFfiLeafCallMustNotTakeHandle,
node.fileOffset, 1, node.location?.file);
}
diff --git a/pkg/vm/lib/transformations/list_literals_lowering.dart b/pkg/vm/lib/transformations/list_literals_lowering.dart
index c7f6739..1acb42f 100644
--- a/pkg/vm/lib/transformations/list_literals_lowering.dart
+++ b/pkg/vm/lib/transformations/list_literals_lowering.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
import 'package:front_end/src/api_unstable/vm.dart'
show isRedirectingFactoryField;
import 'package:kernel/ast.dart';
@@ -24,23 +22,24 @@
final Procedure _defaultFactory;
// Specialized _GrowableList._literalN(e1, ..., eN) factories.
- final List<Procedure> _specializedFactories =
- List<Procedure>.filled(numSpecializedFactories, null);
+ final List<Procedure?> _specializedFactories =
+ List<Procedure?>.filled(numSpecializedFactories, null);
ListLiteralsLowering(this.coreTypes)
: _defaultFactory =
- coreTypes.index.getMember('dart:core', '_GrowableList', '');
+ coreTypes.index.getProcedure('dart:core', '_GrowableList', '');
Procedure getSpecializedFactory(int length) =>
(_specializedFactories[length - 1] ??= coreTypes.index
- .getMember('dart:core', '_GrowableList', '_literal$length'));
+ .getProcedure('dart:core', '_GrowableList', '_literal$length'));
Expression transformListLiteral(ListLiteral node) {
if (node.isConst) {
throw 'Unexpected constant ListLiteral node'
' (such nodes should be converted to ConstantExpression): $node';
}
- if (node.parent is Field && isRedirectingFactoryField(node.parent)) {
+ final parent = node.parent;
+ if (parent is Field && isRedirectingFactoryField(parent)) {
// Do not transform list literals which are used to represent
// redirecting factories.
return node;
diff --git a/pkg/vm/lib/transformations/lowering.dart b/pkg/vm/lib/transformations/lowering.dart
index 72932d9..d776f33 100644
--- a/pkg/vm/lib/transformations/lowering.dart
+++ b/pkg/vm/lib/transformations/lowering.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
import 'package:kernel/core_types.dart' show CoreTypes;
@@ -39,8 +37,8 @@
final FactorySpecializer factorySpecializer;
final ListLiteralsLowering listLiteralsLowering;
- Member _currentMember;
- StaticTypeContext _cachedStaticTypeContext;
+ Member? _currentMember;
+ StaticTypeContext? _cachedStaticTypeContext;
_Lowering(CoreTypes coreTypes, ClassHierarchy hierarchy, this.nullSafety)
: env = TypeEnvironment(coreTypes, hierarchy),
@@ -49,7 +47,7 @@
listLiteralsLowering = ListLiteralsLowering(coreTypes);
StaticTypeContext get _staticTypeContext =>
- _cachedStaticTypeContext ??= StaticTypeContext(_currentMember, env);
+ _cachedStaticTypeContext ??= StaticTypeContext(_currentMember!, env);
@override
defaultMember(Member node) {
diff --git a/pkg/vm/test/dominators_test.dart b/pkg/vm/test/dominators_test.dart
index 15163b2..f9e6ee6 100644
--- a/pkg/vm/test/dominators_test.dart
+++ b/pkg/vm/test/dominators_test.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart=2.9
-
import 'package:expect/expect.dart';
import 'package:vm/dominators.dart';
diff --git a/pkg/vm_service/test/mark_main_isolate_as_system_isolate_test.dart b/pkg/vm_service/test/mark_main_isolate_as_system_isolate_test.dart
new file mode 100644
index 0000000..c69323d
--- /dev/null
+++ b/pkg/vm_service/test/mark_main_isolate_as_system_isolate_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:isolate';
+import 'package:test/test.dart';
+import 'package:vm_service/vm_service.dart' as service;
+
+import 'common/service_test_common.dart';
+import 'common/test_helper.dart';
+
+foo(void _) async {
+ print('non system isolate started');
+ while (true) {}
+}
+
+testMain() async {
+ await Isolate.spawn<void>(foo, null);
+ print('started system isolate main');
+ while (true) {}
+}
+
+var tests = <VMTest>[
+ (service.VmService service) async {
+ final vm = await service.getVM();
+ expect(vm.isolates!.length, 1);
+ expect(vm.isolates!.first.name, 'foo');
+ expect(vm.systemIsolates!.length, greaterThanOrEqualTo(1));
+ expect(vm.systemIsolates!.where((e) => e.name == 'main').isNotEmpty, true);
+ }
+];
+
+main([args = const <String>[]]) => runVMTests(
+ args,
+ tests,
+ 'mark_main_isolate_as_system_isolate_test.dart',
+ testeeConcurrent: testMain,
+ extraArgs: ['--mark-main-isolate-as-system-isolate'],
+ );
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index ba743e7..a288a79 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -934,6 +934,7 @@
int exit_code = 0;
Dart_IsolateFlags flags;
Dart_IsolateFlagsInitialize(&flags);
+ flags.is_system_isolate = Options::mark_main_isolate_as_system_isolate();
Dart_Isolate isolate = CreateIsolateGroupAndSetupHelper(
/* is_main_isolate */ true, script_name, "main",
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index 8f9736d..66e6fde 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -46,7 +46,8 @@
V(disable_dart_dev, disable_dart_dev) \
V(long_ssl_cert_evaluation, long_ssl_cert_evaluation) \
V(bypass_trusting_system_roots, bypass_trusting_system_roots) \
- V(delayed_filewatch_callback, delayed_filewatch_callback)
+ V(delayed_filewatch_callback, delayed_filewatch_callback) \
+ V(mark_main_isolate_as_system_isolate, mark_main_isolate_as_system_isolate)
// Boolean flags that have a short form.
#define SHORT_BOOL_OPTIONS_LIST(V) \
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 18789db..0ca25ee 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -634,6 +634,7 @@
// Make a copy of the state's isolate flags and hand it to the callback.
Dart_IsolateFlags api_flags = *(state_->isolate_flags());
+ api_flags.is_system_isolate = false;
Dart_Isolate isolate = (create_group_callback)(
state_->script_url(), name, nullptr, state_->package_config(),
&api_flags, parent_isolate_->init_callback_data(), &error);
diff --git a/runtime/vm/compiler/frontend/prologue_builder.cc b/runtime/vm/compiler/frontend/prologue_builder.cc
index 035bf63..635b3d9 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.cc
+++ b/runtime/vm/compiler/frontend/prologue_builder.cc
@@ -68,6 +68,11 @@
if (expect_type_args) {
Fragment f = BuildTypeArgumentsHandling();
if (link) prologue += f;
+
+ if (function_.IsClosureFunction()) {
+ Fragment f = BuildClosureDelayedTypeArgumentsHandling();
+ if (!compiling_for_osr_) prologue += f;
+ }
}
const bool is_empty_prologue = prologue.entry == prologue.current;
@@ -372,29 +377,33 @@
handling += TestTypeArgsLen(store_null, store_type_args, 0);
- const auto& function = parsed_function_->function();
- if (function.IsClosureFunction()) {
- LocalVariable* closure = parsed_function_->ParameterVariable(0);
-
- // Currently, delayed type arguments can only be introduced through type
- // inference in the FE. So if they are present, we can assume they are
- // correct in number and bound.
- Fragment use_delayed_type_args;
- use_delayed_type_args += LoadLocal(closure);
- use_delayed_type_args +=
- LoadNativeField(Slot::Closure_delayed_type_arguments());
- use_delayed_type_args +=
- StoreLocal(TokenPosition::kNoSource, type_args_var);
- use_delayed_type_args += Drop();
-
- handling += TestDelayedTypeArgs(closure,
- /*present=*/use_delayed_type_args,
- /*absent=*/Fragment());
- }
-
return handling;
}
+Fragment PrologueBuilder::BuildClosureDelayedTypeArgumentsHandling() {
+ const auto& function = parsed_function_->function();
+ ASSERT(function.IsClosureFunction());
+ LocalVariable* const type_args_var =
+ parsed_function_->RawTypeArgumentsVariable();
+ ASSERT(type_args_var != nullptr);
+
+ LocalVariable* const closure = parsed_function_->ParameterVariable(0);
+
+ // Currently, delayed type arguments can only be introduced through type
+ // inference in the FE. So if they are present, we can assume they are
+ // correct in number and bound.
+ Fragment use_delayed_type_args;
+ use_delayed_type_args += LoadLocal(closure);
+ use_delayed_type_args +=
+ LoadNativeField(Slot::Closure_delayed_type_arguments());
+ use_delayed_type_args += StoreLocal(TokenPosition::kNoSource, type_args_var);
+ use_delayed_type_args += Drop();
+
+ return TestDelayedTypeArgs(closure,
+ /*present=*/use_delayed_type_args,
+ /*absent=*/Fragment());
+}
+
void PrologueBuilder::SortOptionalNamedParametersInto(int* opt_param_position,
int num_fixed_params,
int num_params) {
diff --git a/runtime/vm/compiler/frontend/prologue_builder.h b/runtime/vm/compiler/frontend/prologue_builder.h
index c8d629d..d474d72 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.h
+++ b/runtime/vm/compiler/frontend/prologue_builder.h
@@ -61,6 +61,8 @@
Fragment BuildTypeArgumentsHandling();
+ Fragment BuildClosureDelayedTypeArgumentsHandling();
+
LocalVariable* ParameterVariable(intptr_t index) {
return parsed_function_->RawParameterVariable(index);
}
diff --git a/tests/language/regress/regress46550_test.dart b/tests/language/regress/regress46550_test.dart
new file mode 100644
index 0000000..9b609da
--- /dev/null
+++ b/tests/language/regress/regress46550_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--optimization_counter_threshold=100 --deterministic
+
+import "package:expect/expect.dart";
+
+typedef void test1<T extends num>();
+
+void t1<T extends int>() {
+ Expect.equals(int, T);
+}
+
+const test1 res1 = t1;
+
+main() {
+ for (int i = 0; i < 120; ++i) {
+ res1();
+ }
+}
diff --git a/tests/language_2/regress/regress46550_test.dart b/tests/language_2/regress/regress46550_test.dart
new file mode 100644
index 0000000..9b609da
--- /dev/null
+++ b/tests/language_2/regress/regress46550_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--optimization_counter_threshold=100 --deterministic
+
+import "package:expect/expect.dart";
+
+typedef void test1<T extends num>();
+
+void t1<T extends int>() {
+ Expect.equals(int, T);
+}
+
+const test1 res1 = t1;
+
+main() {
+ for (int i = 0; i < 120; ++i) {
+ res1();
+ }
+}
diff --git a/tools/VERSION b/tools/VERSION
index 627df9f..1d8f46a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 344
+PRERELEASE 345
PRERELEASE_PATCH 0
\ No newline at end of file