Version 2.14.0-353.0.dev
Merge commit 'db90fd784b16ff6282ee4f3d62be1b51d0f72e6f' into 'dev'
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 7730306..ef545f2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1369,46 +1369,6 @@
typeAliasedFactoryInvocations.clear();
}
- @override
- bool isProperRenameForClass(Typedef typedef) {
- DartType? rhsType = typedef.type;
- if (rhsType is! InterfaceType) {
- return false;
- }
-
- List<TypeParameter> fromParameters = typedef.typeParameters;
- List<TypeParameter> toParameters = rhsType.classNode.typeParameters;
- List<DartType> typeArguments = rhsType.typeArguments;
- if (fromParameters.length != typeArguments.length) {
- return false;
- }
- for (int i = 0; i < fromParameters.length; ++i) {
- if (typeArguments[i] !=
- new TypeParameterType.withDefaultNullabilityForLibrary(
- fromParameters[i], typedef.enclosingLibrary)) {
- return false;
- }
- }
-
- Map<TypeParameter, DartType> substitutionMap = {};
- for (int i = 0; i < fromParameters.length; ++i) {
- substitutionMap[fromParameters[i]] =
- new TypeParameterType.forAlphaRenaming(
- fromParameters[i], toParameters[i]);
- }
- Substitution substitution = Substitution.fromMap(substitutionMap);
- for (int i = 0; i < fromParameters.length; ++i) {
- if (!typeEnvironment.areMutualSubtypes(
- toParameters[i].bound,
- substitution.substituteType(fromParameters[i].bound),
- SubtypeCheckMode.withNullabilities)) {
- return false;
- }
- }
-
- return true;
- }
-
/// Perform actions that were delayed
///
/// An action can be delayed, for instance, because it depends on some
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index 4a0b5ca..5333b0c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -63,7 +63,8 @@
import 'constness.dart' show Constness;
-import 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
+import 'expression_generator_helper.dart'
+ show ExpressionGeneratorHelper, isProperRenameForClass;
import 'forest.dart';
@@ -3217,11 +3218,12 @@
_helper.buildDartTypeArguments(typeArguments);
}
if (isGenericTypedefTearOff) {
- if (_helper.isProperRenameForClass(aliasBuilder!.typedef)) {
+ if (isProperRenameForClass(
+ _helper.typeEnvironment, aliasBuilder!.typedef)) {
return tearOffExpression;
}
- Procedure? tearOffLowering = aliasBuilder
- .findConstructorOrFactory(
+ Procedure? tearOffLowering =
+ aliasBuilder.findConstructorOrFactory(
name.text, nameOffset, _uri, _helper.libraryBuilder);
if (tearOffLowering != null) {
return _helper.forest
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
index 8578128..c19553b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
@@ -5,6 +5,8 @@
library fasta.expression_generator_helper;
import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
+import 'package:kernel/type_algebra.dart';
+import 'package:kernel/type_environment.dart';
import '../builder/builder.dart';
import '../builder/formal_parameter_builder.dart';
@@ -30,12 +32,14 @@
Expression,
FunctionNode,
Initializer,
+ InterfaceType,
Member,
Name,
Procedure,
StaticGet,
TreeNode,
TypeParameter,
+ TypeParameterType,
Typedef,
VariableDeclaration;
@@ -178,6 +182,44 @@
/// This is needed for type promotion.
void registerVariableAssignment(VariableDeclaration variable);
- /// Checks that a generic [typedef] for a generic class.
- bool isProperRenameForClass(Typedef typedef);
+ TypeEnvironment get typeEnvironment;
+}
+
+/// Checks that a generic [typedef] for a generic class.
+bool isProperRenameForClass(TypeEnvironment typeEnvironment, Typedef typedef) {
+ DartType? rhsType = typedef.type;
+ if (rhsType is! InterfaceType) {
+ return false;
+ }
+
+ List<TypeParameter> fromParameters = typedef.typeParameters;
+ List<TypeParameter> toParameters = rhsType.classNode.typeParameters;
+ List<DartType> typeArguments = rhsType.typeArguments;
+ if (fromParameters.length != typeArguments.length) {
+ return false;
+ }
+ for (int i = 0; i < fromParameters.length; ++i) {
+ if (typeArguments[i] !=
+ new TypeParameterType.withDefaultNullabilityForLibrary(
+ fromParameters[i], typedef.enclosingLibrary)) {
+ return false;
+ }
+ }
+
+ Map<TypeParameter, DartType> substitutionMap = {};
+ for (int i = 0; i < fromParameters.length; ++i) {
+ substitutionMap[fromParameters[i]] = new TypeParameterType.forAlphaRenaming(
+ fromParameters[i], toParameters[i]);
+ }
+ Substitution substitution = Substitution.fromMap(substitutionMap);
+ for (int i = 0; i < fromParameters.length; ++i) {
+ if (!typeEnvironment.areMutualSubtypes(
+ toParameters[i].bound,
+ substitution.substituteType(fromParameters[i].bound),
+ SubtypeCheckMode.withNullabilities)) {
+ return false;
+ }
+ }
+
+ return true;
}
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 0d35d0f..098e1aa 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -326,12 +326,12 @@
installDefaultSupertypes();
installSyntheticConstructors(myClasses);
loader.resolveConstructors();
- loader.installTypedefTearOffs();
component =
link(new List<Library>.from(loader.libraries), nameRoot: nameRoot);
computeCoreTypes();
loader.buildClassHierarchy(myClasses, objectClassBuilder);
loader.computeHierarchy();
+ loader.installTypedefTearOffs();
loader.performTopLevelInference(myClasses);
loader.checkSupertypes(myClasses);
loader.checkOverrides(myClasses);
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
index ed04394..60e717f 100644
--- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -4,6 +4,7 @@
library fasta.source_type_alias_builder;
+import 'package:front_end/src/fasta/kernel/expression_generator_helper.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart';
@@ -277,7 +278,9 @@
void buildTypedefTearOffs(
SourceLibraryBuilder library, void Function(Procedure) f) {
TypeDeclarationBuilder? declaration = unaliasDeclaration(null);
- if (declaration is ClassBuilder) {
+ if (declaration is ClassBuilder &&
+ typedef.typeParameters.isNotEmpty &&
+ !isProperRenameForClass(library.loader.typeEnvironment, typedef)) {
tearOffs = {};
_tearOffDependencies = {};
declaration
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index a51d1da..d6f2f0c 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -437,6 +437,10 @@
fuzz
fuzzing
fx
+g2a
+g2b
+g3a
+g3b
gallery
gamma
gave
@@ -454,6 +458,16 @@
gtgt
gulp
gunk
+h2a
+h2b
+h3a
+h3b
+h4a
+h4b
+h5a
+h5b
+h6a
+h6b
hackish
hardly
helper2
@@ -472,6 +486,9 @@
hunk
hurray
i'm
+i2a
+i3a
+i3b
ia
ideal
identification
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart
new file mode 100644
index 0000000..1cbbc8e
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart
@@ -0,0 +1,62 @@
+// 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 {}
+
+class B<T> {}
+
+class C<X, Y> {}
+
+class D<X extends num> {}
+
+typedef F = A;
+
+typedef G0 = B;
+typedef G1 = B<int>;
+typedef G2<T> = B<T>;
+typedef G3<T extends num> = B<T>;
+
+typedef H0 = C;
+typedef H1 = C<int, String>;
+typedef H2<T> = C<int, T>;
+typedef H3<T, S> = C<T, S>;
+typedef H4<T, S> = C<S, T>;
+typedef H5<T extends num, S> = C<T, S>;
+typedef H6<T, S extends num> = C<T, S>;
+
+typedef I0 = D;
+typedef I1 = D<num>;
+typedef I2<T extends num> = D<T>;
+typedef I3<T extends int> = D<T>;
+
+main() {
+ var f = F.new;
+
+ var g0 = G0.new;
+ var g1 = G1.new;
+ var g2a = G2.new;
+ var g2b = G2<int>.new;
+ var g3a = G3.new;
+ var g3b = G3<int>.new;
+
+ var h0 = H0.new;
+ var h1 = H1.new;
+ var h2a = H2.new;
+ var h2b = H2<int>.new;
+ var h3a = H3.new;
+ var h3b = H3<int, String>.new;
+ var h4a = H4.new;
+ var h4b = H4<int, String>.new;
+ var h5a = H5.new;
+ var h5b = H5<int, String>.new;
+ var h6a = H6.new;
+ var h6b = H6<String, int>.new;
+
+ var i0 = I0.new;
+ var i1 = I1.new;
+ var i2a = I2.new;
+ var i2b = I2<int>.new;
+ var i3a = I3.new;
+ var i3b = I3<int>.new;
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.strong.expect
new file mode 100644
index 0000000..b6e38f4
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.strong.expect
@@ -0,0 +1,108 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F = self::A;
+typedef G0 = self::B<dynamic>;
+typedef G1 = self::B<core::int>;
+typedef G2<T extends core::Object? = dynamic> = self::B<T%>;
+typedef G3<T extends core::num> = self::B<T>;
+typedef H0 = self::C<dynamic, dynamic>;
+typedef H1 = self::C<core::int, core::String>;
+typedef H2<T extends core::Object? = dynamic> = self::C<core::int, T%>;
+typedef H3<T extends core::Object? = dynamic, S extends core::Object? = dynamic> = self::C<T%, S%>;
+typedef H4<T extends core::Object? = dynamic, S extends core::Object? = dynamic> = self::C<S%, T%>;
+typedef H5<T extends core::num, S extends core::Object? = dynamic> = self::C<T, S%>;
+typedef H6<T extends core::Object? = dynamic, S extends core::num> = self::C<T%, S>;
+typedef I0 = self::D<core::num>;
+typedef I1 = self::D<core::num>;
+typedef I2<T extends core::num> = self::D<T>;
+typedef I3<T extends core::int> = self::D<T>;
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::A
+ return new self::A::•();
+}
+class B<T extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::T%>
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff<T extends core::Object? = dynamic>() → self::B<self::B::_#new#tearOff::T%>
+ return new self::B::•<self::B::_#new#tearOff::T%>();
+}
+class C<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::X%, self::C::Y%>
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → self::C<self::C::_#new#tearOff::X%, self::C::_#new#tearOff::Y%>
+ return new self::C::•<self::C::_#new#tearOff::X%, self::C::_#new#tearOff::Y%>();
+}
+class D<X extends core::num> extends core::Object {
+ synthetic constructor •() → self::D<self::D::X>
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff<X extends core::num>() → self::D<self::D::_#new#tearOff::X>
+ return new self::D::•<self::D::_#new#tearOff::X>();
+}
+static method main() → dynamic {
+ () → self::A f = #C1;
+ () → self::B<dynamic> g0 = #C3;
+ () → self::B<core::int> g1 = #C4;
+ <T extends core::Object? = dynamic>() → self::B<T%> g2a = #C2;
+ () → self::B<core::int> g2b = #C4;
+ <T extends core::num>() → self::B<T> g3a = #C5;
+ () → self::B<core::int> g3b = #C4;
+ () → self::C<dynamic, dynamic> h0 = #C7;
+ () → self::C<core::int, core::String> h1 = #C8;
+ <T extends core::Object? = dynamic>() → self::C<core::int, T%> h2a = #C9;
+ () → self::C<core::int, core::int> h2b = #C10;
+ <X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → self::C<X%, Y%> h3a = #C6;
+ () → self::C<core::int, core::String> h3b = #C8;
+ <T extends core::Object? = dynamic, S extends core::Object? = dynamic>() → self::C<S%, T%> h4a = #C11;
+ () → self::C<core::String, core::int> h4b = #C12;
+ <T extends core::num, S extends core::Object? = dynamic>() → self::C<T, S%> h5a = #C13;
+ () → self::C<core::int, core::String> h5b = #C8;
+ <T extends core::Object? = dynamic, S extends core::num>() → self::C<T%, S> h6a = #C14;
+ () → self::C<core::String, core::int> h6b = #C12;
+ () → self::D<core::num> i0 = #C16;
+ () → self::D<core::num> i1 = #C16;
+ <X extends core::num>() → self::D<X> i2a = #C15;
+ () → self::D<core::int> i2b = #C17;
+ <T extends core::int>() → self::D<T> i3a = #C18;
+ () → self::D<core::int> i3b = #C17;
+}
+static method _#G3#new#tearOff<T extends core::num>() → self::B<self::_#G3#new#tearOff::T>
+ return new self::B::•<self::_#G3#new#tearOff::T>();
+static method _#H2#new#tearOff<T extends core::Object? = dynamic>() → self::C<core::int, self::_#H2#new#tearOff::T%>
+ return new self::C::•<core::int, self::_#H2#new#tearOff::T%>();
+static method _#H4#new#tearOff<T extends core::Object? = dynamic, S extends core::Object? = dynamic>() → self::C<self::_#H4#new#tearOff::S%, self::_#H4#new#tearOff::T%>
+ return new self::C::•<self::_#H4#new#tearOff::S%, self::_#H4#new#tearOff::T%>();
+static method _#H5#new#tearOff<T extends core::num, S extends core::Object? = dynamic>() → self::C<self::_#H5#new#tearOff::T, self::_#H5#new#tearOff::S%>
+ return new self::C::•<self::_#H5#new#tearOff::T, self::_#H5#new#tearOff::S%>();
+static method _#H6#new#tearOff<T extends core::Object? = dynamic, S extends core::num>() → self::C<self::_#H6#new#tearOff::T%, self::_#H6#new#tearOff::S>
+ return new self::C::•<self::_#H6#new#tearOff::T%, self::_#H6#new#tearOff::S>();
+static method _#I3#new#tearOff<T extends core::int>() → self::D<self::_#I3#new#tearOff::T>
+ return new self::D::•<self::_#I3#new#tearOff::T>();
+
+constants {
+ #C1 = static-tearoff self::A::_#new#tearOff
+ #C2 = static-tearoff self::B::_#new#tearOff
+ #C3 = instantiation self::B::_#new#tearOff <dynamic>
+ #C4 = instantiation self::B::_#new#tearOff <core::int>
+ #C5 = static-tearoff self::_#G3#new#tearOff
+ #C6 = static-tearoff self::C::_#new#tearOff
+ #C7 = instantiation self::C::_#new#tearOff <dynamic, dynamic>
+ #C8 = instantiation self::C::_#new#tearOff <core::int, core::String>
+ #C9 = static-tearoff self::_#H2#new#tearOff
+ #C10 = instantiation self::C::_#new#tearOff <core::int, core::int>
+ #C11 = static-tearoff self::_#H4#new#tearOff
+ #C12 = instantiation self::C::_#new#tearOff <core::String, core::int>
+ #C13 = static-tearoff self::_#H5#new#tearOff
+ #C14 = static-tearoff self::_#H6#new#tearOff
+ #C15 = static-tearoff self::D::_#new#tearOff
+ #C16 = instantiation self::D::_#new#tearOff <core::num>
+ #C17 = instantiation self::D::_#new#tearOff <core::int>
+ #C18 = static-tearoff self::_#I3#new#tearOff
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.strong.transformed.expect
new file mode 100644
index 0000000..b6e38f4
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.strong.transformed.expect
@@ -0,0 +1,108 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F = self::A;
+typedef G0 = self::B<dynamic>;
+typedef G1 = self::B<core::int>;
+typedef G2<T extends core::Object? = dynamic> = self::B<T%>;
+typedef G3<T extends core::num> = self::B<T>;
+typedef H0 = self::C<dynamic, dynamic>;
+typedef H1 = self::C<core::int, core::String>;
+typedef H2<T extends core::Object? = dynamic> = self::C<core::int, T%>;
+typedef H3<T extends core::Object? = dynamic, S extends core::Object? = dynamic> = self::C<T%, S%>;
+typedef H4<T extends core::Object? = dynamic, S extends core::Object? = dynamic> = self::C<S%, T%>;
+typedef H5<T extends core::num, S extends core::Object? = dynamic> = self::C<T, S%>;
+typedef H6<T extends core::Object? = dynamic, S extends core::num> = self::C<T%, S>;
+typedef I0 = self::D<core::num>;
+typedef I1 = self::D<core::num>;
+typedef I2<T extends core::num> = self::D<T>;
+typedef I3<T extends core::int> = self::D<T>;
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::A
+ return new self::A::•();
+}
+class B<T extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::T%>
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff<T extends core::Object? = dynamic>() → self::B<self::B::_#new#tearOff::T%>
+ return new self::B::•<self::B::_#new#tearOff::T%>();
+}
+class C<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::X%, self::C::Y%>
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → self::C<self::C::_#new#tearOff::X%, self::C::_#new#tearOff::Y%>
+ return new self::C::•<self::C::_#new#tearOff::X%, self::C::_#new#tearOff::Y%>();
+}
+class D<X extends core::num> extends core::Object {
+ synthetic constructor •() → self::D<self::D::X>
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff<X extends core::num>() → self::D<self::D::_#new#tearOff::X>
+ return new self::D::•<self::D::_#new#tearOff::X>();
+}
+static method main() → dynamic {
+ () → self::A f = #C1;
+ () → self::B<dynamic> g0 = #C3;
+ () → self::B<core::int> g1 = #C4;
+ <T extends core::Object? = dynamic>() → self::B<T%> g2a = #C2;
+ () → self::B<core::int> g2b = #C4;
+ <T extends core::num>() → self::B<T> g3a = #C5;
+ () → self::B<core::int> g3b = #C4;
+ () → self::C<dynamic, dynamic> h0 = #C7;
+ () → self::C<core::int, core::String> h1 = #C8;
+ <T extends core::Object? = dynamic>() → self::C<core::int, T%> h2a = #C9;
+ () → self::C<core::int, core::int> h2b = #C10;
+ <X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → self::C<X%, Y%> h3a = #C6;
+ () → self::C<core::int, core::String> h3b = #C8;
+ <T extends core::Object? = dynamic, S extends core::Object? = dynamic>() → self::C<S%, T%> h4a = #C11;
+ () → self::C<core::String, core::int> h4b = #C12;
+ <T extends core::num, S extends core::Object? = dynamic>() → self::C<T, S%> h5a = #C13;
+ () → self::C<core::int, core::String> h5b = #C8;
+ <T extends core::Object? = dynamic, S extends core::num>() → self::C<T%, S> h6a = #C14;
+ () → self::C<core::String, core::int> h6b = #C12;
+ () → self::D<core::num> i0 = #C16;
+ () → self::D<core::num> i1 = #C16;
+ <X extends core::num>() → self::D<X> i2a = #C15;
+ () → self::D<core::int> i2b = #C17;
+ <T extends core::int>() → self::D<T> i3a = #C18;
+ () → self::D<core::int> i3b = #C17;
+}
+static method _#G3#new#tearOff<T extends core::num>() → self::B<self::_#G3#new#tearOff::T>
+ return new self::B::•<self::_#G3#new#tearOff::T>();
+static method _#H2#new#tearOff<T extends core::Object? = dynamic>() → self::C<core::int, self::_#H2#new#tearOff::T%>
+ return new self::C::•<core::int, self::_#H2#new#tearOff::T%>();
+static method _#H4#new#tearOff<T extends core::Object? = dynamic, S extends core::Object? = dynamic>() → self::C<self::_#H4#new#tearOff::S%, self::_#H4#new#tearOff::T%>
+ return new self::C::•<self::_#H4#new#tearOff::S%, self::_#H4#new#tearOff::T%>();
+static method _#H5#new#tearOff<T extends core::num, S extends core::Object? = dynamic>() → self::C<self::_#H5#new#tearOff::T, self::_#H5#new#tearOff::S%>
+ return new self::C::•<self::_#H5#new#tearOff::T, self::_#H5#new#tearOff::S%>();
+static method _#H6#new#tearOff<T extends core::Object? = dynamic, S extends core::num>() → self::C<self::_#H6#new#tearOff::T%, self::_#H6#new#tearOff::S>
+ return new self::C::•<self::_#H6#new#tearOff::T%, self::_#H6#new#tearOff::S>();
+static method _#I3#new#tearOff<T extends core::int>() → self::D<self::_#I3#new#tearOff::T>
+ return new self::D::•<self::_#I3#new#tearOff::T>();
+
+constants {
+ #C1 = static-tearoff self::A::_#new#tearOff
+ #C2 = static-tearoff self::B::_#new#tearOff
+ #C3 = instantiation self::B::_#new#tearOff <dynamic>
+ #C4 = instantiation self::B::_#new#tearOff <core::int>
+ #C5 = static-tearoff self::_#G3#new#tearOff
+ #C6 = static-tearoff self::C::_#new#tearOff
+ #C7 = instantiation self::C::_#new#tearOff <dynamic, dynamic>
+ #C8 = instantiation self::C::_#new#tearOff <core::int, core::String>
+ #C9 = static-tearoff self::_#H2#new#tearOff
+ #C10 = instantiation self::C::_#new#tearOff <core::int, core::int>
+ #C11 = static-tearoff self::_#H4#new#tearOff
+ #C12 = instantiation self::C::_#new#tearOff <core::String, core::int>
+ #C13 = static-tearoff self::_#H5#new#tearOff
+ #C14 = static-tearoff self::_#H6#new#tearOff
+ #C15 = static-tearoff self::D::_#new#tearOff
+ #C16 = instantiation self::D::_#new#tearOff <core::num>
+ #C17 = instantiation self::D::_#new#tearOff <core::int>
+ #C18 = static-tearoff self::_#I3#new#tearOff
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.textual_outline.expect
new file mode 100644
index 0000000..9a7c825
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.textual_outline.expect
@@ -0,0 +1,25 @@
+class A {}
+
+class B<T> {}
+
+class C<X, Y> {}
+
+class D<X extends num> {}
+
+typedef F = A;
+typedef G0 = B;
+typedef G1 = B<int>;
+typedef G2<T> = B<T>;
+typedef G3<T extends num> = B<T>;
+typedef H0 = C;
+typedef H1 = C<int, String>;
+typedef H2<T> = C<int, T>;
+typedef H3<T, S> = C<T, S>;
+typedef H4<T, S> = C<S, T>;
+typedef H5<T extends num, S> = C<T, S>;
+typedef H6<T, S extends num> = C<T, S>;
+typedef I0 = D;
+typedef I1 = D<num>;
+typedef I2<T extends num> = D<T>;
+typedef I3<T extends int> = D<T>;
+main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f5f173a
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.textual_outline_modelled.expect
@@ -0,0 +1,25 @@
+class A {}
+
+class B<T> {}
+
+class C<X, Y> {}
+
+class D<X extends num> {}
+
+main() {}
+typedef F = A;
+typedef G0 = B;
+typedef G1 = B<int>;
+typedef G2<T> = B<T>;
+typedef G3<T extends num> = B<T>;
+typedef H0 = C;
+typedef H1 = C<int, String>;
+typedef H2<T> = C<int, T>;
+typedef H3<T, S> = C<T, S>;
+typedef H4<T, S> = C<S, T>;
+typedef H5<T extends num, S> = C<T, S>;
+typedef H6<T, S extends num> = C<T, S>;
+typedef I0 = D;
+typedef I1 = D<num>;
+typedef I2<T extends num> = D<T>;
+typedef I3<T extends int> = D<T>;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.weak.expect
new file mode 100644
index 0000000..2d72357
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.weak.expect
@@ -0,0 +1,108 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F = self::A;
+typedef G0 = self::B<dynamic>;
+typedef G1 = self::B<core::int>;
+typedef G2<T extends core::Object? = dynamic> = self::B<T%>;
+typedef G3<T extends core::num> = self::B<T>;
+typedef H0 = self::C<dynamic, dynamic>;
+typedef H1 = self::C<core::int, core::String>;
+typedef H2<T extends core::Object? = dynamic> = self::C<core::int, T%>;
+typedef H3<T extends core::Object? = dynamic, S extends core::Object? = dynamic> = self::C<T%, S%>;
+typedef H4<T extends core::Object? = dynamic, S extends core::Object? = dynamic> = self::C<S%, T%>;
+typedef H5<T extends core::num, S extends core::Object? = dynamic> = self::C<T, S%>;
+typedef H6<T extends core::Object? = dynamic, S extends core::num> = self::C<T%, S>;
+typedef I0 = self::D<core::num>;
+typedef I1 = self::D<core::num>;
+typedef I2<T extends core::num> = self::D<T>;
+typedef I3<T extends core::int> = self::D<T>;
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::A
+ return new self::A::•();
+}
+class B<T extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::T%>
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff<T extends core::Object? = dynamic>() → self::B<self::B::_#new#tearOff::T%>
+ return new self::B::•<self::B::_#new#tearOff::T%>();
+}
+class C<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::X%, self::C::Y%>
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → self::C<self::C::_#new#tearOff::X%, self::C::_#new#tearOff::Y%>
+ return new self::C::•<self::C::_#new#tearOff::X%, self::C::_#new#tearOff::Y%>();
+}
+class D<X extends core::num> extends core::Object {
+ synthetic constructor •() → self::D<self::D::X>
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff<X extends core::num>() → self::D<self::D::_#new#tearOff::X>
+ return new self::D::•<self::D::_#new#tearOff::X>();
+}
+static method main() → dynamic {
+ () → self::A f = #C1;
+ () → self::B<dynamic> g0 = #C3;
+ () → self::B<core::int> g1 = #C4;
+ <T extends core::Object? = dynamic>() → self::B<T%> g2a = #C2;
+ () → self::B<core::int> g2b = #C4;
+ <T extends core::num>() → self::B<T> g3a = #C5;
+ () → self::B<core::int> g3b = #C4;
+ () → self::C<dynamic, dynamic> h0 = #C7;
+ () → self::C<core::int, core::String> h1 = #C8;
+ <T extends core::Object? = dynamic>() → self::C<core::int, T%> h2a = #C9;
+ () → self::C<core::int, core::int> h2b = #C10;
+ <X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → self::C<X%, Y%> h3a = #C6;
+ () → self::C<core::int, core::String> h3b = #C8;
+ <T extends core::Object? = dynamic, S extends core::Object? = dynamic>() → self::C<S%, T%> h4a = #C11;
+ () → self::C<core::String, core::int> h4b = #C12;
+ <T extends core::num, S extends core::Object? = dynamic>() → self::C<T, S%> h5a = #C13;
+ () → self::C<core::int, core::String> h5b = #C8;
+ <T extends core::Object? = dynamic, S extends core::num>() → self::C<T%, S> h6a = #C14;
+ () → self::C<core::String, core::int> h6b = #C12;
+ () → self::D<core::num> i0 = #C16;
+ () → self::D<core::num> i1 = #C16;
+ <X extends core::num>() → self::D<X> i2a = #C15;
+ () → self::D<core::int> i2b = #C17;
+ <T extends core::int>() → self::D<T> i3a = #C18;
+ () → self::D<core::int> i3b = #C17;
+}
+static method _#G3#new#tearOff<T extends core::num>() → self::B<self::_#G3#new#tearOff::T>
+ return new self::B::•<self::_#G3#new#tearOff::T>();
+static method _#H2#new#tearOff<T extends core::Object? = dynamic>() → self::C<core::int, self::_#H2#new#tearOff::T%>
+ return new self::C::•<core::int, self::_#H2#new#tearOff::T%>();
+static method _#H4#new#tearOff<T extends core::Object? = dynamic, S extends core::Object? = dynamic>() → self::C<self::_#H4#new#tearOff::S%, self::_#H4#new#tearOff::T%>
+ return new self::C::•<self::_#H4#new#tearOff::S%, self::_#H4#new#tearOff::T%>();
+static method _#H5#new#tearOff<T extends core::num, S extends core::Object? = dynamic>() → self::C<self::_#H5#new#tearOff::T, self::_#H5#new#tearOff::S%>
+ return new self::C::•<self::_#H5#new#tearOff::T, self::_#H5#new#tearOff::S%>();
+static method _#H6#new#tearOff<T extends core::Object? = dynamic, S extends core::num>() → self::C<self::_#H6#new#tearOff::T%, self::_#H6#new#tearOff::S>
+ return new self::C::•<self::_#H6#new#tearOff::T%, self::_#H6#new#tearOff::S>();
+static method _#I3#new#tearOff<T extends core::int>() → self::D<self::_#I3#new#tearOff::T>
+ return new self::D::•<self::_#I3#new#tearOff::T>();
+
+constants {
+ #C1 = static-tearoff self::A::_#new#tearOff
+ #C2 = static-tearoff self::B::_#new#tearOff
+ #C3 = instantiation self::B::_#new#tearOff <dynamic>
+ #C4 = instantiation self::B::_#new#tearOff <core::int*>
+ #C5 = static-tearoff self::_#G3#new#tearOff
+ #C6 = static-tearoff self::C::_#new#tearOff
+ #C7 = instantiation self::C::_#new#tearOff <dynamic, dynamic>
+ #C8 = instantiation self::C::_#new#tearOff <core::int*, core::String*>
+ #C9 = static-tearoff self::_#H2#new#tearOff
+ #C10 = instantiation self::C::_#new#tearOff <core::int*, core::int*>
+ #C11 = static-tearoff self::_#H4#new#tearOff
+ #C12 = instantiation self::C::_#new#tearOff <core::String*, core::int*>
+ #C13 = static-tearoff self::_#H5#new#tearOff
+ #C14 = static-tearoff self::_#H6#new#tearOff
+ #C15 = static-tearoff self::D::_#new#tearOff
+ #C16 = instantiation self::D::_#new#tearOff <core::num*>
+ #C17 = instantiation self::D::_#new#tearOff <core::int*>
+ #C18 = static-tearoff self::_#I3#new#tearOff
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.weak.outline.expect
new file mode 100644
index 0000000..3dbbebd
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.weak.outline.expect
@@ -0,0 +1,58 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F = self::A;
+typedef G0 = self::B<dynamic>;
+typedef G1 = self::B<core::int>;
+typedef G2<T extends core::Object? = dynamic> = self::B<T%>;
+typedef G3<T extends core::num> = self::B<T>;
+typedef H0 = self::C<dynamic, dynamic>;
+typedef H1 = self::C<core::int, core::String>;
+typedef H2<T extends core::Object? = dynamic> = self::C<core::int, T%>;
+typedef H3<T extends core::Object? = dynamic, S extends core::Object? = dynamic> = self::C<T%, S%>;
+typedef H4<T extends core::Object? = dynamic, S extends core::Object? = dynamic> = self::C<S%, T%>;
+typedef H5<T extends core::num, S extends core::Object? = dynamic> = self::C<T, S%>;
+typedef H6<T extends core::Object? = dynamic, S extends core::num> = self::C<T%, S>;
+typedef I0 = self::D<core::num>;
+typedef I1 = self::D<core::num>;
+typedef I2<T extends core::num> = self::D<T>;
+typedef I3<T extends core::int> = self::D<T>;
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+ static method _#new#tearOff() → self::A
+ return new self::A::•();
+}
+class B<T extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::T%>
+ ;
+ static method _#new#tearOff<T extends core::Object? = dynamic>() → self::B<self::B::_#new#tearOff::T%>
+ return new self::B::•<self::B::_#new#tearOff::T%>();
+}
+class C<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::X%, self::C::Y%>
+ ;
+ static method _#new#tearOff<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → self::C<self::C::_#new#tearOff::X%, self::C::_#new#tearOff::Y%>
+ return new self::C::•<self::C::_#new#tearOff::X%, self::C::_#new#tearOff::Y%>();
+}
+class D<X extends core::num> extends core::Object {
+ synthetic constructor •() → self::D<self::D::X>
+ ;
+ static method _#new#tearOff<X extends core::num>() → self::D<self::D::_#new#tearOff::X>
+ return new self::D::•<self::D::_#new#tearOff::X>();
+}
+static method main() → dynamic
+ ;
+static method _#G3#new#tearOff<T extends core::num>() → self::B<self::_#G3#new#tearOff::T>
+ return new self::B::•<self::_#G3#new#tearOff::T>();
+static method _#H2#new#tearOff<T extends core::Object? = dynamic>() → self::C<core::int, self::_#H2#new#tearOff::T%>
+ return new self::C::•<core::int, self::_#H2#new#tearOff::T%>();
+static method _#H4#new#tearOff<T extends core::Object? = dynamic, S extends core::Object? = dynamic>() → self::C<self::_#H4#new#tearOff::S%, self::_#H4#new#tearOff::T%>
+ return new self::C::•<self::_#H4#new#tearOff::S%, self::_#H4#new#tearOff::T%>();
+static method _#H5#new#tearOff<T extends core::num, S extends core::Object? = dynamic>() → self::C<self::_#H5#new#tearOff::T, self::_#H5#new#tearOff::S%>
+ return new self::C::•<self::_#H5#new#tearOff::T, self::_#H5#new#tearOff::S%>();
+static method _#H6#new#tearOff<T extends core::Object? = dynamic, S extends core::num>() → self::C<self::_#H6#new#tearOff::T%, self::_#H6#new#tearOff::S>
+ return new self::C::•<self::_#H6#new#tearOff::T%, self::_#H6#new#tearOff::S>();
+static method _#I3#new#tearOff<T extends core::int>() → self::D<self::_#I3#new#tearOff::T>
+ return new self::D::•<self::_#I3#new#tearOff::T>();
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.weak.transformed.expect
new file mode 100644
index 0000000..2d72357
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/proper_rename.dart.weak.transformed.expect
@@ -0,0 +1,108 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef F = self::A;
+typedef G0 = self::B<dynamic>;
+typedef G1 = self::B<core::int>;
+typedef G2<T extends core::Object? = dynamic> = self::B<T%>;
+typedef G3<T extends core::num> = self::B<T>;
+typedef H0 = self::C<dynamic, dynamic>;
+typedef H1 = self::C<core::int, core::String>;
+typedef H2<T extends core::Object? = dynamic> = self::C<core::int, T%>;
+typedef H3<T extends core::Object? = dynamic, S extends core::Object? = dynamic> = self::C<T%, S%>;
+typedef H4<T extends core::Object? = dynamic, S extends core::Object? = dynamic> = self::C<S%, T%>;
+typedef H5<T extends core::num, S extends core::Object? = dynamic> = self::C<T, S%>;
+typedef H6<T extends core::Object? = dynamic, S extends core::num> = self::C<T%, S>;
+typedef I0 = self::D<core::num>;
+typedef I1 = self::D<core::num>;
+typedef I2<T extends core::num> = self::D<T>;
+typedef I3<T extends core::int> = self::D<T>;
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff() → self::A
+ return new self::A::•();
+}
+class B<T extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::T%>
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff<T extends core::Object? = dynamic>() → self::B<self::B::_#new#tearOff::T%>
+ return new self::B::•<self::B::_#new#tearOff::T%>();
+}
+class C<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::X%, self::C::Y%>
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → self::C<self::C::_#new#tearOff::X%, self::C::_#new#tearOff::Y%>
+ return new self::C::•<self::C::_#new#tearOff::X%, self::C::_#new#tearOff::Y%>();
+}
+class D<X extends core::num> extends core::Object {
+ synthetic constructor •() → self::D<self::D::X>
+ : super core::Object::•()
+ ;
+ static method _#new#tearOff<X extends core::num>() → self::D<self::D::_#new#tearOff::X>
+ return new self::D::•<self::D::_#new#tearOff::X>();
+}
+static method main() → dynamic {
+ () → self::A f = #C1;
+ () → self::B<dynamic> g0 = #C3;
+ () → self::B<core::int> g1 = #C4;
+ <T extends core::Object? = dynamic>() → self::B<T%> g2a = #C2;
+ () → self::B<core::int> g2b = #C4;
+ <T extends core::num>() → self::B<T> g3a = #C5;
+ () → self::B<core::int> g3b = #C4;
+ () → self::C<dynamic, dynamic> h0 = #C7;
+ () → self::C<core::int, core::String> h1 = #C8;
+ <T extends core::Object? = dynamic>() → self::C<core::int, T%> h2a = #C9;
+ () → self::C<core::int, core::int> h2b = #C10;
+ <X extends core::Object? = dynamic, Y extends core::Object? = dynamic>() → self::C<X%, Y%> h3a = #C6;
+ () → self::C<core::int, core::String> h3b = #C8;
+ <T extends core::Object? = dynamic, S extends core::Object? = dynamic>() → self::C<S%, T%> h4a = #C11;
+ () → self::C<core::String, core::int> h4b = #C12;
+ <T extends core::num, S extends core::Object? = dynamic>() → self::C<T, S%> h5a = #C13;
+ () → self::C<core::int, core::String> h5b = #C8;
+ <T extends core::Object? = dynamic, S extends core::num>() → self::C<T%, S> h6a = #C14;
+ () → self::C<core::String, core::int> h6b = #C12;
+ () → self::D<core::num> i0 = #C16;
+ () → self::D<core::num> i1 = #C16;
+ <X extends core::num>() → self::D<X> i2a = #C15;
+ () → self::D<core::int> i2b = #C17;
+ <T extends core::int>() → self::D<T> i3a = #C18;
+ () → self::D<core::int> i3b = #C17;
+}
+static method _#G3#new#tearOff<T extends core::num>() → self::B<self::_#G3#new#tearOff::T>
+ return new self::B::•<self::_#G3#new#tearOff::T>();
+static method _#H2#new#tearOff<T extends core::Object? = dynamic>() → self::C<core::int, self::_#H2#new#tearOff::T%>
+ return new self::C::•<core::int, self::_#H2#new#tearOff::T%>();
+static method _#H4#new#tearOff<T extends core::Object? = dynamic, S extends core::Object? = dynamic>() → self::C<self::_#H4#new#tearOff::S%, self::_#H4#new#tearOff::T%>
+ return new self::C::•<self::_#H4#new#tearOff::S%, self::_#H4#new#tearOff::T%>();
+static method _#H5#new#tearOff<T extends core::num, S extends core::Object? = dynamic>() → self::C<self::_#H5#new#tearOff::T, self::_#H5#new#tearOff::S%>
+ return new self::C::•<self::_#H5#new#tearOff::T, self::_#H5#new#tearOff::S%>();
+static method _#H6#new#tearOff<T extends core::Object? = dynamic, S extends core::num>() → self::C<self::_#H6#new#tearOff::T%, self::_#H6#new#tearOff::S>
+ return new self::C::•<self::_#H6#new#tearOff::T%, self::_#H6#new#tearOff::S>();
+static method _#I3#new#tearOff<T extends core::int>() → self::D<self::_#I3#new#tearOff::T>
+ return new self::D::•<self::_#I3#new#tearOff::T>();
+
+constants {
+ #C1 = static-tearoff self::A::_#new#tearOff
+ #C2 = static-tearoff self::B::_#new#tearOff
+ #C3 = instantiation self::B::_#new#tearOff <dynamic>
+ #C4 = instantiation self::B::_#new#tearOff <core::int*>
+ #C5 = static-tearoff self::_#G3#new#tearOff
+ #C6 = static-tearoff self::C::_#new#tearOff
+ #C7 = instantiation self::C::_#new#tearOff <dynamic, dynamic>
+ #C8 = instantiation self::C::_#new#tearOff <core::int*, core::String*>
+ #C9 = static-tearoff self::_#H2#new#tearOff
+ #C10 = instantiation self::C::_#new#tearOff <core::int*, core::int*>
+ #C11 = static-tearoff self::_#H4#new#tearOff
+ #C12 = instantiation self::C::_#new#tearOff <core::String*, core::int*>
+ #C13 = static-tearoff self::_#H5#new#tearOff
+ #C14 = static-tearoff self::_#H6#new#tearOff
+ #C15 = static-tearoff self::D::_#new#tearOff
+ #C16 = instantiation self::D::_#new#tearOff <core::num*>
+ #C17 = instantiation self::D::_#new#tearOff <core::int*>
+ #C18 = static-tearoff self::_#I3#new#tearOff
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.strong.expect
index f68f95f..848dbdd 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.strong.expect
@@ -296,18 +296,8 @@
}
throw "Expected exception";
}
-static method _#DA1#new#tearOff() → self::A
- return new self::A::•();
static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
return new self::A::•();
-static method _#DB1#_#tearOff(core::int field1, core::String field2) → self::B<core::String>
- return new self::B::_<core::String>(field1, field2);
-static method _#DB1#new#tearOff() → self::B<core::String>
- return new self::B::•<core::String>();
-static method _#DB1#foo#tearOff(core::int field1) → self::B<core::String>
- return new self::B::foo<core::String>(field1);
-static method _#DB1#bar#tearOff(core::int i, core::String j) → self::B<core::String>
- return self::B::bar<core::String>(i, j);
static method _#DB2#_#tearOff<X extends core::num>(core::int field1, core::String field2) → self::B<self::_#DB2#_#tearOff::X>
return new self::B::_<self::_#DB2#_#tearOff::X>(field1, field2);
static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.strong.transformed.expect
index f5bd2bb..7c8571b 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.strong.transformed.expect
@@ -296,18 +296,8 @@
}
throw "Expected exception";
}
-static method _#DA1#new#tearOff() → self::A
- return new self::A::•();
static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
return new self::A::•();
-static method _#DB1#_#tearOff(core::int field1, core::String field2) → self::B<core::String>
- return new self::B::_<core::String>(field1, field2);
-static method _#DB1#new#tearOff() → self::B<core::String>
- return new self::B::•<core::String>();
-static method _#DB1#foo#tearOff(core::int field1) → self::B<core::String>
- return new self::B::foo<core::String>(field1);
-static method _#DB1#bar#tearOff(core::int i, core::String j) → self::B<core::String>
- return self::B::bar<core::String>(i, j);
static method _#DB2#_#tearOff<X extends core::num>(core::int field1, core::String field2) → self::B<self::_#DB2#_#tearOff::X>
return new self::B::_<self::_#DB2#_#tearOff::X>(field1, field2);
static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.weak.expect
index d485819..f4e5e89 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.weak.expect
@@ -296,18 +296,8 @@
}
throw "Expected exception";
}
-static method _#DA1#new#tearOff() → self::A
- return new self::A::•();
static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
return new self::A::•();
-static method _#DB1#_#tearOff(core::int field1, core::String field2) → self::B<core::String>
- return new self::B::_<core::String>(field1, field2);
-static method _#DB1#new#tearOff() → self::B<core::String>
- return new self::B::•<core::String>();
-static method _#DB1#foo#tearOff(core::int field1) → self::B<core::String>
- return new self::B::foo<core::String>(field1);
-static method _#DB1#bar#tearOff(core::int i, core::String j) → self::B<core::String>
- return self::B::bar<core::String>(i, j);
static method _#DB2#_#tearOff<X extends core::num>(core::int field1, core::String field2) → self::B<self::_#DB2#_#tearOff::X>
return new self::B::_<self::_#DB2#_#tearOff::X>(field1, field2);
static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.weak.outline.expect
index a3bed2d..10537bf 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.weak.outline.expect
@@ -40,18 +40,8 @@
;
static method throws(() → dynamic f, {core::bool inSoundModeOnly}) → dynamic
;
-static method _#DA1#new#tearOff() → self::A
- return new self::A::•();
static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
return new self::A::•();
-static method _#DB1#_#tearOff(core::int field1, core::String field2) → self::B<core::String>
- return new self::B::_<core::String>(field1, field2);
-static method _#DB1#new#tearOff() → self::B<core::String>
- return new self::B::•<core::String>();
-static method _#DB1#foo#tearOff(core::int field1) → self::B<core::String>
- return new self::B::foo<core::String>(field1);
-static method _#DB1#bar#tearOff(core::int i, core::String j) → self::B<core::String>
- return self::B::bar<core::String>(i, j);
static method _#DB2#_#tearOff<X extends core::num>(core::int field1, core::String field2) → self::B<self::_#DB2#_#tearOff::X>
return new self::B::_<self::_#DB2#_#tearOff::X>(field1, field2);
static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.weak.transformed.expect
index e905181..12bd083 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/typedef_tear_off.dart.weak.transformed.expect
@@ -296,18 +296,8 @@
}
throw "Expected exception";
}
-static method _#DA1#new#tearOff() → self::A
- return new self::A::•();
static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
return new self::A::•();
-static method _#DB1#_#tearOff(core::int field1, core::String field2) → self::B<core::String>
- return new self::B::_<core::String>(field1, field2);
-static method _#DB1#new#tearOff() → self::B<core::String>
- return new self::B::•<core::String>();
-static method _#DB1#foo#tearOff(core::int field1) → self::B<core::String>
- return new self::B::foo<core::String>(field1);
-static method _#DB1#bar#tearOff(core::int i, core::String j) → self::B<core::String>
- return self::B::bar<core::String>(i, j);
static method _#DB2#_#tearOff<X extends core::num>(core::int field1, core::String field2) → self::B<self::_#DB2#_#tearOff::X>
return new self::B::_<self::_#DB2#_#tearOff::X>(field1, field2);
static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
diff --git a/tests/language/abstract/exact_selector_runtime_test.dart b/tests/language/abstract/exact_selector_runtime_test.dart
index e8fc4ec..3d8f29e 100644
--- a/tests/language/abstract/exact_selector_runtime_test.dart
+++ b/tests/language/abstract/exact_selector_runtime_test.dart
@@ -9,13 +9,13 @@
// methods to handle `noSuchMethod`.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
class Foo {
noSuchMethod(im) => 42;
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
returnFoo() {
(() => 42)();
return new Foo();
diff --git a/tests/language/abstract/exact_selector_test.dart b/tests/language/abstract/exact_selector_test.dart
index 0df1020..fc6dba8 100644
--- a/tests/language/abstract/exact_selector_test.dart
+++ b/tests/language/abstract/exact_selector_test.dart
@@ -6,13 +6,13 @@
// methods to handle `noSuchMethod`.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
abstract class Foo {
noSuchMethod(im) => 42;
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
returnFoo() {
(() => 42)();
return new Foo();
diff --git a/tests/language/compiler_annotations.dart b/tests/language/compiler_annotations.dart
deleted file mode 100644
index c920add..0000000
--- a/tests/language/compiler_annotations.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2013, 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.
-
-library compiler_annotations;
-
-// This library contains annotations useful for testing.
-
-// TODO(ngeoffray): Implement in dart2js.
-class DontInline {
- const DontInline();
-}
diff --git a/tests/language/const/map5_test.dart b/tests/language/const/map5_test.dart
new file mode 100644
index 0000000..0fbd8de
--- /dev/null
+++ b/tests/language/const/map5_test.dart
@@ -0,0 +1,47 @@
+// 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.
+
+// Tests lookup of type literals of user-defined classes in const maps.
+
+import 'package:expect/expect.dart';
+
+class A {}
+
+class C<T> {}
+
+typedef F = T Function<T>();
+typedef Cint = C<int>;
+
+const aType = A;
+const fType = F;
+const cIntType = Cint;
+
+main() {
+ final map = const {A: 42, F: 2, 'asdf': 'fdsa', Cint: 'foo'};
+ Expect.equals(42, map[getValueNonOptimized(A)]);
+ Expect.equals(42, map[getValueNonOptimized(aType)]);
+ Expect.equals(2, map[getValueNonOptimized(F)]);
+ Expect.equals(2, map[getValueNonOptimized(fType)]);
+ Expect.equals('foo', map[getValueNonOptimized(Cint)]);
+ Expect.equals('foo', map[getValueNonOptimized(cIntType)]);
+ Expect.isTrue(map.containsKey(getValueNonOptimized(A)));
+ Expect.isTrue(map.containsKey(getValueNonOptimized(aType)));
+ Expect.isTrue(map.containsKey(getValueNonOptimized(F)));
+ Expect.isTrue(map.containsKey(getValueNonOptimized(fType)));
+ Expect.isTrue(map.containsKey(getValueNonOptimized(Cint)));
+ Expect.isTrue(map.containsKey(getValueNonOptimized(cIntType)));
+}
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
+ return getValueNonOptimized(2);
+ }
+ return x;
+}
diff --git a/tests/language/const/map_hashcode_override2_test.dart b/tests/language/const/map_hashcode_override2_test.dart
index 871b14a..d2e5858 100644
--- a/tests/language/const/map_hashcode_override2_test.dart
+++ b/tests/language/const/map_hashcode_override2_test.dart
@@ -7,10 +7,13 @@
/// Returns its argument.
///
/// Prevents static optimizations and inlining.
-getValueNonOptimized(x) {
- // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
- if (DateTime.now().millisecondsSinceEpoch == 42)
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
return getValueNonOptimized(2);
+ }
return x;
}
diff --git a/tests/language/const/map_hashcode_override_test.dart b/tests/language/const/map_hashcode_override_test.dart
index a88d1a8..f8aa3cc 100644
--- a/tests/language/const/map_hashcode_override_test.dart
+++ b/tests/language/const/map_hashcode_override_test.dart
@@ -7,10 +7,13 @@
/// Returns its argument.
///
/// Prevents static optimizations and inlining.
-getValueNonOptimized(x) {
- // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
- if (DateTime.now().millisecondsSinceEpoch == 42)
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
return getValueNonOptimized(2);
+ }
return x;
}
diff --git a/tests/language/const/map_null_lookup_test.dart b/tests/language/const/map_null_lookup_test.dart
new file mode 100644
index 0000000..e493653
--- /dev/null
+++ b/tests/language/const/map_null_lookup_test.dart
@@ -0,0 +1,29 @@
+// 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.
+
+// Tests lookup of null in const maps.
+
+import 'package:expect/expect.dart';
+
+main() {
+ final map1 = const {1: 42, null: 2, 'asdf': 'fdsa'};
+ Expect.equals(2, map1[getValueNonOptimized(null)]);
+ Expect.isTrue(map1.containsKey(null));
+ final map2 = const {1: 42, 2: 2, 'asdf': 'fdsa'};
+ Expect.equals(null, map2[getValueNonOptimized(null)]);
+ Expect.isFalse(map2.containsKey(null));
+}
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
+ return getValueNonOptimized(2);
+ }
+ return x;
+}
diff --git a/tests/language/const/map_test.dart b/tests/language/const/map_test.dart
index 3658459..d1a88fe 100644
--- a/tests/language/const/map_test.dart
+++ b/tests/language/const/map_test.dart
@@ -7,10 +7,13 @@
/// Returns its argument.
///
/// Prevents static optimizations and inlining.
-getValueNonOptimized(x) {
- // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
- if (DateTime.now().millisecondsSinceEpoch == 42)
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
return getValueNonOptimized(2);
+ }
return x;
}
diff --git a/tests/language/const/set5_test.dart b/tests/language/const/set5_test.dart
new file mode 100644
index 0000000..f27b5f9
--- /dev/null
+++ b/tests/language/const/set5_test.dart
@@ -0,0 +1,47 @@
+// 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.
+
+// Tests lookup of type literals of user-defined classes in const sets.
+
+import 'package:expect/expect.dart';
+
+class A {}
+
+class C<T> {}
+
+typedef F = T Function<T>();
+typedef Cint = C<int>;
+
+const aType = A;
+const fType = F;
+const cIntType = Cint;
+
+main() {
+ final set1 = const {A, 1, 'asdf', F, Cint};
+ Expect.isTrue(set1.contains(getValueNonOptimized(A)));
+ Expect.isTrue(set1.contains(getValueNonOptimized(aType)));
+ Expect.isTrue(set1.contains(getValueNonOptimized(F)));
+ Expect.isTrue(set1.contains(getValueNonOptimized(fType)));
+ Expect.isTrue(set1.contains(getValueNonOptimized(Cint)));
+ Expect.isTrue(set1.contains(getValueNonOptimized(cIntType)));
+ Expect.equals(A, set1.lookup(getValueNonOptimized(A)));
+ Expect.equals(A, set1.lookup(getValueNonOptimized(aType)));
+ Expect.equals(F, set1.lookup(getValueNonOptimized(F)));
+ Expect.equals(F, set1.lookup(getValueNonOptimized(fType)));
+ Expect.equals(Cint, set1.lookup(getValueNonOptimized(Cint)));
+ Expect.equals(Cint, set1.lookup(getValueNonOptimized(cIntType)));
+}
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
+ return getValueNonOptimized(2);
+ }
+ return x;
+}
diff --git a/tests/language/const/set_hashcode_override2_test.dart b/tests/language/const/set_hashcode_override2_test.dart
index 0775822..cbe8944 100644
--- a/tests/language/const/set_hashcode_override2_test.dart
+++ b/tests/language/const/set_hashcode_override2_test.dart
@@ -7,10 +7,13 @@
/// Returns its argument.
///
/// Prevents static optimizations and inlining.
-getValueNonOptimized(x) {
- // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
- if (DateTime.now().millisecondsSinceEpoch == 42)
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
return getValueNonOptimized(2);
+ }
return x;
}
diff --git a/tests/language/const/set_null_lookup_test.dart b/tests/language/const/set_null_lookup_test.dart
new file mode 100644
index 0000000..a2b4044
--- /dev/null
+++ b/tests/language/const/set_null_lookup_test.dart
@@ -0,0 +1,29 @@
+// 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.
+
+// Tests lookup of null in const maps.
+
+import 'package:expect/expect.dart';
+
+main() {
+ final set1 = const {null, 1, 'asdf'};
+ Expect.isTrue(set1.contains(getValueNonOptimized(null)));
+ Expect.equals(null, set1.lookup(null));
+ final set2 = const {42, 1, 'asdf'};
+ Expect.isFalse(set2.contains(getValueNonOptimized(null)));
+ Expect.equals(null, set2.lookup(null));
+}
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
+ return getValueNonOptimized(2);
+ }
+ return x;
+}
diff --git a/tests/language/constructor/multiple_field_assignment_constructor_test.dart b/tests/language/constructor/multiple_field_assignment_constructor_test.dart
index 7292e80..c499161 100644
--- a/tests/language/constructor/multiple_field_assignment_constructor_test.dart
+++ b/tests/language/constructor/multiple_field_assignment_constructor_test.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
var a = [null];
@@ -11,7 +10,8 @@
var foo;
var bar;
- @DontInline()
+ @pragma('vm:never-inline')
+ @pragma('dart2js:noInline')
A() {
// Currently defeat inlining by using a closure.
bar = () => 42;
@@ -24,7 +24,8 @@
var foo;
var bar;
- @DontInline()
+ @pragma('vm:never-inline')
+ @pragma('dart2js:noInline')
B() {
// Currently defeat inlining by using a closure.
bar = () => 42;
@@ -44,7 +45,8 @@
new B();
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
bar() {
// Currently defeat inlining by using a closure.
Expect.throwsNoSuchMethodError(() => new A().foo + 42);
diff --git a/tests/language/optimize/inferrer_constructor2_test.dart b/tests/language/optimize/inferrer_constructor2_test.dart
index 58da3ad..4d28519 100644
--- a/tests/language/optimize/inferrer_constructor2_test.dart
+++ b/tests/language/optimize/inferrer_constructor2_test.dart
@@ -7,13 +7,13 @@
// inlined.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
class A {
var foo;
var bar;
- @DontInline()
+ @pragma('vm:never-inline')
+ @pragma('dart2js:noInline')
A() {
// Currently defeat inlining by using a closure.
bar = () => 42;
@@ -33,7 +33,8 @@
class B {
var bar;
var closure;
- @DontInline()
+ @pragma('vm:never-inline')
+ @pragma('dart2js:noInline')
B() {
// Currently defeat inlining by using a closure.
closure = () => 42;
@@ -41,7 +42,8 @@
}
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
bar() {
// Make sure B's constructor is analyzed first by surrounding the
// body by two allocations.
@@ -52,7 +54,8 @@
new B();
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
codegenLast() {
// This assignment currently defeats simple type inference, but not
// the optimistic inferrer.
diff --git a/tests/language/optimize/inferrer_constructor3_test.dart b/tests/language/optimize/inferrer_constructor3_test.dart
index 395f113..a3e9038 100644
--- a/tests/language/optimize/inferrer_constructor3_test.dart
+++ b/tests/language/optimize/inferrer_constructor3_test.dart
@@ -7,7 +7,6 @@
// inlined.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
class A {
var field;
@@ -24,14 +23,16 @@
bar();
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
doIt() {
() => 42;
var c = new A(null);
Expect.throwsNoSuchMethodError(() => c.field + 42);
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
bar() {
() => 42;
return inlineLevel1();
diff --git a/tests/language/optimize/inferrer_named_parameter_test.dart b/tests/language/optimize/inferrer_named_parameter_test.dart
index a6655b4..c06fc38 100644
--- a/tests/language/optimize/inferrer_named_parameter_test.dart
+++ b/tests/language/optimize/inferrer_named_parameter_test.dart
@@ -6,9 +6,9 @@
// correctly infer optional named parameters.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
foo({path}) {
() => 42;
return path;
diff --git a/tests/language/optimize/inferrer_synthesized_super_constructor_test.dart b/tests/language/optimize/inferrer_synthesized_super_constructor_test.dart
index 1a7284b..dc81959 100644
--- a/tests/language/optimize/inferrer_synthesized_super_constructor_test.dart
+++ b/tests/language/optimize/inferrer_synthesized_super_constructor_test.dart
@@ -2,10 +2,9 @@
// 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 '../compiler_annotations.dart';
-
class A {
- @DontInline()
+ @pragma('vm:never-inline')
+ @pragma('dart2js:noInline')
A([a]) {
() => 42;
if (a != null) throw 'Test failed';
diff --git a/tests/language/regress/regress12284_test.dart b/tests/language/regress/regress12284_test.dart
index 4164c44..aeaf366 100644
--- a/tests/language/regress/regress12284_test.dart
+++ b/tests/language/regress/regress12284_test.dart
@@ -3,12 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
class A {
int field = -1;
- @DontInline()
+ @pragma('vm:never-inline')
+ @pragma('dart2js:noInline')
A(param) {
// Currently defeat inlining by using a closure.
var bar = () => 42;
diff --git a/tests/language/regress/regress12336_test.dart b/tests/language/regress/regress12336_test.dart
index 029c3f1..7630c49 100644
--- a/tests/language/regress/regress12336_test.dart
+++ b/tests/language/regress/regress12336_test.dart
@@ -6,7 +6,6 @@
// [foo].
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
main() {
var result = foo(1, 2);
@@ -18,7 +17,8 @@
Expect.listEquals([], result[1]);
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
foo(a, b) {
() => 42;
if (a is List) {
diff --git a/tests/language/string/optimizations_test.dart b/tests/language/string/optimizations_test.dart
index a40bc0b..b595437 100644
--- a/tests/language/string/optimizations_test.dart
+++ b/tests/language/string/optimizations_test.dart
@@ -6,15 +6,16 @@
// correctly infer optional named parameters.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
foo({path}) {
() => 42;
return path.toString();
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
bar({path}) {
() => 42;
return path;
diff --git a/tests/language/unsorted/refine_receiver_null_test.dart b/tests/language/unsorted/refine_receiver_null_test.dart
index 499e998..50a5fa7 100644
--- a/tests/language/unsorted/refine_receiver_null_test.dart
+++ b/tests/language/unsorted/refine_receiver_null_test.dart
@@ -7,7 +7,6 @@
// work for Object methods.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
main() {
var a = true ? null : 42;
@@ -15,7 +14,8 @@
foo(a);
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
foo(a) {
var f = () => 42;
Expect.throwsNoSuchMethodError(() => a + 42);
diff --git a/tests/language_2/abstract/exact_selector_runtime_test.dart b/tests/language_2/abstract/exact_selector_runtime_test.dart
index 2d18f98..eb8d0c8 100644
--- a/tests/language_2/abstract/exact_selector_runtime_test.dart
+++ b/tests/language_2/abstract/exact_selector_runtime_test.dart
@@ -11,14 +11,13 @@
// methods to handle `noSuchMethod`.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
-
- class Foo {
+class Foo {
noSuchMethod(im) => 42;
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
returnFoo() {
(() => 42)();
return new Foo();
diff --git a/tests/language_2/abstract/exact_selector_test.dart b/tests/language_2/abstract/exact_selector_test.dart
index 23a69e0..dff88cb 100644
--- a/tests/language_2/abstract/exact_selector_test.dart
+++ b/tests/language_2/abstract/exact_selector_test.dart
@@ -8,14 +8,13 @@
// methods to handle `noSuchMethod`.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
-abstract
- class Foo {
+abstract class Foo {
noSuchMethod(im) => 42;
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
returnFoo() {
(() => 42)();
return new Foo();
diff --git a/tests/language_2/compiler_annotations.dart b/tests/language_2/compiler_annotations.dart
deleted file mode 100644
index 9264514..0000000
--- a/tests/language_2/compiler_annotations.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2013, 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.
-
-// @dart = 2.9
-
-library compiler_annotations;
-
-// This library contains annotations useful for testing.
-
-// TODO(ngeoffray): Implement in dart2js.
-class DontInline {
- const DontInline();
-}
diff --git a/tests/language_2/const/map5_test.dart b/tests/language_2/const/map5_test.dart
new file mode 100644
index 0000000..4827e54
--- /dev/null
+++ b/tests/language_2/const/map5_test.dart
@@ -0,0 +1,43 @@
+// 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.
+
+// Tests lookup of type literals of user-defined classes in const maps.
+
+// @dart = 2.9
+
+import 'package:expect/expect.dart';
+
+class A {}
+
+class C<T> {}
+
+typedef F = T Function<T>();
+
+const aType = A;
+const fType = F;
+
+main() {
+ final map = const {A: 42, F: 2, 'asdf': 'fdsa'};
+ Expect.equals(42, map[getValueNonOptimized(A)]);
+ Expect.equals(42, map[getValueNonOptimized(aType)]);
+ Expect.equals(2, map[getValueNonOptimized(F)]);
+ Expect.equals(2, map[getValueNonOptimized(fType)]);
+ Expect.isTrue(map.containsKey(getValueNonOptimized(A)));
+ Expect.isTrue(map.containsKey(getValueNonOptimized(aType)));
+ Expect.isTrue(map.containsKey(getValueNonOptimized(F)));
+ Expect.isTrue(map.containsKey(getValueNonOptimized(fType)));
+}
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
+ return getValueNonOptimized(2);
+ }
+ return x;
+}
diff --git a/tests/language_2/const/map_hashcode_override2_test.dart b/tests/language_2/const/map_hashcode_override2_test.dart
index 26ffaf6..a5add26 100644
--- a/tests/language_2/const/map_hashcode_override2_test.dart
+++ b/tests/language_2/const/map_hashcode_override2_test.dart
@@ -9,10 +9,13 @@
/// Returns its argument.
///
/// Prevents static optimizations and inlining.
-getValueNonOptimized(x) {
- // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
- if (DateTime.now().millisecondsSinceEpoch == 42)
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
return getValueNonOptimized(2);
+ }
return x;
}
diff --git a/tests/language_2/const/map_hashcode_override_test.dart b/tests/language_2/const/map_hashcode_override_test.dart
index c297c54..a696d36 100644
--- a/tests/language_2/const/map_hashcode_override_test.dart
+++ b/tests/language_2/const/map_hashcode_override_test.dart
@@ -9,10 +9,13 @@
/// Returns its argument.
///
/// Prevents static optimizations and inlining.
-getValueNonOptimized(x) {
- // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
- if (DateTime.now().millisecondsSinceEpoch == 42)
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
return getValueNonOptimized(2);
+ }
return x;
}
diff --git a/tests/language_2/const/map_null_lookup_test.dart b/tests/language_2/const/map_null_lookup_test.dart
new file mode 100644
index 0000000..612f3ca
--- /dev/null
+++ b/tests/language_2/const/map_null_lookup_test.dart
@@ -0,0 +1,31 @@
+// 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.
+
+// Tests lookup of null in const maps.
+
+// @dart = 2.9
+
+import 'package:expect/expect.dart';
+
+main() {
+ final map1 = const {1: 42, null: 2, 'asdf': 'fdsa'};
+ Expect.equals(2, map1[getValueNonOptimized(null)]);
+ Expect.isTrue(map1.containsKey(null));
+ final map2 = const {1: 42, 2: 2, 'asdf': 'fdsa'};
+ Expect.equals(null, map2[getValueNonOptimized(null)]);
+ Expect.isFalse(map2.containsKey(null));
+}
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
+ return getValueNonOptimized(2);
+ }
+ return x;
+}
diff --git a/tests/language_2/const/map_test.dart b/tests/language_2/const/map_test.dart
index 543596a..3ffcf7a 100644
--- a/tests/language_2/const/map_test.dart
+++ b/tests/language_2/const/map_test.dart
@@ -9,10 +9,13 @@
/// Returns its argument.
///
/// Prevents static optimizations and inlining.
-getValueNonOptimized(x) {
- // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
- if (DateTime.now().millisecondsSinceEpoch == 42)
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
return getValueNonOptimized(2);
+ }
return x;
}
diff --git a/tests/language_2/const/set5_test.dart b/tests/language_2/const/set5_test.dart
new file mode 100644
index 0000000..dc0088d
--- /dev/null
+++ b/tests/language_2/const/set5_test.dart
@@ -0,0 +1,43 @@
+// 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.
+
+// Tests lookup of type literals of user-defined classes in const sets.
+
+// @dart = 2.9
+
+import 'package:expect/expect.dart';
+
+class A {}
+
+class C<T> {}
+
+typedef F = T Function<T>();
+
+const aType = A;
+const fType = F;
+
+main() {
+ final set1 = const {A, 1, 'asdf', F};
+ Expect.isTrue(set1.contains(getValueNonOptimized(A)));
+ Expect.isTrue(set1.contains(getValueNonOptimized(aType)));
+ Expect.isTrue(set1.contains(getValueNonOptimized(F)));
+ Expect.isTrue(set1.contains(getValueNonOptimized(fType)));
+ Expect.equals(A, set1.lookup(getValueNonOptimized(A)));
+ Expect.equals(A, set1.lookup(getValueNonOptimized(aType)));
+ Expect.equals(F, set1.lookup(getValueNonOptimized(F)));
+ Expect.equals(F, set1.lookup(getValueNonOptimized(fType)));
+}
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
+ return getValueNonOptimized(2);
+ }
+ return x;
+}
diff --git a/tests/language_2/const/set_hashcode_override2_test.dart b/tests/language_2/const/set_hashcode_override2_test.dart
index d14e8e2..0be2136 100644
--- a/tests/language_2/const/set_hashcode_override2_test.dart
+++ b/tests/language_2/const/set_hashcode_override2_test.dart
@@ -9,10 +9,13 @@
/// Returns its argument.
///
/// Prevents static optimizations and inlining.
-getValueNonOptimized(x) {
- // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
- if (DateTime.now().millisecondsSinceEpoch == 42)
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
return getValueNonOptimized(2);
+ }
return x;
}
diff --git a/tests/language_2/const/set_null_lookup_test.dart b/tests/language_2/const/set_null_lookup_test.dart
new file mode 100644
index 0000000..1e7a09a
--- /dev/null
+++ b/tests/language_2/const/set_null_lookup_test.dart
@@ -0,0 +1,31 @@
+// 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.
+
+// Tests lookup of null in const sets.
+
+// @dart = 2.9
+
+import 'package:expect/expect.dart';
+
+main() {
+ final set1 = const {null, 1, 'asdf'};
+ Expect.isTrue(set1.contains(getValueNonOptimized(null)));
+ Expect.equals(null, set1.lookup(null));
+ final set2 = const {42, 1, 'asdf'};
+ Expect.isFalse(set2.contains(getValueNonOptimized(null)));
+ Expect.equals(null, set2.lookup(null));
+}
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
+dynamic getValueNonOptimized(dynamic x) {
+ // DateTime.now() cannot be predicted statically, never equal to 42.
+ if (DateTime.now().millisecondsSinceEpoch == 42) {
+ return getValueNonOptimized(2);
+ }
+ return x;
+}
diff --git a/tests/language_2/constructor/multiple_field_assignment_constructor_test.dart b/tests/language_2/constructor/multiple_field_assignment_constructor_test.dart
index 48ee8b9..6e76204 100644
--- a/tests/language_2/constructor/multiple_field_assignment_constructor_test.dart
+++ b/tests/language_2/constructor/multiple_field_assignment_constructor_test.dart
@@ -5,7 +5,6 @@
// @dart = 2.9
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
var a = [null];
@@ -13,7 +12,8 @@
var foo;
var bar;
- @DontInline()
+ @pragma('vm:never-inline')
+ @pragma('dart2js:noInline')
A() {
// Currently defeat inlining by using a closure.
bar = () => 42;
@@ -26,7 +26,8 @@
var foo;
var bar;
- @DontInline()
+ @pragma('vm:never-inline')
+ @pragma('dart2js:noInline')
B() {
// Currently defeat inlining by using a closure.
bar = () => 42;
@@ -46,7 +47,8 @@
new B();
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
bar() {
// Currently defeat inlining by using a closure.
Expect.throwsNoSuchMethodError(() => new A().foo + 42);
diff --git a/tests/language_2/optimize/inferrer_constructor2_test.dart b/tests/language_2/optimize/inferrer_constructor2_test.dart
index 3b8d026..3db6e22 100644
--- a/tests/language_2/optimize/inferrer_constructor2_test.dart
+++ b/tests/language_2/optimize/inferrer_constructor2_test.dart
@@ -9,13 +9,13 @@
// inlined.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
class A {
var foo;
var bar;
- @DontInline()
+ @pragma('vm:never-inline')
+ @pragma('dart2js:noInline')
A() {
// Currently defeat inlining by using a closure.
bar = () => 42;
@@ -35,7 +35,8 @@
class B {
var bar;
var closure;
- @DontInline()
+ @pragma('vm:never-inline')
+ @pragma('dart2js:noInline')
B() {
// Currently defeat inlining by using a closure.
closure = () => 42;
@@ -43,7 +44,8 @@
}
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
bar() {
// Make sure B's constructor is analyzed first by surrounding the
// body by two allocations.
@@ -54,7 +56,8 @@
new B();
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
codegenLast() {
// This assignment currently defeats simple type inference, but not
// the optimistic inferrer.
diff --git a/tests/language_2/optimize/inferrer_constructor3_test.dart b/tests/language_2/optimize/inferrer_constructor3_test.dart
index ab89c9d..91c5e8e 100644
--- a/tests/language_2/optimize/inferrer_constructor3_test.dart
+++ b/tests/language_2/optimize/inferrer_constructor3_test.dart
@@ -9,7 +9,6 @@
// inlined.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
class A {
var field;
@@ -26,14 +25,16 @@
bar();
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
doIt() {
() => 42;
var c = new A(null);
Expect.throwsNoSuchMethodError(() => c.field + 42);
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
bar() {
() => 42;
return inlineLevel1();
diff --git a/tests/language_2/optimize/inferrer_named_parameter_test.dart b/tests/language_2/optimize/inferrer_named_parameter_test.dart
index a2edd32..fd95b33 100644
--- a/tests/language_2/optimize/inferrer_named_parameter_test.dart
+++ b/tests/language_2/optimize/inferrer_named_parameter_test.dart
@@ -8,9 +8,9 @@
// correctly infer optional named parameters.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
foo({path}) {
() => 42;
return path;
diff --git a/tests/language_2/optimize/inferrer_synthesized_super_constructor_test.dart b/tests/language_2/optimize/inferrer_synthesized_super_constructor_test.dart
index 07db1d2..8b686ae 100644
--- a/tests/language_2/optimize/inferrer_synthesized_super_constructor_test.dart
+++ b/tests/language_2/optimize/inferrer_synthesized_super_constructor_test.dart
@@ -4,10 +4,9 @@
// @dart = 2.9
-import '../compiler_annotations.dart';
-
class A {
- @DontInline()
+ @pragma('vm:never-inline')
+ @pragma('dart2js:noInline')
A([a]) {
() => 42;
if (a != null) throw 'Test failed';
diff --git a/tests/language_2/regress/regress12284_test.dart b/tests/language_2/regress/regress12284_test.dart
index 25a91f1..4c5b0bb 100644
--- a/tests/language_2/regress/regress12284_test.dart
+++ b/tests/language_2/regress/regress12284_test.dart
@@ -5,12 +5,12 @@
// @dart = 2.9
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
class A {
int field;
- @DontInline()
+ @pragma('vm:never-inline')
+ @pragma('dart2js:noInline')
A(param) {
// Currently defeat inlining by using a closure.
var bar = () => 42;
diff --git a/tests/language_2/regress/regress12336_test.dart b/tests/language_2/regress/regress12336_test.dart
index 9c62ae0..df72870 100644
--- a/tests/language_2/regress/regress12336_test.dart
+++ b/tests/language_2/regress/regress12336_test.dart
@@ -8,7 +8,6 @@
// [foo].
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
main() {
var result = foo(1, 2);
@@ -20,7 +19,8 @@
Expect.listEquals([], result[1]);
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
foo(a, b) {
() => 42;
if (a is List) {
diff --git a/tests/language_2/string/optimizations_test.dart b/tests/language_2/string/optimizations_test.dart
index 7b8ea64..5c2bb9de 100644
--- a/tests/language_2/string/optimizations_test.dart
+++ b/tests/language_2/string/optimizations_test.dart
@@ -8,15 +8,16 @@
// correctly infer optional named parameters.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
foo({path}) {
() => 42;
return path.toString();
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
bar({path}) {
() => 42;
return path;
diff --git a/tests/language_2/unsorted/refine_receiver_null_test.dart b/tests/language_2/unsorted/refine_receiver_null_test.dart
index 46df819..df580ba 100644
--- a/tests/language_2/unsorted/refine_receiver_null_test.dart
+++ b/tests/language_2/unsorted/refine_receiver_null_test.dart
@@ -9,7 +9,6 @@
// work for Object methods.
import "package:expect/expect.dart";
-import "../compiler_annotations.dart";
main() {
var a = true ? null : 42;
@@ -17,7 +16,8 @@
foo(a);
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
foo(a) {
var f = () => 42;
Expect.throwsNoSuchMethodError(() => a + 42);
diff --git a/tests/web/inferrer_is_int_test.dart b/tests/web/inferrer_is_int_test.dart
index f544578..59813ff 100644
--- a/tests/web/inferrer_is_int_test.dart
+++ b/tests/web/inferrer_is_int_test.dart
@@ -6,16 +6,17 @@
// literal might become an int at runtime.
import "package:expect/expect.dart";
-import '../language/compiler_annotations.dart';
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
callWithStringAndDouble(value) {
() => 42;
if (value is! int) throw new ArgumentError(value);
return 42;
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
callWithDouble(value) {
() => 42;
if (value is! int) throw new ArgumentError(value);
diff --git a/tests/web_2/inferrer_is_int_test.dart b/tests/web_2/inferrer_is_int_test.dart
index 4aa7717..0f58deb 100644
--- a/tests/web_2/inferrer_is_int_test.dart
+++ b/tests/web_2/inferrer_is_int_test.dart
@@ -8,16 +8,17 @@
// literal might become an int at runtime.
import "package:expect/expect.dart";
-import '../language_2/compiler_annotations.dart';
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
callWithStringAndDouble(value) {
() => 42;
if (value is! int) throw new ArgumentError(value);
return 42;
}
-@DontInline()
+@pragma('vm:never-inline')
+@pragma('dart2js:noInline')
callWithDouble(value) {
() => 42;
if (value is! int) throw new ArgumentError(value);
diff --git a/tools/VERSION b/tools/VERSION
index e6e0d78..ce0eb0e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 352
+PRERELEASE 353
PRERELEASE_PATCH 0
\ No newline at end of file