Version 2.14.0-290.0.dev

Merge commit '6facd6dfdafa2953e8523348220d3129ea884678' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index 1229ded..289ec96 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -12,6 +12,15 @@
 part of _fe_analyzer_shared.messages.codes;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeAbstractClassConstructorTearOff =
+    messageAbstractClassConstructorTearOff;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageAbstractClassConstructorTearOff = const MessageCode(
+    "AbstractClassConstructorTearOff",
+    message: r"""Constructors on abstract classes can't be torn off.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String name)>
     templateAbstractClassInstantiation =
     const Template<Message Function(String name)>(
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index f939fe1..dc97091 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -108,6 +108,9 @@
   bool get supportsNewMethodInvocationEncoding => true;
 
   @override
+  int get enabledConstructorTearOffLowerings => ConstructorTearOffLowering.none;
+
+  @override
   List<String> get extraRequiredLibraries => _requiredLibraries[name];
 
   @override
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 627f50a..b6020ee 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -53,6 +53,9 @@
   bool get supportsNewMethodInvocationEncoding => true;
 
   @override
+  int get enabledConstructorTearOffLowerings => ConstructorTearOffLowering.none;
+
+  @override
   String get name => 'dartdevc';
 
   @override
diff --git a/pkg/front_end/lib/src/base/command_line_options.dart b/pkg/front_end/lib/src/base/command_line_options.dart
index 4d8ef80..3babd76 100644
--- a/pkg/front_end/lib/src/base/command_line_options.dart
+++ b/pkg/front_end/lib/src/base/command_line_options.dart
@@ -15,6 +15,8 @@
       "--force-static-field-lowering";
   static const String forceNoExplicitGetterCalls =
       "--force-no-explicit-getter-calls";
+  static const String forceConstructorTearOffLowering =
+      "--force-constructor-tear-off-lowering";
 
   static const String target = "--target";
 
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index 0f577ff..09a4810 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -408,7 +408,8 @@
         name.startsWith("_")) {
       return null;
     }
-    MemberBuilder? declaration = constructors.lookup(name, charOffset, uri);
+    MemberBuilder? declaration =
+        constructors.lookup(name == 'new' ? '' : name, charOffset, uri);
     if (declaration == null && isPatch) {
       return origin.findConstructorOrFactory(
           name, charOffset, uri, accessingLibrary);
diff --git a/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart b/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
index 86e0021..d659697 100644
--- a/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
@@ -13,9 +13,9 @@
 
 import '../kernel/body_builder.dart' show BodyBuilder;
 import '../kernel/class_hierarchy_builder.dart' show ClassMember;
+import '../kernel/constructor_tearoff_lowering.dart';
 import '../kernel/expression_generator_helper.dart'
     show ExpressionGeneratorHelper;
-
 import '../kernel/kernel_builder.dart'
     show isRedirectingGenerativeConstructorImplementation;
 import '../kernel/kernel_target.dart' show ClonedFunctionNode;
@@ -92,6 +92,7 @@
 class ConstructorBuilderImpl extends FunctionBuilderImpl
     implements ConstructorBuilder {
   final Constructor _constructor;
+  final Procedure? _constructorTearOff;
 
   Set<FieldBuilder>? _initializedFields;
 
@@ -125,7 +126,8 @@
       this.charOpenParenOffset,
       int charEndOffset,
       Member? referenceFrom,
-      [String? nativeMethodName])
+      {String? nativeMethodName,
+      required bool forAbstractClassOrEnum})
       : _constructor = new Constructor(new FunctionNode(null),
             name: new Name(name, compilationUnit.library),
             fileUri: compilationUnit.fileUri,
@@ -134,11 +136,16 @@
           ..fileOffset = charOffset
           ..fileEndOffset = charEndOffset
           ..isNonNullableByDefault = compilationUnit.isNonNullableByDefault,
+        _constructorTearOff = createConstructorTearOffProcedure(
+            name, compilationUnit, charOffset,
+            forAbstractClassOrEnum: forAbstractClassOrEnum),
         super(metadata, modifiers, returnType, name, typeVariables, formals,
             compilationUnit, charOffset, nativeMethodName);
 
+  SourceLibraryBuilder get library => super.library as SourceLibraryBuilder;
+
   @override
-  Member? get readTarget => null;
+  Member? get readTarget => _constructorTearOff ?? _constructor;
 
   @override
   Member? get writeTarget => null;
@@ -183,6 +190,9 @@
       SourceLibraryBuilder library, void Function(Member, BuiltMemberKind) f) {
     Member member = build(library);
     f(member, BuiltMemberKind.Constructor);
+    if (_constructorTearOff != null) {
+      f(_constructorTearOff!, BuiltMemberKind.Method);
+    }
   }
 
   bool _hasBeenBuilt = false;
@@ -197,6 +207,12 @@
       _constructor.isConst = isConst;
       _constructor.isExternal = isExternal;
       updatePrivateMemberName(_constructor, libraryBuilder);
+
+      if (_constructorTearOff != null) {
+        buildConstructorTearOffProcedure(_constructorTearOff!, _constructor,
+            classBuilder!.cls, libraryBuilder);
+      }
+
       _hasBeenBuilt = true;
     }
     if (formals != null) {
@@ -247,6 +263,10 @@
       bodyBuilder.parseInitializers(beginInitializers!);
       bodyBuilder.resolveRedirectingFactoryTargets();
     }
+    if (_constructorTearOff != null) {
+      buildConstructorTearOffOutline(
+          _constructorTearOff!, constructor, classBuilder!.cls);
+    }
     beginInitializers = null;
   }
 
@@ -355,6 +375,21 @@
   }
 
   @override
+  VariableDeclaration? getTearOffParameter(int index) {
+    if (_constructorTearOff != null) {
+      if (index < _constructorTearOff!.function.positionalParameters.length) {
+        return _constructorTearOff!.function.positionalParameters[index];
+      } else {
+        index -= _constructorTearOff!.function.positionalParameters.length;
+        if (index < _constructorTearOff!.function.namedParameters.length) {
+          return _constructorTearOff!.function.namedParameters[index];
+        }
+      }
+    }
+    return null;
+  }
+
+  @override
   int finishPatch() {
     if (!isPatch) return 0;
 
@@ -435,13 +470,14 @@
   MemberBuilderImpl? _origin;
   ClonedFunctionNode? _clonedFunctionNode;
 
-  SyntheticConstructorBuilder(
-      SourceClassBuilder parent, Constructor constructor,
+  SyntheticConstructorBuilder(SourceClassBuilder parent,
+      Constructor constructor, Procedure? constructorTearOff,
       {MemberBuilderImpl? origin, ClonedFunctionNode? clonedFunctionNode})
       : _origin = origin,
         _clonedFunctionNode = clonedFunctionNode,
-        super(constructor, parent);
+        super(constructor, constructorTearOff, parent);
 
+  @override
   void buildOutlineExpressions(
       SourceLibraryBuilder libraryBuilder,
       CoreTypes coreTypes,
diff --git a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart b/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
index 9d294ec..8947531 100644
--- a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
@@ -288,7 +288,8 @@
         charOffset,
         charOffset,
         charEndOffset,
-        constructorReference);
+        constructorReference,
+        forAbstractClassOrEnum: true);
     constructors[""] = constructorBuilder;
     FieldBuilder valuesBuilder = new SourceFieldBuilder(
         /* metadata = */ null,
diff --git a/pkg/front_end/lib/src/fasta/builder/function_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
index 1fee4be..dd4d74a 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
@@ -110,13 +110,13 @@
   /// this parameter on extension instance members.
   VariableDeclaration getFormalParameter(int index);
 
-  /// If this is an extension instance method, the tear off closure parameter
-  /// corresponding to the [index]th parameter on the instance method is
-  /// returned.
+  /// If this is an extension instance method or constructor with lowering
+  /// enabled, the tear off parameter corresponding to the [index]th parameter
+  /// on the instance method or constructor is returned.
   ///
   /// This is used to update the default value for the closure parameter when
   /// it has been computed for the original parameter.
-  VariableDeclaration? getExtensionTearOffParameter(int index);
+  VariableDeclaration? getTearOffParameter(int index);
 
   /// Returns the parameter for 'this' synthetically added to extension
   /// instance members.
@@ -474,7 +474,7 @@
   }
 
   @override
-  VariableDeclaration? getExtensionTearOffParameter(int index) => null;
+  VariableDeclaration? getTearOffParameter(int index) => null;
 
   @override
   VariableDeclaration? get extensionThis {
diff --git a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
index a6c464e..e47840f 100644
--- a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
@@ -580,7 +580,7 @@
   Procedure? get extensionTearOff => _extensionTearOff;
 
   @override
-  VariableDeclaration? getExtensionTearOffParameter(int index) {
+  VariableDeclaration? getTearOffParameter(int index) {
     return _extensionTearOffParameterMap?[getFormalParameter(index)];
   }
 
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
index 1918210..fe9e63c 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
@@ -98,7 +98,8 @@
           break;
       }
     } else if (member is Constructor) {
-      DillConstructorBuilder builder = new DillConstructorBuilder(member, this);
+      DillConstructorBuilder builder =
+          new DillConstructorBuilder(member, null, this);
       String name = member.name.text;
       constructorScopeBuilder.addMember(name, builder);
     } else {
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart
index 37dd939..d076161 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart
@@ -205,15 +205,17 @@
 
 class DillConstructorBuilder extends DillMemberBuilder {
   final Constructor constructor;
+  final Procedure? _constructorTearOff;
 
-  DillConstructorBuilder(this.constructor, Builder parent)
+  DillConstructorBuilder(
+      this.constructor, this._constructorTearOff, Builder parent)
       : super(constructor, parent);
 
   @override
   Constructor get member => constructor;
 
   @override
-  Member? get readTarget => null;
+  Member? get readTarget => _constructorTearOff ?? constructor;
 
   @override
   Member? get writeTarget => null;
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 2c4b9da..4656d20 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -998,15 +998,15 @@
                 libraryBuilder.library);
           }
 
-          VariableDeclaration? extensionTearOffParameter =
-              builder.getExtensionTearOffParameter(i);
-          if (extensionTearOffParameter != null) {
+          VariableDeclaration? tearOffParameter =
+              builder.getTearOffParameter(i);
+          if (tearOffParameter != null) {
             cloner ??= new CloneVisitorNotMembers();
             Expression tearOffInitializer = cloner!.clone(initializer!);
-            extensionTearOffParameter.initializer = tearOffInitializer
-              ..parent = extensionTearOffParameter;
+            tearOffParameter.initializer = tearOffInitializer
+              ..parent = tearOffParameter;
             libraryBuilder.loader.transformPostInference(
-                extensionTearOffParameter,
+                tearOffParameter,
                 transformSetLiterals,
                 transformCollections,
                 libraryBuilder.library);
@@ -6680,13 +6680,15 @@
 
   @override
   void handleNewAsIdentifier(Token token) {
-    // TODO(johnniwinther, paulberry): disable this error when the
-    // "constructor-tearoffs" feature is enabled.
-    addProblem(
-        templateExperimentNotEnabled.withArguments('constructor-tearoffs',
-            libraryBuilder.enableConstructorTearOffsVersionInLibrary.toText()),
-        token.charOffset,
-        token.length);
+    if (!libraryBuilder.enableConstructorTearOffsInLibrary) {
+      addProblem(
+          templateExperimentNotEnabled.withArguments(
+              'constructor-tearoffs',
+              libraryBuilder.enableConstructorTearOffsVersionInLibrary
+                  .toText()),
+          token.charOffset,
+          token.length);
+    }
   }
 }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart b/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
new file mode 100644
index 0000000..33aa5d1
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
@@ -0,0 +1,166 @@
+// 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 'package:front_end/src/fasta/kernel/kernel_api.dart';
+import 'package:kernel/ast.dart';
+import 'package:kernel/type_algebra.dart';
+import '../builder/member_builder.dart';
+import '../source/source_library_builder.dart';
+
+/// Creates the synthesized name to use for the lowering of a generative
+/// constructor by the given [constructorName] in [library].
+Name constructorTearOffName(String constructorName, Library library) {
+  return new Name(
+      '_#${constructorName.isEmpty ? 'new' : constructorName}#tearOff',
+      library);
+}
+
+/// Creates the [Procedure] for the lowering of a generative constructor of
+/// the given [name] in [compilationUnit].
+///
+/// If constructor tear off lowering is not enabled, `null` is returned.
+Procedure? createConstructorTearOffProcedure(
+    String name, SourceLibraryBuilder compilationUnit, int fileOffset,
+    {required bool forAbstractClassOrEnum}) {
+  if (!forAbstractClassOrEnum &&
+      compilationUnit
+          .loader.target.backendTarget.isConstructorTearOffLoweringEnabled) {
+    return new Procedure(constructorTearOffName(name, compilationUnit.library),
+        ProcedureKind.Method, new FunctionNode(null),
+        fileUri: compilationUnit.fileUri, isStatic: true)
+      ..startFileOffset = fileOffset
+      ..fileOffset = fileOffset
+      ..fileEndOffset = fileOffset
+      ..isNonNullableByDefault = compilationUnit.isNonNullableByDefault;
+  }
+  return null;
+}
+
+/// Creates the parameters and body for [tearOff] based on [constructor].
+void buildConstructorTearOffProcedure(
+    Procedure tearOff,
+    Constructor constructor,
+    Class enclosingClass,
+    SourceLibraryBuilder libraryBuilder) {
+  int fileOffset = tearOff.fileOffset;
+
+  List<TypeParameter> classTypeParameters = enclosingClass.typeParameters;
+
+  List<TypeParameter> typeParameters;
+  List<DartType> typeArguments;
+  Substitution substitution = Substitution.empty;
+  if (classTypeParameters.isNotEmpty) {
+    FreshTypeParameters freshTypeParameters =
+        getFreshTypeParameters(classTypeParameters);
+    typeParameters = freshTypeParameters.freshTypeParameters;
+    typeArguments = freshTypeParameters.freshTypeArguments;
+    substitution = freshTypeParameters.substitution;
+    tearOff.function.typeParameters.addAll(typeParameters);
+    setParents(typeParameters, tearOff.function);
+  } else {
+    typeParameters = [];
+    typeArguments = [];
+    substitution = Substitution.empty;
+  }
+
+  List<Expression> positionalArguments = [];
+  for (VariableDeclaration constructorParameter
+      in constructor.function.positionalParameters) {
+    VariableDeclaration tearOffParameter = new VariableDeclaration(
+        constructorParameter.name,
+        type: substitution.substituteType(constructorParameter.type))
+      ..fileOffset = constructorParameter.fileOffset;
+    tearOff.function.positionalParameters.add(tearOffParameter);
+    positionalArguments
+        .add(new VariableGet(tearOffParameter)..fileOffset = fileOffset);
+    tearOffParameter.parent = tearOff.function;
+  }
+  List<NamedExpression> namedArguments = [];
+  for (VariableDeclaration constructorParameter
+      in constructor.function.namedParameters) {
+    VariableDeclaration tearOffParameter = new VariableDeclaration(
+        constructorParameter.name,
+        type: substitution.substituteType(constructorParameter.type),
+        isRequired: constructorParameter.isRequired)
+      ..fileOffset = constructorParameter.fileOffset;
+    tearOff.function.namedParameters.add(tearOffParameter);
+    tearOffParameter.parent = tearOff.function;
+    namedArguments.add(new NamedExpression(tearOffParameter.name!,
+        new VariableGet(tearOffParameter)..fileOffset = fileOffset)
+      ..fileOffset = fileOffset);
+  }
+  tearOff.function.returnType =
+      substitution.substituteType(constructor.function.returnType);
+  tearOff.function.requiredParameterCount =
+      constructor.function.requiredParameterCount;
+  tearOff.function.body = new ReturnStatement(
+      new ConstructorInvocation(
+          constructor,
+          new Arguments(positionalArguments,
+              named: namedArguments, types: typeArguments)
+            ..fileOffset = tearOff.fileOffset)
+        ..fileOffset = tearOff.fileOffset)
+    ..fileOffset = tearOff.fileOffset
+    ..parent = tearOff.function;
+  tearOff.function.fileOffset = tearOff.fileOffset;
+  tearOff.function.fileEndOffset = tearOff.fileOffset;
+  updatePrivateMemberName(tearOff, libraryBuilder);
+}
+
+/// Copies the parameter types from [constructor] to [tearOff].
+///
+/// These might have been inferred and therefore not available when the
+/// parameters were created.
+// TODO(johnniwinther): Add tests for inferred parameter types.
+// TODO(johnniwinther): Avoid doing this when parameter types are not inferred.
+void buildConstructorTearOffOutline(
+    Procedure tearOff, Constructor constructor, Class enclosingClass) {
+  List<TypeParameter> classTypeParameters = enclosingClass.typeParameters;
+  Substitution substitution = Substitution.empty;
+  if (classTypeParameters.isNotEmpty) {
+    List<DartType> typeArguments = [];
+    for (TypeParameter typeParameter in tearOff.function.typeParameters) {
+      typeArguments.add(new TypeParameterType(typeParameter,
+          TypeParameterType.computeNullabilityFromBound(typeParameter)));
+    }
+    substitution = Substitution.fromPairs(classTypeParameters, typeArguments);
+  }
+  for (int i = 0; i < constructor.function.positionalParameters.length; i++) {
+    VariableDeclaration tearOffParameter =
+        tearOff.function.positionalParameters[i];
+    VariableDeclaration constructorParameter =
+        constructor.function.positionalParameters[i];
+    tearOffParameter.type =
+        substitution.substituteType(constructorParameter.type);
+  }
+  for (int i = 0; i < constructor.function.namedParameters.length; i++) {
+    VariableDeclaration tearOffParameter = tearOff.function.namedParameters[i];
+    VariableDeclaration constructorParameter =
+        constructor.function.namedParameters[i];
+    tearOffParameter.type =
+        substitution.substituteType(constructorParameter.type);
+  }
+}
+
+void buildConstructorTearOffDefaultValues(
+    Procedure tearOff, Constructor constructor, Class enclosingClass) {
+  CloneVisitorNotMembers cloner = new CloneVisitorNotMembers();
+  for (int i = 0; i < constructor.function.positionalParameters.length; i++) {
+    VariableDeclaration tearOffParameter =
+        tearOff.function.positionalParameters[i];
+    VariableDeclaration constructorParameter =
+        constructor.function.positionalParameters[i];
+    tearOffParameter.initializer =
+        cloner.cloneOptional(constructorParameter.initializer);
+    tearOffParameter.initializer?.parent = tearOffParameter;
+  }
+  for (int i = 0; i < constructor.function.namedParameters.length; i++) {
+    VariableDeclaration tearOffParameter = tearOff.function.namedParameters[i];
+    VariableDeclaration constructorParameter =
+        constructor.function.namedParameters[i];
+    tearOffParameter.initializer =
+        cloner.cloneOptional(constructorParameter.initializer);
+    tearOffParameter.initializer?.parent = tearOffParameter;
+  }
+}
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 e010bb0..9789db1 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -14,7 +14,6 @@
 
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
-import '../builder/constructor_builder.dart';
 import '../builder/declaration_builder.dart';
 import '../builder/extension_builder.dart';
 import '../builder/invalid_type_declaration_builder.dart';
@@ -3092,6 +3091,7 @@
   @override
   buildPropertyAccess(
       IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
+    int nameOffset = offsetForToken(send.token);
     Name name = send.name;
     Arguments? arguments = send.arguments;
 
@@ -3107,8 +3107,7 @@
     if (declarationBuilder is DeclarationBuilder) {
       DeclarationBuilder declaration = declarationBuilder;
       Builder? member = declaration.findStaticBuilder(
-          name.text, offsetForToken(send.token), _uri, _helper.libraryBuilder);
-
+          name.text, nameOffset, _uri, _helper.libraryBuilder);
       Generator generator;
       if (member == null) {
         // If we find a setter, [member] is an [AccessErrorBuilder], not null.
@@ -3116,19 +3115,25 @@
           if (_helper.enableConstructorTearOffsInLibrary &&
               declarationBuilder is ClassBuilder) {
             MemberBuilder? constructor =
-                declarationBuilder.findConstructorOrFactory(name.text,
-                    offsetForToken(send.token), _uri, _helper.libraryBuilder);
-            if (constructor is ConstructorBuilder) {
-              return _helper.forest.createConstructorTearOff(
-                  token.charOffset, constructor.constructor);
-            } else {
-              // TODO(dmitryas): Add support for factories.
-              generator =
-                  new UnresolvedNameGenerator(_helper, send.token, name);
+                declarationBuilder.findConstructorOrFactory(
+                    name.text, nameOffset, _uri, _helper.libraryBuilder);
+            Member? tearOff = constructor?.readTarget;
+            if (tearOff is Constructor) {
+              if (declarationBuilder.isAbstract) {
+                return _helper.buildProblem(
+                    messageAbstractClassConstructorTearOff,
+                    nameOffset,
+                    name.text.length);
+              }
+              return _helper.forest
+                  .createConstructorTearOff(token.charOffset, tearOff);
+            } else if (tearOff is Procedure) {
+              return _helper.forest
+                  .createStaticTearOff(token.charOffset, tearOff);
             }
-          } else {
-            generator = new UnresolvedNameGenerator(_helper, send.token, name);
+            // TODO(dmitryas): Add support for factories.
           }
+          generator = new UnresolvedNameGenerator(_helper, send.token, name);
         } else {
           return _helper.buildConstructorInvocation(
               declaration,
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index b53d108..75d9371 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -832,6 +832,12 @@
     assert(fileOffset != null);
     return new ConstructorTearOff(constructor)..fileOffset = fileOffset;
   }
+
+  StaticTearOff createStaticTearOff(int fileOffset, Procedure procedure) {
+    // ignore: unnecessary_null_comparison
+    assert(fileOffset != null);
+    return new StaticTearOff(procedure)..fileOffset = fileOffset;
+  }
 }
 
 class _VariablesDeclaration extends Statement {
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index ccd5c3b..d87c8f9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -191,7 +191,9 @@
   @override
   ExpressionInferenceResult visitStaticTearOff(
       StaticTearOff node, DartType typeContext) {
-    return _unhandledExpression(node, typeContext);
+    DartType type =
+        node.target.function.computeFunctionType(inferrer.library.nonNullable);
+    return inferrer.instantiateTearOff(type, typeContext, node);
   }
 
   @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 956c6a8..2531ba7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -43,6 +43,7 @@
 import '../dill/dill_library_builder.dart' show DillLibraryBuilder;
 import '../dill/dill_target.dart' show DillTarget;
 import '../fasta_codes.dart' show LocatedMessage, Message;
+import '../kernel/constructor_tearoff_lowering.dart';
 import '../loader.dart' show Loader;
 import '../messages.dart'
     show
@@ -778,6 +779,7 @@
             fileUri: cls.fileUri)
           ..isNonNullableByDefault =
               cls.enclosingLibrary.isNonNullableByDefault,
+        null,
         // If the constructor is constant, the default values must be part of
         // the outline expressions. We pass on the original constructor and
         // cloned function nodes to ensure that the default values are computed
@@ -797,17 +799,26 @@
   SyntheticConstructorBuilder _makeDefaultConstructor(
       SourceClassBuilder classBuilder, Constructor? referenceFrom) {
     Class enclosingClass = classBuilder.cls;
+    Constructor constructor = new Constructor(
+        new FunctionNode(new EmptyStatement(),
+            returnType: makeConstructorReturnType(enclosingClass)),
+        name: new Name(""),
+        isSynthetic: true,
+        reference: referenceFrom?.reference,
+        fileUri: enclosingClass.fileUri)
+      ..fileOffset = enclosingClass.fileOffset
+      ..isNonNullableByDefault =
+          enclosingClass.enclosingLibrary.isNonNullableByDefault;
+    Procedure? constructorTearOff = createConstructorTearOffProcedure(
+        '', classBuilder.library, constructor.fileOffset,
+        forAbstractClassOrEnum:
+            enclosingClass.isAbstract || enclosingClass.isEnum);
+    if (constructorTearOff != null) {
+      buildConstructorTearOffProcedure(constructorTearOff, constructor,
+          classBuilder.cls, classBuilder.library);
+    }
     return new SyntheticConstructorBuilder(
-        classBuilder,
-        new Constructor(
-            new FunctionNode(new EmptyStatement(),
-                returnType: makeConstructorReturnType(enclosingClass)),
-            name: new Name(""),
-            isSynthetic: true,
-            reference: referenceFrom?.reference,
-            fileUri: enclosingClass.fileUri)
-          ..isNonNullableByDefault =
-              enclosingClass.enclosingLibrary.isNonNullableByDefault);
+        classBuilder, constructor, constructorTearOff);
   }
 
   DartType makeConstructorReturnType(Class enclosingClass) {
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index ec8bc6f..4cc93c2 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -105,6 +105,7 @@
 
   final bool enableNative;
   final bool stringExpectedAfterNative;
+  bool inAbstractClass = false;
   bool inConstructor = false;
   bool inConstructorName = false;
   int importIndex = 0;
@@ -470,6 +471,7 @@
     libraryBuilder.currentTypeParameterScopeBuilder
         .markAsClassDeclaration(name.lexeme, name.charOffset, typeVariables);
     libraryBuilder.setCurrentClassName(name.lexeme);
+    inAbstractClass = abstractToken != null;
     push(abstractToken != null ? abstractMask : 0);
   }
 
@@ -584,6 +586,7 @@
       supertype.typeVariables = typeVariables;
     }
     List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
+    inAbstractClass = false;
     checkEmpty(beginToken.charOffset);
     if (name is ParserRecovery) {
       libraryBuilder
@@ -1240,7 +1243,8 @@
           formalsOffset,
           endToken.charOffset,
           nativeMethodName,
-          beginInitializers: beginInitializers);
+          beginInitializers: beginInitializers,
+          forAbstractClass: inAbstractClass);
     } else {
       if (isConst) {
         // TODO(danrubel): consider removing this
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 0bb1220..392acae 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -558,7 +558,11 @@
     constructorScopeBuilder.addMember(name, constructorBuilder);
     // Synthetic constructors are created after the component has been built
     // so we need to add the constructor to the class.
-    cls.addConstructor(constructorBuilder.member);
+    cls.addConstructor(constructorBuilder.invokeTarget);
+    if (constructorBuilder.readTarget != null &&
+        constructorBuilder.readTarget != constructorBuilder.invokeTarget) {
+      cls.addProcedure(constructorBuilder.readTarget as Procedure);
+    }
     if (constructorBuilder.isConst) {
       cls.hasConstConstructor = true;
     }
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 78cf330..b9eed88 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -2324,7 +2324,8 @@
       int charOpenParenOffset,
       int charEndOffset,
       String? nativeMethodName,
-      {Token? beginInitializers}) {
+      {Token? beginInitializers,
+      required bool forAbstractClass}) {
     Member? referenceFrom;
     if (_currentClassReferencesFromIndexed != null) {
       referenceFrom = _currentClassReferencesFromIndexed!.lookupConstructor(
@@ -2344,7 +2345,8 @@
         charOpenParenOffset,
         charEndOffset,
         referenceFrom,
-        nativeMethodName);
+        nativeMethodName: nativeMethodName,
+        forAbstractClassOrEnum: forAbstractClass);
     checkTypeVariables(typeVariables, constructorBuilder);
     addBuilder(constructorName, constructorBuilder, charOffset,
         getterReference: referenceFrom?.reference);
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 18c7bae..f6e79b9 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -5,6 +5,7 @@
 # Note that test/spelling: Status will have no effect. Spelling errors can
 # always be fixed by either spelling correctly or updating the dictionary.
 
+AbstractClassConstructorTearOff/analyzerCode: Fail
 AbstractClassInstantiation/example: Fail
 AbstractExtensionField/analyzerCode: Fail
 AbstractExtensionField/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 8045d59..84ed8c2 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -5232,3 +5232,10 @@
   script: |
     f<X>() {}
     main() => f<int, String>;
+
+AbstractClassConstructorTearOff:
+  template: "Constructors on abstract classes can't be torn off."
+  experiments: constructor-tearoffs
+  script: |
+    abstract class Class {}
+    main() => Class.new;
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 04c1037..e8d1ece 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -124,20 +124,12 @@
 import 'package:kernel/target/targets.dart'
     show
         ConstantsBackend,
+        ConstructorTearOffLowering,
         DiagnosticReporter,
-        NoneConstantsBackend,
-        NoneTarget,
         LateLowering,
-        Target,
-        TargetFlags;
-
-import 'package:kernel/target/targets.dart'
-    show
-        ConstantsBackend,
-        DiagnosticReporter,
+        NumberSemantics,
         NoneConstantsBackend,
         NoneTarget,
-        NumberSemantics,
         Target,
         TargetFlags;
 
@@ -249,6 +241,7 @@
   final bool forceLateLoweringSentinel;
   final bool forceStaticFieldLowering;
   final bool forceNoExplicitGetterCalls;
+  final int forceConstructorTearOffLowering;
   final bool nnbdAgnosticMode;
   final Map<String, String> defines;
   final bool noVerify;
@@ -260,6 +253,7 @@
       this.forceLateLoweringSentinel: false,
       this.forceStaticFieldLowering: false,
       this.forceNoExplicitGetterCalls: false,
+      this.forceConstructorTearOffLowering: ConstructorTearOffLowering.none,
       this.nnbdAgnosticMode: false,
       this.defines: const {},
       this.noVerify: false,
@@ -426,6 +420,7 @@
       bool forceLateLoweringSentinel = false;
       bool forceStaticFieldLowering = false;
       bool forceNoExplicitGetterCalls = false;
+      int forceConstructorTearOffLowering = ConstructorTearOffLowering.none;
       bool nnbdAgnosticMode = false;
       bool noVerify = false;
       Map<String, String> defines = {};
@@ -436,6 +431,7 @@
             forceLateLoweringSentinel: forceLateLoweringSentinel,
             forceStaticFieldLowering: forceStaticFieldLowering,
             forceNoExplicitGetterCalls: forceNoExplicitGetterCalls,
+            forceConstructorTearOffLowering: forceConstructorTearOffLowering,
             nnbdAgnosticMode: nnbdAgnosticMode,
             defines: defines,
             noVerify: noVerify,
@@ -468,6 +464,8 @@
               forceNoExplicitGetterCalls = true;
             } else if (line.startsWith(Flags.forceNoExplicitGetterCalls)) {
               forceNoExplicitGetterCalls = true;
+            } else if (line.startsWith(Flags.forceConstructorTearOffLowering)) {
+              forceConstructorTearOffLowering = ConstructorTearOffLowering.all;
             } else if (line.startsWith(Flags.nnbdAgnosticMode)) {
               nnbdAgnosticMode = true;
             } else if (line.startsWith(Flags.noDefines)) {
@@ -520,6 +518,7 @@
               forceLateLoweringSentinel: forceLateLoweringSentinel,
               forceStaticFieldLowering: forceStaticFieldLowering,
               forceNoExplicitGetterCalls: forceNoExplicitGetterCalls,
+              forceConstructorTearOffLowering: forceConstructorTearOffLowering,
               nnbdAgnosticMode: nnbdAgnosticMode,
               defines: defines,
               noVerify: noVerify,
@@ -1708,6 +1707,8 @@
     forceStaticFieldLoweringForTesting: folderOptions.forceStaticFieldLowering,
     forceNoExplicitGetterCallsForTesting:
         folderOptions.forceNoExplicitGetterCalls,
+    forceConstructorTearOffLoweringForTesting:
+        folderOptions.forceConstructorTearOffLowering,
     enableNullSafety: context.soundNullSafety,
   );
   Target target;
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index c957a82..d3835d4 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -107,7 +107,26 @@
 busywait
 bye
 c's
+c1a
+c1b
+c1c
+c1d
+c2a
+c2b
+c2c
+c2d
+c3a
+c3b
+c3c
+c3d
+c4a
+c4b
 c59cdee365b94ce066344840f9e3412d642019b
+c5a
+c5b
+c6a
+c6b
+c6c
 ca
 cafebabe
 calloc
@@ -133,6 +152,7 @@
 class2e
 class2f
 class3d
+class4int
 class5a
 class5b
 class5c
@@ -298,9 +318,22 @@
 explainer
 extern
 f1
+f1a
+f1b
+f1c
 f2
+f2a
+f2b
 f3
+f3a
+f3b
 f4
+f4a
+f4b
+f5a
+f5b
+f6a
+f6b
 fac
 faking
 falling
diff --git a/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart
new file mode 100644
index 0000000..31fcc39
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.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.
+
+class ConcreteClass {}
+abstract class AbstractClass {}
+mixin Mixin {}
+class NamedMixinApplication = Object with Mixin;
+abstract class AbstractNamedMixinApplication = Object with Mixin;
+extension Extension on int {}
+
+test() {
+  ConcreteClass.new; // ok
+  AbstractClass.new; // error
+  Mixin.new; // error
+  NamedMixinApplication.new; // ok
+  AbstractNamedMixinApplication.new; // error
+  Extension.new; // error
+}
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.strong.expect
new file mode 100644
index 0000000..e8c1280
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.strong.expect
@@ -0,0 +1,64 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:14:17: Error: Constructors on abstract classes can't be torn off.
+//   AbstractClass.new; // error
+//                 ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:15:9: Error: Getter not found: 'new'.
+//   Mixin.new; // error
+//         ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:17:33: Error: Constructors on abstract classes can't be torn off.
+//   AbstractNamedMixinApplication.new; // error
+//                                 ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:18:13: Error: Getter not found: 'new'.
+//   Extension.new; // error
+//             ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class ConcreteClass extends core::Object {
+  synthetic constructor •() → self::ConcreteClass
+    : super core::Object::•()
+    ;
+}
+abstract class AbstractClass extends core::Object {
+  synthetic constructor •() → self::AbstractClass
+    : super core::Object::•()
+    ;
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+}
+class NamedMixinApplication = core::Object with self::Mixin /*hasConstConstructor*/  {
+  const synthetic constructor •() → self::NamedMixinApplication
+    : super core::Object::•()
+    ;
+}
+abstract class AbstractNamedMixinApplication = core::Object with self::Mixin /*hasConstConstructor*/  {
+  const synthetic constructor •() → self::AbstractNamedMixinApplication
+    : super core::Object::•()
+    ;
+}
+extension Extension on core::int {
+}
+static method test() → dynamic {
+  self::ConcreteClass::•;
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:14:17: Error: Constructors on abstract classes can't be torn off.
+  AbstractClass.new; // error
+                ^^^";
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:15:9: Error: Getter not found: 'new'.
+  Mixin.new; // error
+        ^^^";
+  self::NamedMixinApplication::•;
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:17:33: Error: Constructors on abstract classes can't be torn off.
+  AbstractNamedMixinApplication.new; // error
+                                ^^^";
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:18:13: Error: Getter not found: 'new'.
+  Extension.new; // error
+            ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.strong.transformed.expect
new file mode 100644
index 0000000..b86fac8
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.strong.transformed.expect
@@ -0,0 +1,64 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:14:17: Error: Constructors on abstract classes can't be torn off.
+//   AbstractClass.new; // error
+//                 ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:15:9: Error: Getter not found: 'new'.
+//   Mixin.new; // error
+//         ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:17:33: Error: Constructors on abstract classes can't be torn off.
+//   AbstractNamedMixinApplication.new; // error
+//                                 ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:18:13: Error: Getter not found: 'new'.
+//   Extension.new; // error
+//             ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class ConcreteClass extends core::Object {
+  synthetic constructor •() → self::ConcreteClass
+    : super core::Object::•()
+    ;
+}
+abstract class AbstractClass extends core::Object {
+  synthetic constructor •() → self::AbstractClass
+    : super core::Object::•()
+    ;
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+}
+class NamedMixinApplication extends core::Object implements self::Mixin /*isEliminatedMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::NamedMixinApplication
+    : super core::Object::•()
+    ;
+}
+abstract class AbstractNamedMixinApplication extends core::Object implements self::Mixin /*isEliminatedMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::AbstractNamedMixinApplication
+    : super core::Object::•()
+    ;
+}
+extension Extension on core::int {
+}
+static method test() → dynamic {
+  self::ConcreteClass::•;
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:14:17: Error: Constructors on abstract classes can't be torn off.
+  AbstractClass.new; // error
+                ^^^";
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:15:9: Error: Getter not found: 'new'.
+  Mixin.new; // error
+        ^^^";
+  self::NamedMixinApplication::•;
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:17:33: Error: Constructors on abstract classes can't be torn off.
+  AbstractNamedMixinApplication.new; // error
+                                ^^^";
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:18:13: Error: Getter not found: 'new'.
+  Extension.new; // error
+            ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..a955952
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.textual_outline.expect
@@ -0,0 +1,12 @@
+class ConcreteClass {}
+
+abstract class AbstractClass {}
+
+mixin Mixin {}
+class NamedMixinApplication = Object with Mixin;
+abstract class AbstractNamedMixinApplication = Object with Mixin;
+
+extension Extension on int {}
+
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f9d5a03
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+abstract class AbstractClass {}
+
+abstract class AbstractNamedMixinApplication = Object with Mixin;
+
+class ConcreteClass {}
+
+class NamedMixinApplication = Object with Mixin;
+
+extension Extension on int {}
+
+main() {}
+mixin Mixin {}
+test() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.weak.expect
new file mode 100644
index 0000000..e8c1280
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.weak.expect
@@ -0,0 +1,64 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:14:17: Error: Constructors on abstract classes can't be torn off.
+//   AbstractClass.new; // error
+//                 ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:15:9: Error: Getter not found: 'new'.
+//   Mixin.new; // error
+//         ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:17:33: Error: Constructors on abstract classes can't be torn off.
+//   AbstractNamedMixinApplication.new; // error
+//                                 ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:18:13: Error: Getter not found: 'new'.
+//   Extension.new; // error
+//             ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class ConcreteClass extends core::Object {
+  synthetic constructor •() → self::ConcreteClass
+    : super core::Object::•()
+    ;
+}
+abstract class AbstractClass extends core::Object {
+  synthetic constructor •() → self::AbstractClass
+    : super core::Object::•()
+    ;
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+}
+class NamedMixinApplication = core::Object with self::Mixin /*hasConstConstructor*/  {
+  const synthetic constructor •() → self::NamedMixinApplication
+    : super core::Object::•()
+    ;
+}
+abstract class AbstractNamedMixinApplication = core::Object with self::Mixin /*hasConstConstructor*/  {
+  const synthetic constructor •() → self::AbstractNamedMixinApplication
+    : super core::Object::•()
+    ;
+}
+extension Extension on core::int {
+}
+static method test() → dynamic {
+  self::ConcreteClass::•;
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:14:17: Error: Constructors on abstract classes can't be torn off.
+  AbstractClass.new; // error
+                ^^^";
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:15:9: Error: Getter not found: 'new'.
+  Mixin.new; // error
+        ^^^";
+  self::NamedMixinApplication::•;
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:17:33: Error: Constructors on abstract classes can't be torn off.
+  AbstractNamedMixinApplication.new; // error
+                                ^^^";
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:18:13: Error: Getter not found: 'new'.
+  Extension.new; // error
+            ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.weak.outline.expect
new file mode 100644
index 0000000..23490ce
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.weak.outline.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class ConcreteClass extends core::Object {
+  synthetic constructor •() → self::ConcreteClass
+    ;
+}
+abstract class AbstractClass extends core::Object {
+  synthetic constructor •() → self::AbstractClass
+    ;
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+}
+class NamedMixinApplication = core::Object with self::Mixin /*hasConstConstructor*/  {
+  const synthetic constructor •() → self::NamedMixinApplication
+    : super core::Object::•()
+    ;
+}
+abstract class AbstractNamedMixinApplication = core::Object with self::Mixin /*hasConstConstructor*/  {
+  const synthetic constructor •() → self::AbstractNamedMixinApplication
+    : super core::Object::•()
+    ;
+}
+extension Extension on core::int {
+}
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.weak.transformed.expect
new file mode 100644
index 0000000..b86fac8
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart.weak.transformed.expect
@@ -0,0 +1,64 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:14:17: Error: Constructors on abstract classes can't be torn off.
+//   AbstractClass.new; // error
+//                 ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:15:9: Error: Getter not found: 'new'.
+//   Mixin.new; // error
+//         ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:17:33: Error: Constructors on abstract classes can't be torn off.
+//   AbstractNamedMixinApplication.new; // error
+//                                 ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:18:13: Error: Getter not found: 'new'.
+//   Extension.new; // error
+//             ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class ConcreteClass extends core::Object {
+  synthetic constructor •() → self::ConcreteClass
+    : super core::Object::•()
+    ;
+}
+abstract class AbstractClass extends core::Object {
+  synthetic constructor •() → self::AbstractClass
+    : super core::Object::•()
+    ;
+}
+abstract class Mixin extends core::Object /*isMixinDeclaration*/  {
+}
+class NamedMixinApplication extends core::Object implements self::Mixin /*isEliminatedMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::NamedMixinApplication
+    : super core::Object::•()
+    ;
+}
+abstract class AbstractNamedMixinApplication extends core::Object implements self::Mixin /*isEliminatedMixin,hasConstConstructor*/  {
+  const synthetic constructor •() → self::AbstractNamedMixinApplication
+    : super core::Object::•()
+    ;
+}
+extension Extension on core::int {
+}
+static method test() → dynamic {
+  self::ConcreteClass::•;
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:14:17: Error: Constructors on abstract classes can't be torn off.
+  AbstractClass.new; // error
+                ^^^";
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:15:9: Error: Getter not found: 'new'.
+  Mixin.new; // error
+        ^^^";
+  self::NamedMixinApplication::•;
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:17:33: Error: Constructors on abstract classes can't be torn off.
+  AbstractNamedMixinApplication.new; // error
+                                ^^^";
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/abstract_class_constructor_tear_off.dart:18:13: Error: Getter not found: 'new'.
+  Extension.new; // error
+            ^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.strong.expect
index 4dc6864..f3930d4 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.strong.expect
@@ -9,17 +9,26 @@
 // A<X> Function<X>(X) test2() => A.foo2; // Error.
 //                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:34: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*2*/' is from 'unknown'.
 // A<X> Function<X>(X) test3() => A.new; // Error.
-//                                  ^^^
+//                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:39: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*2*/' is from 'unknown'.
 // A<X> Function<X>(X) test4() => A<int>.new; // Error.
-//                                       ^^^
+//                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:47: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*2*/' is from 'unknown'.
 // A<X> Function<X>(X) test5() => A<int, String>.new; // Error.
-//                                               ^^^
+//                                ^
 //
 // pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:18:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
 //  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
@@ -57,30 +66,39 @@
 A<X> Function<X>(X) test2() => A.foo2; // Error.
                                ^" in self::A::foo2 as{TypeError,ForNonNullableByDefault} Never;
 static method test3() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:34: Error: Getter not found: 'new'.
+  return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test3() => A.new; // Error.
-                                 ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} <X extends core::Object? = dynamic>(X%) → self::A<X%>;
+                               ^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
 static method test4() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:39: Error: Getter not found: 'new'.
+  return let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test4() => A<int>.new; // Error.
-                                      ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} <X extends core::Object? = dynamic>(X%) → self::A<X%>;
+                               ^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
 static method test5() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:47: Error: Getter not found: 'new'.
+  return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test5() => A<int, String>.new; // Error.
-                                              ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} <X extends core::Object? = dynamic>(X%) → self::A<X%>;
+                               ^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
 static method test6() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
   return self::A::foo1;
 static method test7() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
   return self::A::foo1;
 static method test8() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:18:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+  return let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:18:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test8() => A<int>.foo2; // Error.
                                ^" in self::A::foo2 as{TypeError,ForNonNullableByDefault} Never;
 static method test9() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:19:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+  return let final Never #t6 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:19:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*2*/' is from 'unknown'.
diff --git a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.strong.transformed.expect
index b7f501c..f3930d4 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.strong.transformed.expect
@@ -9,17 +9,26 @@
 // A<X> Function<X>(X) test2() => A.foo2; // Error.
 //                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:34: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*2*/' is from 'unknown'.
 // A<X> Function<X>(X) test3() => A.new; // Error.
-//                                  ^^^
+//                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:39: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*2*/' is from 'unknown'.
 // A<X> Function<X>(X) test4() => A<int>.new; // Error.
-//                                       ^^^
+//                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:47: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*2*/' is from 'unknown'.
 // A<X> Function<X>(X) test5() => A<int, String>.new; // Error.
-//                                               ^^^
+//                                ^
 //
 // pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:18:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
 //  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
@@ -57,30 +66,39 @@
 A<X> Function<X>(X) test2() => A.foo2; // Error.
                                ^" in self::A::foo2 as{TypeError,ForNonNullableByDefault} Never;
 static method test3() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:34: Error: Getter not found: 'new'.
+  return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test3() => A.new; // Error.
-                                 ^^^";
+                               ^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
 static method test4() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:39: Error: Getter not found: 'new'.
+  return let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test4() => A<int>.new; // Error.
-                                      ^^^";
+                               ^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
 static method test5() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:47: Error: Getter not found: 'new'.
+  return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test5() => A<int, String>.new; // Error.
-                                              ^^^";
+                               ^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
 static method test6() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
   return self::A::foo1;
 static method test7() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
   return self::A::foo1;
 static method test8() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:18:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+  return let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:18:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test8() => A<int>.foo2; // Error.
                                ^" in self::A::foo2 as{TypeError,ForNonNullableByDefault} Never;
 static method test9() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:19:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+  return let final Never #t6 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:19:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*2*/' is from 'unknown'.
diff --git a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.weak.expect
index 4dc6864..f3930d4 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.weak.expect
@@ -9,17 +9,26 @@
 // A<X> Function<X>(X) test2() => A.foo2; // Error.
 //                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:34: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*2*/' is from 'unknown'.
 // A<X> Function<X>(X) test3() => A.new; // Error.
-//                                  ^^^
+//                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:39: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*2*/' is from 'unknown'.
 // A<X> Function<X>(X) test4() => A<int>.new; // Error.
-//                                       ^^^
+//                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:47: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*2*/' is from 'unknown'.
 // A<X> Function<X>(X) test5() => A<int, String>.new; // Error.
-//                                               ^^^
+//                                ^
 //
 // pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:18:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
 //  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
@@ -57,30 +66,39 @@
 A<X> Function<X>(X) test2() => A.foo2; // Error.
                                ^" in self::A::foo2 as{TypeError,ForNonNullableByDefault} Never;
 static method test3() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:34: Error: Getter not found: 'new'.
+  return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test3() => A.new; // Error.
-                                 ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} <X extends core::Object? = dynamic>(X%) → self::A<X%>;
+                               ^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
 static method test4() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:39: Error: Getter not found: 'new'.
+  return let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test4() => A<int>.new; // Error.
-                                      ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} <X extends core::Object? = dynamic>(X%) → self::A<X%>;
+                               ^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
 static method test5() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:47: Error: Getter not found: 'new'.
+  return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test5() => A<int, String>.new; // Error.
-                                              ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} <X extends core::Object? = dynamic>(X%) → self::A<X%>;
+                               ^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
 static method test6() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
   return self::A::foo1;
 static method test7() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
   return self::A::foo1;
 static method test8() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:18:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+  return let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:18:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test8() => A<int>.foo2; // Error.
                                ^" in self::A::foo2 as{TypeError,ForNonNullableByDefault} Never;
 static method test9() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:19:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+  return let final Never #t6 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:19:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*2*/' is from 'unknown'.
diff --git a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.weak.transformed.expect
index b7f501c..f3930d4 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart.weak.transformed.expect
@@ -9,17 +9,26 @@
 // A<X> Function<X>(X) test2() => A.foo2; // Error.
 //                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:34: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*2*/' is from 'unknown'.
 // A<X> Function<X>(X) test3() => A.new; // Error.
-//                                  ^^^
+//                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:39: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*2*/' is from 'unknown'.
 // A<X> Function<X>(X) test4() => A<int>.new; // Error.
-//                                       ^^^
+//                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:47: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+//  - 'X/*2*/' is from 'unknown'.
 // A<X> Function<X>(X) test5() => A<int, String>.new; // Error.
-//                                               ^^^
+//                                ^
 //
 // pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:18:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
 //  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
@@ -57,30 +66,39 @@
 A<X> Function<X>(X) test2() => A.foo2; // Error.
                                ^" in self::A::foo2 as{TypeError,ForNonNullableByDefault} Never;
 static method test3() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:34: Error: Getter not found: 'new'.
+  return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:13:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test3() => A.new; // Error.
-                                 ^^^";
+                               ^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
 static method test4() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:39: Error: Getter not found: 'new'.
+  return let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:14:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test4() => A<int>.new; // Error.
-                                      ^^^";
+                               ^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
 static method test5() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:47: Error: Getter not found: 'new'.
+  return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
+ - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test5() => A<int, String>.new; // Error.
-                                              ^^^";
+                               ^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
 static method test6() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
   return self::A::foo1;
 static method test7() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
   return self::A::foo1;
 static method test8() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:18:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+  return let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:18:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*2*/' is from 'unknown'.
 A<X> Function<X>(X) test8() => A<int>.foo2; // Error.
                                ^" in self::A::foo2 as{TypeError,ForNonNullableByDefault} Never;
 static method test9() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
-  return let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:19:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
+  return let final Never #t6 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:19:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
  - 'X/*2*/' is from 'unknown'.
diff --git a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.strong.expect
index 75dc4d2..fdf0c65 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.strong.expect
@@ -1,19 +1,4 @@
 library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:12:16: Error: Getter not found: 'new'.
-// testNew() => A.new; // Ok.
-//                ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:13:25: Error: Getter not found: 'new'.
-// testNewArgs() => A<int>.new; // Ok.
-//                         ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:16:38: Error: Getter not found: 'new'.
-// testNewExtraArgs() => A<int, String>.new; // Error.
-//                                      ^^^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -28,17 +13,11 @@
 static method testFooArgs() → dynamic
   return self::A::foo;
 static method testNew() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:12:16: Error: Getter not found: 'new'.
-testNew() => A.new; // Ok.
-               ^^^";
+  return self::A::•;
 static method testNewArgs() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:13:25: Error: Getter not found: 'new'.
-testNewArgs() => A<int>.new; // Ok.
-                        ^^^";
+  return self::A::•;
 static method testFooExtraArgs() → dynamic
   return self::A::foo;
 static method testNewExtraArgs() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:16:38: Error: Getter not found: 'new'.
-testNewExtraArgs() => A<int, String>.new; // Error.
-                                     ^^^";
+  return self::A::•;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.strong.transformed.expect
index 75dc4d2..fdf0c65 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.strong.transformed.expect
@@ -1,19 +1,4 @@
 library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:12:16: Error: Getter not found: 'new'.
-// testNew() => A.new; // Ok.
-//                ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:13:25: Error: Getter not found: 'new'.
-// testNewArgs() => A<int>.new; // Ok.
-//                         ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:16:38: Error: Getter not found: 'new'.
-// testNewExtraArgs() => A<int, String>.new; // Error.
-//                                      ^^^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -28,17 +13,11 @@
 static method testFooArgs() → dynamic
   return self::A::foo;
 static method testNew() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:12:16: Error: Getter not found: 'new'.
-testNew() => A.new; // Ok.
-               ^^^";
+  return self::A::•;
 static method testNewArgs() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:13:25: Error: Getter not found: 'new'.
-testNewArgs() => A<int>.new; // Ok.
-                        ^^^";
+  return self::A::•;
 static method testFooExtraArgs() → dynamic
   return self::A::foo;
 static method testNewExtraArgs() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:16:38: Error: Getter not found: 'new'.
-testNewExtraArgs() => A<int, String>.new; // Error.
-                                     ^^^";
+  return self::A::•;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.weak.expect
index 75dc4d2..fdf0c65 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.weak.expect
@@ -1,19 +1,4 @@
 library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:12:16: Error: Getter not found: 'new'.
-// testNew() => A.new; // Ok.
-//                ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:13:25: Error: Getter not found: 'new'.
-// testNewArgs() => A<int>.new; // Ok.
-//                         ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:16:38: Error: Getter not found: 'new'.
-// testNewExtraArgs() => A<int, String>.new; // Error.
-//                                      ^^^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -28,17 +13,11 @@
 static method testFooArgs() → dynamic
   return self::A::foo;
 static method testNew() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:12:16: Error: Getter not found: 'new'.
-testNew() => A.new; // Ok.
-               ^^^";
+  return self::A::•;
 static method testNewArgs() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:13:25: Error: Getter not found: 'new'.
-testNewArgs() => A<int>.new; // Ok.
-                        ^^^";
+  return self::A::•;
 static method testFooExtraArgs() → dynamic
   return self::A::foo;
 static method testNewExtraArgs() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:16:38: Error: Getter not found: 'new'.
-testNewExtraArgs() => A<int, String>.new; // Error.
-                                     ^^^";
+  return self::A::•;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.weak.transformed.expect
index 75dc4d2..fdf0c65 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart.weak.transformed.expect
@@ -1,19 +1,4 @@
 library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:12:16: Error: Getter not found: 'new'.
-// testNew() => A.new; // Ok.
-//                ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:13:25: Error: Getter not found: 'new'.
-// testNewArgs() => A<int>.new; // Ok.
-//                         ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:16:38: Error: Getter not found: 'new'.
-// testNewExtraArgs() => A<int, String>.new; // Error.
-//                                      ^^^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -28,17 +13,11 @@
 static method testFooArgs() → dynamic
   return self::A::foo;
 static method testNew() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:12:16: Error: Getter not found: 'new'.
-testNew() => A.new; // Ok.
-               ^^^";
+  return self::A::•;
 static method testNewArgs() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:13:25: Error: Getter not found: 'new'.
-testNewArgs() => A<int>.new; // Ok.
-                        ^^^";
+  return self::A::•;
 static method testFooExtraArgs() → dynamic
   return self::A::foo;
 static method testNewExtraArgs() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_without_context.dart:16:38: Error: Getter not found: 'new'.
-testNewExtraArgs() => A<int, String>.new; // Error.
-                                     ^^^";
+  return self::A::•;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/instantiation.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/instantiation.dart.strong.expect
index 99f37b0..86f5a15 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/instantiation.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/instantiation.dart.strong.expect
@@ -2,14 +2,6 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:12:35: Error: Getter not found: 'new'.
-// A<num> Function(num) test3() => A.new; // Ok.
-//                                   ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:13:35: Error: Getter not found: 'new'.
-// A<int> Function(int) test4() => A.new; // Ok.
-//                                   ^^^
-//
 // pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:15:40: Error: Inferred type argument 'String' doesn't conform to the bound 'num' of the type variable 'X' on 'A<X> Function<X extends num>(X)'.
 //  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/instantiation.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
@@ -19,13 +11,14 @@
 // class A<X extends num> {
 //         ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:16:42: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:16:40: Error: Inferred type argument 'String' doesn't conform to the bound 'num' of the type variable 'X' on 'A<X> Function<X extends num>(X)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/instantiation.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
 // A<dynamic> Function(String) test6() => A.new; // Error.
-//                                          ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:18:44: Error: Getter not found: 'new'.
-// A<dynamic> Function(num) test8() => A<num>.new; // Error.
-//                                            ^^^
+//                                        ^
+// pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {
+//         ^
 //
 import self as self;
 import "dart:core" as core;
@@ -41,23 +34,15 @@
 static method test2() → (core::int) → self::A<core::int>
   return self::A::foo<core::int>;
 static method test3() → (core::num) → self::A<core::num>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:12:35: Error: Getter not found: 'new'.
-A<num> Function(num) test3() => A.new; // Ok.
-                                  ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} (core::num) → self::A<core::num>;
+  return self::A::•<core::num>;
 static method test4() → (core::int) → self::A<core::int>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:13:35: Error: Getter not found: 'new'.
-A<int> Function(int) test4() => A.new; // Ok.
-                                  ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} (core::int) → self::A<core::int>;
+  return self::A::•<core::int>;
 static method test5() → (core::String) → self::A<dynamic>
   return self::A::foo<core::String>;
 static method test6() → (core::String) → self::A<dynamic>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:16:42: Error: Getter not found: 'new'.
-A<dynamic> Function(String) test6() => A.new; // Error.
-                                         ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} (core::String) → self::A<dynamic>;
+  return self::A::•<core::String>;
 static method test7() → (core::num) → self::A<dynamic>
   return self::A::foo<core::num>;
 static method test8() → (core::num) → self::A<dynamic>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:18:44: Error: Getter not found: 'new'.
-A<dynamic> Function(num) test8() => A<num>.new; // Error.
-                                           ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} (core::num) → self::A<dynamic>;
+  return self::A::•<core::num>;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/instantiation.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/instantiation.dart.weak.expect
index 99f37b0..86f5a15 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/instantiation.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/instantiation.dart.weak.expect
@@ -2,14 +2,6 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:12:35: Error: Getter not found: 'new'.
-// A<num> Function(num) test3() => A.new; // Ok.
-//                                   ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:13:35: Error: Getter not found: 'new'.
-// A<int> Function(int) test4() => A.new; // Ok.
-//                                   ^^^
-//
 // pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:15:40: Error: Inferred type argument 'String' doesn't conform to the bound 'num' of the type variable 'X' on 'A<X> Function<X extends num>(X)'.
 //  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/instantiation.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
@@ -19,13 +11,14 @@
 // class A<X extends num> {
 //         ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:16:42: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:16:40: Error: Inferred type argument 'String' doesn't conform to the bound 'num' of the type variable 'X' on 'A<X> Function<X extends num>(X)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/instantiation.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
 // A<dynamic> Function(String) test6() => A.new; // Error.
-//                                          ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:18:44: Error: Getter not found: 'new'.
-// A<dynamic> Function(num) test8() => A<num>.new; // Error.
-//                                            ^^^
+//                                        ^
+// pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {
+//         ^
 //
 import self as self;
 import "dart:core" as core;
@@ -41,23 +34,15 @@
 static method test2() → (core::int) → self::A<core::int>
   return self::A::foo<core::int>;
 static method test3() → (core::num) → self::A<core::num>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:12:35: Error: Getter not found: 'new'.
-A<num> Function(num) test3() => A.new; // Ok.
-                                  ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} (core::num) → self::A<core::num>;
+  return self::A::•<core::num>;
 static method test4() → (core::int) → self::A<core::int>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:13:35: Error: Getter not found: 'new'.
-A<int> Function(int) test4() => A.new; // Ok.
-                                  ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} (core::int) → self::A<core::int>;
+  return self::A::•<core::int>;
 static method test5() → (core::String) → self::A<dynamic>
   return self::A::foo<core::String>;
 static method test6() → (core::String) → self::A<dynamic>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:16:42: Error: Getter not found: 'new'.
-A<dynamic> Function(String) test6() => A.new; // Error.
-                                         ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} (core::String) → self::A<dynamic>;
+  return self::A::•<core::String>;
 static method test7() → (core::num) → self::A<dynamic>
   return self::A::foo<core::num>;
 static method test8() → (core::num) → self::A<dynamic>
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/instantiation.dart:18:44: Error: Getter not found: 'new'.
-A<dynamic> Function(num) test8() => A<num>.new; // Error.
-                                           ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} (core::num) → self::A<dynamic>;
+  return self::A::•<core::num>;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart
new file mode 100644
index 0000000..37a72c7
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart
@@ -0,0 +1,154 @@
+// 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.
+
+final bool inSoundMode = <int?>[] is! List<int>;
+
+main() {
+  print('inSoundMode: $inSoundMode');
+  testNoArgs();
+  testArgs();
+}
+
+class Class1 {}
+
+class Class2 {
+  Class2.named();
+}
+
+testNoArgs() {
+  var f1a = Class1.new;
+  var c1a = f1a();
+  expect(true, c1a is Class1);
+
+  dynamic f1b = Class1.new;
+  var c1b = f1b();
+  expect(true, c1b is Class1);
+
+  expect(true, identical(f1a, f1b));
+
+  var f2a = Class2.named;
+  var c2a = f2a();
+  expect(true, c2a is Class2);
+
+  dynamic f2b = Class2.named;
+  var c2b = f2b();
+  expect(true, c2b is Class2);
+
+  expect(true, identical(f2a, f2b));
+}
+
+class Class3 {
+  final int field;
+
+  Class3(this.field);
+}
+
+class Class4 {
+  final int? field;
+
+  Class4([this.field]);
+}
+
+class Class5 {
+  final int field1;
+  final int? field2;
+
+  Class5(this.field1, [this.field2]);
+}
+
+class Class6 {
+  final int field1;
+  final int? field2;
+  final int field3;
+
+  Class6(this.field1, {this.field2, required this.field3});
+}
+
+testArgs() {
+  var f3a = Class3.new;
+  var c3a = f3a(42);
+  expect(42, c3a.field);
+  () {
+    f3a(); // error
+    f3a(42, 87); // error
+  };
+
+  dynamic f3b = Class3.new;
+  var c3b = f3b(87);
+  expect(87, c3b.field);
+  throws(() => f3b());
+  throws(() => f3b(42, 87));
+
+  var f4a = Class4.new;
+  var c4a = f4a();
+  expect(null, c4a.field);
+  var c4b = f4a(42);
+  expect(42, c4b.field);
+  () {
+    f4a(42, 87); // error
+  };
+  dynamic f4b = Class4.new;
+  throws(() => f4b(42, 87));
+
+
+  var f5a = Class5.new;
+  var c5a = f5a(42);
+  expect(42, c5a.field1);
+  expect(null, c5a.field2);
+  var c5b = f5a(87, 42);
+  expect(87, c5b.field1);
+  expect(42, c5b.field2);
+  () {
+    f5a(); // error
+    f5a(42, 87, 123); // error
+  };
+  dynamic f5b = Class5.new;
+  throws(() => f5b());
+  throws(() => f5b(42, 87, 123));
+
+  var f6a = Class6.new;
+  var c6a = f6a(42, field3: 87);
+  expect(42, c6a.field1);
+  expect(null, c6a.field2);
+  expect(87, c6a.field3);
+  () {
+    f6a(); // error
+    f6a(42); // error
+    f6a(42, 87); // error
+    f6a(field1: 87, field2: 87); // error
+  };
+
+  var c6b = f6a(42, field2: 123, field3: 87);
+  expect(42, c6b.field1);
+  expect(123, c6b.field2);
+  expect(87, c6b.field3);
+
+  var c6c = f6a(87, field3: 42, field2: 123);
+  expect(87, c6c.field1);
+  expect(123, c6c.field2);
+  expect(42, c6c.field3);
+
+  dynamic f6b = Class6.new;
+  throws(() => f6b());
+  throws(() => f6b(42), inSoundModeOnly: true);
+  throws(() => f6b(42, 87), inSoundModeOnly: true);
+  throws(() => f6b(field1: 87, field2: 87));
+}
+
+expect(expected, actual) {
+  if (expected != actual) throw 'Expected $expected, actual $actual';
+}
+
+throws(Function() f, {bool inSoundModeOnly: false}) {
+  try {
+    f();
+  } catch (e) {
+    print('Thrown: $e');
+    return;
+  }
+  if (!inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw 'Expected exception';
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.strong.expect
new file mode 100644
index 0000000..ecc6126
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.strong.expect
@@ -0,0 +1,230 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:73:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f3a(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:74:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f3a(42, 87); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:89:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f4a(42, 87); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:103:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f5a(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:104:8: Error: Too many positional arguments: 2 allowed, but 3 found.
+// Try removing the extra positional arguments.
+//     f5a(42, 87, 123); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:116:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f6a(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:117:8: Error: Required named parameter 'field3' must be provided.
+//     f6a(42); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:118:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f6a(42, 87); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:119:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f6a(field1: 87, field2: 87); // error
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff() → self::Class1
+    return new self::Class1::•();
+}
+class Class2 extends core::Object {
+  constructor named() → self::Class2
+    : super core::Object::•()
+    ;
+  static method _#named#tearOff() → self::Class2
+    return new self::Class2::named();
+}
+class Class3 extends core::Object {
+  final field core::int field;
+  constructor •(core::int field) → self::Class3
+    : self::Class3::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field) → self::Class3
+    return new self::Class3::•(field);
+}
+class Class4 extends core::Object {
+  final field core::int? field;
+  constructor •([core::int? field = #C1]) → self::Class4
+    : self::Class4::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff([core::int? field = #C1]) → self::Class4
+    return new self::Class4::•(field);
+}
+class Class5 extends core::Object {
+  final field core::int field1;
+  final field core::int? field2;
+  constructor •(core::int field1, [core::int? field2 = #C1]) → self::Class5
+    : self::Class5::field1 = field1, self::Class5::field2 = field2, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field1, [core::int? field2 = #C1]) → self::Class5
+    return new self::Class5::•(field1, field2);
+}
+class Class6 extends core::Object {
+  final field core::int field1;
+  final field core::int? field2;
+  final field core::int field3;
+  constructor •(core::int field1, {core::int? field2 = #C1, required core::int field3 = #C1}) → self::Class6
+    : self::Class6::field1 = field1, self::Class6::field2 = field2, self::Class6::field3 = field3, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field1, {core::int? field2 = #C1, required core::int field3 = #C1}) → self::Class6
+    return new self::Class6::•(field1, field2: field2, field3: field3);
+}
+static final field core::bool inSoundMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testNoArgs();
+  self::testArgs();
+}
+static method testNoArgs() → dynamic {
+  () → self::Class1 f1a = #C2;
+  self::Class1 c1a = f1a(){() → self::Class1};
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1);
+  dynamic f1b = #C2;
+  dynamic c1b = f1b{dynamic}.call();
+  self::expect(true, c1b is{ForNonNullableByDefault} self::Class1);
+  self::expect(true, core::identical(f1a, f1b));
+  () → self::Class2 f2a = #C3;
+  self::Class2 c2a = f2a(){() → self::Class2};
+  self::expect(true, c2a is{ForNonNullableByDefault} self::Class2);
+  dynamic f2b = #C3;
+  dynamic c2b = f2b{dynamic}.call();
+  self::expect(true, c2b is{ForNonNullableByDefault} self::Class2);
+  self::expect(true, core::identical(f2a, f2b));
+}
+static method testArgs() → dynamic {
+  (core::int) → self::Class3 f3a = #C4;
+  self::Class3 c3a = f3a(42){(core::int) → self::Class3};
+  self::expect(42, c3a.{self::Class3::field}{core::int});
+  () → Null {
+    let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:73:8: Error: Too few positional arguments: 1 required, 0 given.
+    f3a(); // error
+       ^" in f3a{<inapplicable>}.();
+    let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:74:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f3a(42, 87); // error
+       ^" in f3a{<inapplicable>}.(42, 87);
+  };
+  dynamic f3b = #C4;
+  dynamic c3b = f3b{dynamic}.call(87);
+  self::expect(87, c3b{dynamic}.field);
+  self::throws(() → dynamic => f3b{dynamic}.call());
+  self::throws(() → dynamic => f3b{dynamic}.call(42, 87));
+  ([core::int?]) → self::Class4 f4a = #C5;
+  self::Class4 c4a = f4a(){([core::int?]) → self::Class4};
+  self::expect(null, c4a.{self::Class4::field}{core::int?});
+  self::Class4 c4b = f4a(42){([core::int?]) → self::Class4};
+  self::expect(42, c4b.{self::Class4::field}{core::int?});
+  () → Null {
+    let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:89:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f4a(42, 87); // error
+       ^" in f4a{<inapplicable>}.(42, 87);
+  };
+  dynamic f4b = #C5;
+  self::throws(() → dynamic => f4b{dynamic}.call(42, 87));
+  (core::int, [core::int?]) → self::Class5 f5a = #C6;
+  self::Class5 c5a = f5a(42){(core::int, [core::int?]) → self::Class5};
+  self::expect(42, c5a.{self::Class5::field1}{core::int});
+  self::expect(null, c5a.{self::Class5::field2}{core::int?});
+  self::Class5 c5b = f5a(87, 42){(core::int, [core::int?]) → self::Class5};
+  self::expect(87, c5b.{self::Class5::field1}{core::int});
+  self::expect(42, c5b.{self::Class5::field2}{core::int?});
+  () → Null {
+    let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:103:8: Error: Too few positional arguments: 1 required, 0 given.
+    f5a(); // error
+       ^" in f5a{<inapplicable>}.();
+    let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:104:8: Error: Too many positional arguments: 2 allowed, but 3 found.
+Try removing the extra positional arguments.
+    f5a(42, 87, 123); // error
+       ^" in f5a{<inapplicable>}.(42, 87, 123);
+  };
+  dynamic f5b = #C6;
+  self::throws(() → dynamic => f5b{dynamic}.call());
+  self::throws(() → dynamic => f5b{dynamic}.call(42, 87, 123));
+  (core::int, {field2: core::int?, required field3: core::int}) → self::Class6 f6a = #C7;
+  self::Class6 c6a = f6a(42, field3: 87){(core::int, {field2: core::int?, required field3: core::int}) → self::Class6};
+  self::expect(42, c6a.{self::Class6::field1}{core::int});
+  self::expect(null, c6a.{self::Class6::field2}{core::int?});
+  self::expect(87, c6a.{self::Class6::field3}{core::int});
+  () → Null {
+    let final Never #t6 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:116:8: Error: Too few positional arguments: 1 required, 0 given.
+    f6a(); // error
+       ^" in f6a{<inapplicable>}.();
+    let final Never #t7 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:117:8: Error: Required named parameter 'field3' must be provided.
+    f6a(42); // error
+       ^" in f6a{<inapplicable>}.(42);
+    let final Never #t8 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:118:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f6a(42, 87); // error
+       ^" in f6a{<inapplicable>}.(42, 87);
+    let final Never #t9 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:119:8: Error: Too few positional arguments: 1 required, 0 given.
+    f6a(field1: 87, field2: 87); // error
+       ^" in f6a{<inapplicable>}.(field1: 87, field2: 87);
+  };
+  self::Class6 c6b = f6a(42, field2: 123, field3: 87){(core::int, {field2: core::int?, required field3: core::int}) → self::Class6};
+  self::expect(42, c6b.{self::Class6::field1}{core::int});
+  self::expect(123, c6b.{self::Class6::field2}{core::int?});
+  self::expect(87, c6b.{self::Class6::field3}{core::int});
+  self::Class6 c6c = f6a(87, field3: 42, field2: 123){(core::int, {field2: core::int?, required field3: core::int}) → self::Class6};
+  self::expect(87, c6c.{self::Class6::field1}{core::int});
+  self::expect(123, c6c.{self::Class6::field2}{core::int?});
+  self::expect(42, c6c.{self::Class6::field3}{core::int});
+  dynamic f6b = #C7;
+  self::throws(() → dynamic => f6b{dynamic}.call());
+  self::throws(() → dynamic => f6b{dynamic}.call(42), inSoundModeOnly: true);
+  self::throws(() → dynamic => f6b{dynamic}.call(42, 87), inSoundModeOnly: true);
+  self::throws(() → dynamic => f6b{dynamic}.call(field1: 87, field2: 87));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C8}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = null
+  #C2 = tearoff self::Class1::_#new#tearOff
+  #C3 = tearoff self::Class2::_#named#tearOff
+  #C4 = tearoff self::Class3::_#new#tearOff
+  #C5 = tearoff self::Class4::_#new#tearOff
+  #C6 = tearoff self::Class5::_#new#tearOff
+  #C7 = tearoff self::Class6::_#new#tearOff
+  #C8 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.strong.transformed.expect
new file mode 100644
index 0000000..49aa5ce
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.strong.transformed.expect
@@ -0,0 +1,230 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:73:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f3a(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:74:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f3a(42, 87); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:89:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f4a(42, 87); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:103:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f5a(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:104:8: Error: Too many positional arguments: 2 allowed, but 3 found.
+// Try removing the extra positional arguments.
+//     f5a(42, 87, 123); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:116:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f6a(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:117:8: Error: Required named parameter 'field3' must be provided.
+//     f6a(42); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:118:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f6a(42, 87); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:119:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f6a(field1: 87, field2: 87); // error
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff() → self::Class1
+    return new self::Class1::•();
+}
+class Class2 extends core::Object {
+  constructor named() → self::Class2
+    : super core::Object::•()
+    ;
+  static method _#named#tearOff() → self::Class2
+    return new self::Class2::named();
+}
+class Class3 extends core::Object {
+  final field core::int field;
+  constructor •(core::int field) → self::Class3
+    : self::Class3::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field) → self::Class3
+    return new self::Class3::•(field);
+}
+class Class4 extends core::Object {
+  final field core::int? field;
+  constructor •([core::int? field = #C1]) → self::Class4
+    : self::Class4::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff([core::int? field = #C1]) → self::Class4
+    return new self::Class4::•(field);
+}
+class Class5 extends core::Object {
+  final field core::int field1;
+  final field core::int? field2;
+  constructor •(core::int field1, [core::int? field2 = #C1]) → self::Class5
+    : self::Class5::field1 = field1, self::Class5::field2 = field2, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field1, [core::int? field2 = #C1]) → self::Class5
+    return new self::Class5::•(field1, field2);
+}
+class Class6 extends core::Object {
+  final field core::int field1;
+  final field core::int? field2;
+  final field core::int field3;
+  constructor •(core::int field1, {core::int? field2 = #C1, required core::int field3 = #C1}) → self::Class6
+    : self::Class6::field1 = field1, self::Class6::field2 = field2, self::Class6::field3 = field3, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field1, {core::int? field2 = #C1, required core::int field3 = #C1}) → self::Class6
+    return new self::Class6::•(field1, field2: field2, field3: field3);
+}
+static final field core::bool inSoundMode = !(core::_GrowableList::•<core::int?>(0) is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testNoArgs();
+  self::testArgs();
+}
+static method testNoArgs() → dynamic {
+  () → self::Class1 f1a = #C2;
+  self::Class1 c1a = f1a(){() → self::Class1};
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1);
+  dynamic f1b = #C2;
+  dynamic c1b = f1b{dynamic}.call();
+  self::expect(true, c1b is{ForNonNullableByDefault} self::Class1);
+  self::expect(true, core::identical(f1a, f1b));
+  () → self::Class2 f2a = #C3;
+  self::Class2 c2a = f2a(){() → self::Class2};
+  self::expect(true, c2a is{ForNonNullableByDefault} self::Class2);
+  dynamic f2b = #C3;
+  dynamic c2b = f2b{dynamic}.call();
+  self::expect(true, c2b is{ForNonNullableByDefault} self::Class2);
+  self::expect(true, core::identical(f2a, f2b));
+}
+static method testArgs() → dynamic {
+  (core::int) → self::Class3 f3a = #C4;
+  self::Class3 c3a = f3a(42){(core::int) → self::Class3};
+  self::expect(42, c3a.{self::Class3::field}{core::int});
+  () → Null {
+    let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:73:8: Error: Too few positional arguments: 1 required, 0 given.
+    f3a(); // error
+       ^" in f3a{<inapplicable>}.();
+    let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:74:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f3a(42, 87); // error
+       ^" in f3a{<inapplicable>}.(42, 87);
+  };
+  dynamic f3b = #C4;
+  dynamic c3b = f3b{dynamic}.call(87);
+  self::expect(87, c3b{dynamic}.field);
+  self::throws(() → dynamic => f3b{dynamic}.call());
+  self::throws(() → dynamic => f3b{dynamic}.call(42, 87));
+  ([core::int?]) → self::Class4 f4a = #C5;
+  self::Class4 c4a = f4a(){([core::int?]) → self::Class4};
+  self::expect(null, c4a.{self::Class4::field}{core::int?});
+  self::Class4 c4b = f4a(42){([core::int?]) → self::Class4};
+  self::expect(42, c4b.{self::Class4::field}{core::int?});
+  () → Null {
+    let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:89:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f4a(42, 87); // error
+       ^" in f4a{<inapplicable>}.(42, 87);
+  };
+  dynamic f4b = #C5;
+  self::throws(() → dynamic => f4b{dynamic}.call(42, 87));
+  (core::int, [core::int?]) → self::Class5 f5a = #C6;
+  self::Class5 c5a = f5a(42){(core::int, [core::int?]) → self::Class5};
+  self::expect(42, c5a.{self::Class5::field1}{core::int});
+  self::expect(null, c5a.{self::Class5::field2}{core::int?});
+  self::Class5 c5b = f5a(87, 42){(core::int, [core::int?]) → self::Class5};
+  self::expect(87, c5b.{self::Class5::field1}{core::int});
+  self::expect(42, c5b.{self::Class5::field2}{core::int?});
+  () → Null {
+    let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:103:8: Error: Too few positional arguments: 1 required, 0 given.
+    f5a(); // error
+       ^" in f5a{<inapplicable>}.();
+    let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:104:8: Error: Too many positional arguments: 2 allowed, but 3 found.
+Try removing the extra positional arguments.
+    f5a(42, 87, 123); // error
+       ^" in f5a{<inapplicable>}.(42, 87, 123);
+  };
+  dynamic f5b = #C6;
+  self::throws(() → dynamic => f5b{dynamic}.call());
+  self::throws(() → dynamic => f5b{dynamic}.call(42, 87, 123));
+  (core::int, {field2: core::int?, required field3: core::int}) → self::Class6 f6a = #C7;
+  self::Class6 c6a = f6a(42, field3: 87){(core::int, {field2: core::int?, required field3: core::int}) → self::Class6};
+  self::expect(42, c6a.{self::Class6::field1}{core::int});
+  self::expect(null, c6a.{self::Class6::field2}{core::int?});
+  self::expect(87, c6a.{self::Class6::field3}{core::int});
+  () → Null {
+    let final Never #t6 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:116:8: Error: Too few positional arguments: 1 required, 0 given.
+    f6a(); // error
+       ^" in f6a{<inapplicable>}.();
+    let final Never #t7 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:117:8: Error: Required named parameter 'field3' must be provided.
+    f6a(42); // error
+       ^" in f6a{<inapplicable>}.(42);
+    let final Never #t8 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:118:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f6a(42, 87); // error
+       ^" in f6a{<inapplicable>}.(42, 87);
+    let final Never #t9 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:119:8: Error: Too few positional arguments: 1 required, 0 given.
+    f6a(field1: 87, field2: 87); // error
+       ^" in f6a{<inapplicable>}.(field1: 87, field2: 87);
+  };
+  self::Class6 c6b = f6a(42, field2: 123, field3: 87){(core::int, {field2: core::int?, required field3: core::int}) → self::Class6};
+  self::expect(42, c6b.{self::Class6::field1}{core::int});
+  self::expect(123, c6b.{self::Class6::field2}{core::int?});
+  self::expect(87, c6b.{self::Class6::field3}{core::int});
+  self::Class6 c6c = f6a(87, field3: 42, field2: 123){(core::int, {field2: core::int?, required field3: core::int}) → self::Class6};
+  self::expect(87, c6c.{self::Class6::field1}{core::int});
+  self::expect(123, c6c.{self::Class6::field2}{core::int?});
+  self::expect(42, c6c.{self::Class6::field3}{core::int});
+  dynamic f6b = #C7;
+  self::throws(() → dynamic => f6b{dynamic}.call());
+  self::throws(() → dynamic => f6b{dynamic}.call(42), inSoundModeOnly: true);
+  self::throws(() → dynamic => f6b{dynamic}.call(42, 87), inSoundModeOnly: true);
+  self::throws(() → dynamic => f6b{dynamic}.call(field1: 87, field2: 87));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C8}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = null
+  #C2 = tearoff self::Class1::_#new#tearOff
+  #C3 = tearoff self::Class2::_#named#tearOff
+  #C4 = tearoff self::Class3::_#new#tearOff
+  #C5 = tearoff self::Class4::_#new#tearOff
+  #C6 = tearoff self::Class5::_#new#tearOff
+  #C7 = tearoff self::Class6::_#new#tearOff
+  #C8 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..88f046b
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.textual_outline.expect
@@ -0,0 +1,37 @@
+final bool inSoundMode = <int?>[] is! List<int>;
+main() {}
+
+class Class1 {}
+
+class Class2 {
+  Class2.named();
+}
+
+testNoArgs() {}
+
+class Class3 {
+  final int field;
+  Class3(this.field);
+}
+
+class Class4 {
+  final int? field;
+  Class4([this.field]);
+}
+
+class Class5 {
+  final int field1;
+  final int? field2;
+  Class5(this.field1, [this.field2]);
+}
+
+class Class6 {
+  final int field1;
+  final int? field2;
+  final int field3;
+  Class6(this.field1, {this.field2, required this.field3});
+}
+
+testArgs() {}
+expect(expected, actual) {}
+throws(Function() f, {bool inSoundModeOnly: false}) {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..d8d816c
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,35 @@
+class Class1 {}
+
+class Class2 {
+  Class2.named();
+}
+
+class Class3 {
+  Class3(this.field);
+  final int field;
+}
+
+class Class4 {
+  Class4([this.field]);
+  final int? field;
+}
+
+class Class5 {
+  Class5(this.field1, [this.field2]);
+  final int? field2;
+  final int field1;
+}
+
+class Class6 {
+  Class6(this.field1, {this.field2, required this.field3});
+  final int? field2;
+  final int field1;
+  final int field3;
+}
+
+expect(expected, actual) {}
+final bool inSoundMode = <int?>[] is! List<int>;
+main() {}
+testArgs() {}
+testNoArgs() {}
+throws(Function() f, {bool inSoundModeOnly: false}) {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.weak.expect
new file mode 100644
index 0000000..ecc6126
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.weak.expect
@@ -0,0 +1,230 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:73:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f3a(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:74:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f3a(42, 87); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:89:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f4a(42, 87); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:103:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f5a(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:104:8: Error: Too many positional arguments: 2 allowed, but 3 found.
+// Try removing the extra positional arguments.
+//     f5a(42, 87, 123); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:116:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f6a(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:117:8: Error: Required named parameter 'field3' must be provided.
+//     f6a(42); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:118:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f6a(42, 87); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:119:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f6a(field1: 87, field2: 87); // error
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff() → self::Class1
+    return new self::Class1::•();
+}
+class Class2 extends core::Object {
+  constructor named() → self::Class2
+    : super core::Object::•()
+    ;
+  static method _#named#tearOff() → self::Class2
+    return new self::Class2::named();
+}
+class Class3 extends core::Object {
+  final field core::int field;
+  constructor •(core::int field) → self::Class3
+    : self::Class3::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field) → self::Class3
+    return new self::Class3::•(field);
+}
+class Class4 extends core::Object {
+  final field core::int? field;
+  constructor •([core::int? field = #C1]) → self::Class4
+    : self::Class4::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff([core::int? field = #C1]) → self::Class4
+    return new self::Class4::•(field);
+}
+class Class5 extends core::Object {
+  final field core::int field1;
+  final field core::int? field2;
+  constructor •(core::int field1, [core::int? field2 = #C1]) → self::Class5
+    : self::Class5::field1 = field1, self::Class5::field2 = field2, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field1, [core::int? field2 = #C1]) → self::Class5
+    return new self::Class5::•(field1, field2);
+}
+class Class6 extends core::Object {
+  final field core::int field1;
+  final field core::int? field2;
+  final field core::int field3;
+  constructor •(core::int field1, {core::int? field2 = #C1, required core::int field3 = #C1}) → self::Class6
+    : self::Class6::field1 = field1, self::Class6::field2 = field2, self::Class6::field3 = field3, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field1, {core::int? field2 = #C1, required core::int field3 = #C1}) → self::Class6
+    return new self::Class6::•(field1, field2: field2, field3: field3);
+}
+static final field core::bool inSoundMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testNoArgs();
+  self::testArgs();
+}
+static method testNoArgs() → dynamic {
+  () → self::Class1 f1a = #C2;
+  self::Class1 c1a = f1a(){() → self::Class1};
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1);
+  dynamic f1b = #C2;
+  dynamic c1b = f1b{dynamic}.call();
+  self::expect(true, c1b is{ForNonNullableByDefault} self::Class1);
+  self::expect(true, core::identical(f1a, f1b));
+  () → self::Class2 f2a = #C3;
+  self::Class2 c2a = f2a(){() → self::Class2};
+  self::expect(true, c2a is{ForNonNullableByDefault} self::Class2);
+  dynamic f2b = #C3;
+  dynamic c2b = f2b{dynamic}.call();
+  self::expect(true, c2b is{ForNonNullableByDefault} self::Class2);
+  self::expect(true, core::identical(f2a, f2b));
+}
+static method testArgs() → dynamic {
+  (core::int) → self::Class3 f3a = #C4;
+  self::Class3 c3a = f3a(42){(core::int) → self::Class3};
+  self::expect(42, c3a.{self::Class3::field}{core::int});
+  () → Null {
+    let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:73:8: Error: Too few positional arguments: 1 required, 0 given.
+    f3a(); // error
+       ^" in f3a{<inapplicable>}.();
+    let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:74:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f3a(42, 87); // error
+       ^" in f3a{<inapplicable>}.(42, 87);
+  };
+  dynamic f3b = #C4;
+  dynamic c3b = f3b{dynamic}.call(87);
+  self::expect(87, c3b{dynamic}.field);
+  self::throws(() → dynamic => f3b{dynamic}.call());
+  self::throws(() → dynamic => f3b{dynamic}.call(42, 87));
+  ([core::int?]) → self::Class4 f4a = #C5;
+  self::Class4 c4a = f4a(){([core::int?]) → self::Class4};
+  self::expect(null, c4a.{self::Class4::field}{core::int?});
+  self::Class4 c4b = f4a(42){([core::int?]) → self::Class4};
+  self::expect(42, c4b.{self::Class4::field}{core::int?});
+  () → Null {
+    let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:89:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f4a(42, 87); // error
+       ^" in f4a{<inapplicable>}.(42, 87);
+  };
+  dynamic f4b = #C5;
+  self::throws(() → dynamic => f4b{dynamic}.call(42, 87));
+  (core::int, [core::int?]) → self::Class5 f5a = #C6;
+  self::Class5 c5a = f5a(42){(core::int, [core::int?]) → self::Class5};
+  self::expect(42, c5a.{self::Class5::field1}{core::int});
+  self::expect(null, c5a.{self::Class5::field2}{core::int?});
+  self::Class5 c5b = f5a(87, 42){(core::int, [core::int?]) → self::Class5};
+  self::expect(87, c5b.{self::Class5::field1}{core::int});
+  self::expect(42, c5b.{self::Class5::field2}{core::int?});
+  () → Null {
+    let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:103:8: Error: Too few positional arguments: 1 required, 0 given.
+    f5a(); // error
+       ^" in f5a{<inapplicable>}.();
+    let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:104:8: Error: Too many positional arguments: 2 allowed, but 3 found.
+Try removing the extra positional arguments.
+    f5a(42, 87, 123); // error
+       ^" in f5a{<inapplicable>}.(42, 87, 123);
+  };
+  dynamic f5b = #C6;
+  self::throws(() → dynamic => f5b{dynamic}.call());
+  self::throws(() → dynamic => f5b{dynamic}.call(42, 87, 123));
+  (core::int, {field2: core::int?, required field3: core::int}) → self::Class6 f6a = #C7;
+  self::Class6 c6a = f6a(42, field3: 87){(core::int, {field2: core::int?, required field3: core::int}) → self::Class6};
+  self::expect(42, c6a.{self::Class6::field1}{core::int});
+  self::expect(null, c6a.{self::Class6::field2}{core::int?});
+  self::expect(87, c6a.{self::Class6::field3}{core::int});
+  () → Null {
+    let final Never #t6 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:116:8: Error: Too few positional arguments: 1 required, 0 given.
+    f6a(); // error
+       ^" in f6a{<inapplicable>}.();
+    let final Never #t7 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:117:8: Error: Required named parameter 'field3' must be provided.
+    f6a(42); // error
+       ^" in f6a{<inapplicable>}.(42);
+    let final Never #t8 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:118:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f6a(42, 87); // error
+       ^" in f6a{<inapplicable>}.(42, 87);
+    let final Never #t9 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:119:8: Error: Too few positional arguments: 1 required, 0 given.
+    f6a(field1: 87, field2: 87); // error
+       ^" in f6a{<inapplicable>}.(field1: 87, field2: 87);
+  };
+  self::Class6 c6b = f6a(42, field2: 123, field3: 87){(core::int, {field2: core::int?, required field3: core::int}) → self::Class6};
+  self::expect(42, c6b.{self::Class6::field1}{core::int});
+  self::expect(123, c6b.{self::Class6::field2}{core::int?});
+  self::expect(87, c6b.{self::Class6::field3}{core::int});
+  self::Class6 c6c = f6a(87, field3: 42, field2: 123){(core::int, {field2: core::int?, required field3: core::int}) → self::Class6};
+  self::expect(87, c6c.{self::Class6::field1}{core::int});
+  self::expect(123, c6c.{self::Class6::field2}{core::int?});
+  self::expect(42, c6c.{self::Class6::field3}{core::int});
+  dynamic f6b = #C7;
+  self::throws(() → dynamic => f6b{dynamic}.call());
+  self::throws(() → dynamic => f6b{dynamic}.call(42), inSoundModeOnly: true);
+  self::throws(() → dynamic => f6b{dynamic}.call(42, 87), inSoundModeOnly: true);
+  self::throws(() → dynamic => f6b{dynamic}.call(field1: 87, field2: 87));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C8}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = null
+  #C2 = tearoff self::Class1::_#new#tearOff
+  #C3 = tearoff self::Class2::_#named#tearOff
+  #C4 = tearoff self::Class3::_#new#tearOff
+  #C5 = tearoff self::Class4::_#new#tearOff
+  #C6 = tearoff self::Class5::_#new#tearOff
+  #C7 = tearoff self::Class6::_#new#tearOff
+  #C8 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.weak.outline.expect
new file mode 100644
index 0000000..8cdb742
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.weak.outline.expect
@@ -0,0 +1,58 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
+    ;
+  static method _#new#tearOff() → self::Class1
+    return new self::Class1::•();
+}
+class Class2 extends core::Object {
+  constructor named() → self::Class2
+    ;
+  static method _#named#tearOff() → self::Class2
+    return new self::Class2::named();
+}
+class Class3 extends core::Object {
+  final field core::int field;
+  constructor •(core::int field) → self::Class3
+    ;
+  static method _#new#tearOff(core::int field) → self::Class3
+    return new self::Class3::•(field);
+}
+class Class4 extends core::Object {
+  final field core::int? field;
+  constructor •([core::int? field]) → self::Class4
+    ;
+  static method _#new#tearOff([core::int? field]) → self::Class4
+    return new self::Class4::•(field);
+}
+class Class5 extends core::Object {
+  final field core::int field1;
+  final field core::int? field2;
+  constructor •(core::int field1, [core::int? field2]) → self::Class5
+    ;
+  static method _#new#tearOff(core::int field1, [core::int? field2]) → self::Class5
+    return new self::Class5::•(field1, field2);
+}
+class Class6 extends core::Object {
+  final field core::int field1;
+  final field core::int? field2;
+  final field core::int field3;
+  constructor •(core::int field1, {core::int? field2, required core::int field3}) → self::Class6
+    ;
+  static method _#new#tearOff(core::int field1, {core::int? field2, required core::int field3}) → self::Class6
+    return new self::Class6::•(field1, field2: field2, field3: field3);
+}
+static final field core::bool inSoundMode;
+static method main() → dynamic
+  ;
+static method testNoArgs() → dynamic
+  ;
+static method testArgs() → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
+static method throws(() → dynamic f, {core::bool inSoundModeOnly}) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.weak.transformed.expect
new file mode 100644
index 0000000..49aa5ce
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart.weak.transformed.expect
@@ -0,0 +1,230 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:73:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f3a(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:74:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f3a(42, 87); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:89:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f4a(42, 87); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:103:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f5a(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:104:8: Error: Too many positional arguments: 2 allowed, but 3 found.
+// Try removing the extra positional arguments.
+//     f5a(42, 87, 123); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:116:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f6a(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:117:8: Error: Required named parameter 'field3' must be provided.
+//     f6a(42); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:118:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f6a(42, 87); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:119:8: Error: Too few positional arguments: 1 required, 0 given.
+//     f6a(field1: 87, field2: 87); // error
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  synthetic constructor •() → self::Class1
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff() → self::Class1
+    return new self::Class1::•();
+}
+class Class2 extends core::Object {
+  constructor named() → self::Class2
+    : super core::Object::•()
+    ;
+  static method _#named#tearOff() → self::Class2
+    return new self::Class2::named();
+}
+class Class3 extends core::Object {
+  final field core::int field;
+  constructor •(core::int field) → self::Class3
+    : self::Class3::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field) → self::Class3
+    return new self::Class3::•(field);
+}
+class Class4 extends core::Object {
+  final field core::int? field;
+  constructor •([core::int? field = #C1]) → self::Class4
+    : self::Class4::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff([core::int? field = #C1]) → self::Class4
+    return new self::Class4::•(field);
+}
+class Class5 extends core::Object {
+  final field core::int field1;
+  final field core::int? field2;
+  constructor •(core::int field1, [core::int? field2 = #C1]) → self::Class5
+    : self::Class5::field1 = field1, self::Class5::field2 = field2, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field1, [core::int? field2 = #C1]) → self::Class5
+    return new self::Class5::•(field1, field2);
+}
+class Class6 extends core::Object {
+  final field core::int field1;
+  final field core::int? field2;
+  final field core::int field3;
+  constructor •(core::int field1, {core::int? field2 = #C1, required core::int field3 = #C1}) → self::Class6
+    : self::Class6::field1 = field1, self::Class6::field2 = field2, self::Class6::field3 = field3, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field1, {core::int? field2 = #C1, required core::int field3 = #C1}) → self::Class6
+    return new self::Class6::•(field1, field2: field2, field3: field3);
+}
+static final field core::bool inSoundMode = !(core::_GrowableList::•<core::int?>(0) is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testNoArgs();
+  self::testArgs();
+}
+static method testNoArgs() → dynamic {
+  () → self::Class1 f1a = #C2;
+  self::Class1 c1a = f1a(){() → self::Class1};
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1);
+  dynamic f1b = #C2;
+  dynamic c1b = f1b{dynamic}.call();
+  self::expect(true, c1b is{ForNonNullableByDefault} self::Class1);
+  self::expect(true, core::identical(f1a, f1b));
+  () → self::Class2 f2a = #C3;
+  self::Class2 c2a = f2a(){() → self::Class2};
+  self::expect(true, c2a is{ForNonNullableByDefault} self::Class2);
+  dynamic f2b = #C3;
+  dynamic c2b = f2b{dynamic}.call();
+  self::expect(true, c2b is{ForNonNullableByDefault} self::Class2);
+  self::expect(true, core::identical(f2a, f2b));
+}
+static method testArgs() → dynamic {
+  (core::int) → self::Class3 f3a = #C4;
+  self::Class3 c3a = f3a(42){(core::int) → self::Class3};
+  self::expect(42, c3a.{self::Class3::field}{core::int});
+  () → Null {
+    let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:73:8: Error: Too few positional arguments: 1 required, 0 given.
+    f3a(); // error
+       ^" in f3a{<inapplicable>}.();
+    let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:74:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f3a(42, 87); // error
+       ^" in f3a{<inapplicable>}.(42, 87);
+  };
+  dynamic f3b = #C4;
+  dynamic c3b = f3b{dynamic}.call(87);
+  self::expect(87, c3b{dynamic}.field);
+  self::throws(() → dynamic => f3b{dynamic}.call());
+  self::throws(() → dynamic => f3b{dynamic}.call(42, 87));
+  ([core::int?]) → self::Class4 f4a = #C5;
+  self::Class4 c4a = f4a(){([core::int?]) → self::Class4};
+  self::expect(null, c4a.{self::Class4::field}{core::int?});
+  self::Class4 c4b = f4a(42){([core::int?]) → self::Class4};
+  self::expect(42, c4b.{self::Class4::field}{core::int?});
+  () → Null {
+    let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:89:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f4a(42, 87); // error
+       ^" in f4a{<inapplicable>}.(42, 87);
+  };
+  dynamic f4b = #C5;
+  self::throws(() → dynamic => f4b{dynamic}.call(42, 87));
+  (core::int, [core::int?]) → self::Class5 f5a = #C6;
+  self::Class5 c5a = f5a(42){(core::int, [core::int?]) → self::Class5};
+  self::expect(42, c5a.{self::Class5::field1}{core::int});
+  self::expect(null, c5a.{self::Class5::field2}{core::int?});
+  self::Class5 c5b = f5a(87, 42){(core::int, [core::int?]) → self::Class5};
+  self::expect(87, c5b.{self::Class5::field1}{core::int});
+  self::expect(42, c5b.{self::Class5::field2}{core::int?});
+  () → Null {
+    let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:103:8: Error: Too few positional arguments: 1 required, 0 given.
+    f5a(); // error
+       ^" in f5a{<inapplicable>}.();
+    let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:104:8: Error: Too many positional arguments: 2 allowed, but 3 found.
+Try removing the extra positional arguments.
+    f5a(42, 87, 123); // error
+       ^" in f5a{<inapplicable>}.(42, 87, 123);
+  };
+  dynamic f5b = #C6;
+  self::throws(() → dynamic => f5b{dynamic}.call());
+  self::throws(() → dynamic => f5b{dynamic}.call(42, 87, 123));
+  (core::int, {field2: core::int?, required field3: core::int}) → self::Class6 f6a = #C7;
+  self::Class6 c6a = f6a(42, field3: 87){(core::int, {field2: core::int?, required field3: core::int}) → self::Class6};
+  self::expect(42, c6a.{self::Class6::field1}{core::int});
+  self::expect(null, c6a.{self::Class6::field2}{core::int?});
+  self::expect(87, c6a.{self::Class6::field3}{core::int});
+  () → Null {
+    let final Never #t6 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:116:8: Error: Too few positional arguments: 1 required, 0 given.
+    f6a(); // error
+       ^" in f6a{<inapplicable>}.();
+    let final Never #t7 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:117:8: Error: Required named parameter 'field3' must be provided.
+    f6a(42); // error
+       ^" in f6a{<inapplicable>}.(42);
+    let final Never #t8 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:118:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f6a(42, 87); // error
+       ^" in f6a{<inapplicable>}.(42, 87);
+    let final Never #t9 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off.dart:119:8: Error: Too few positional arguments: 1 required, 0 given.
+    f6a(field1: 87, field2: 87); // error
+       ^" in f6a{<inapplicable>}.(field1: 87, field2: 87);
+  };
+  self::Class6 c6b = f6a(42, field2: 123, field3: 87){(core::int, {field2: core::int?, required field3: core::int}) → self::Class6};
+  self::expect(42, c6b.{self::Class6::field1}{core::int});
+  self::expect(123, c6b.{self::Class6::field2}{core::int?});
+  self::expect(87, c6b.{self::Class6::field3}{core::int});
+  self::Class6 c6c = f6a(87, field3: 42, field2: 123){(core::int, {field2: core::int?, required field3: core::int}) → self::Class6};
+  self::expect(87, c6c.{self::Class6::field1}{core::int});
+  self::expect(123, c6c.{self::Class6::field2}{core::int?});
+  self::expect(42, c6c.{self::Class6::field3}{core::int});
+  dynamic f6b = #C7;
+  self::throws(() → dynamic => f6b{dynamic}.call());
+  self::throws(() → dynamic => f6b{dynamic}.call(42), inSoundModeOnly: true);
+  self::throws(() → dynamic => f6b{dynamic}.call(42, 87), inSoundModeOnly: true);
+  self::throws(() → dynamic => f6b{dynamic}.call(field1: 87, field2: 87));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C8}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = null
+  #C2 = tearoff self::Class1::_#new#tearOff
+  #C3 = tearoff self::Class2::_#named#tearOff
+  #C4 = tearoff self::Class3::_#new#tearOff
+  #C5 = tearoff self::Class4::_#new#tearOff
+  #C6 = tearoff self::Class5::_#new#tearOff
+  #C7 = tearoff self::Class6::_#new#tearOff
+  #C8 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart
new file mode 100644
index 0000000..80b72e45
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart
@@ -0,0 +1,51 @@
+// 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.
+
+final bool inSoundMode = <int?>[] is! List<int>;
+
+main() {
+  print('inSoundMode: $inSoundMode');
+  testDefaultValues();
+}
+
+class Class1 {
+  final int field;
+
+  Class1([this.field = 42]);
+}
+
+void testDefaultValues() {
+  var f1a = Class1.new;
+  var c1a = f1a();
+  expect(42, c1a.field);
+  var c1b = f1a(87);
+  expect(87, c1b.field);
+  () {
+    f1a(42, 87); // error
+  };
+
+  dynamic f1b = Class1.new;
+  var c1c = f1b();
+  expect(42, c1c.field);
+  var c1d = f1b(87);
+  expect(87, c1d.field);
+  throws(() => f1b(42, 87));
+}
+
+expect(expected, actual) {
+  if (expected != actual) throw 'Expected $expected, actual $actual';
+}
+
+throws(Function() f, {bool inSoundModeOnly: false}) {
+  try {
+    f();
+  } catch (e) {
+    print('Thrown: $e');
+    return;
+  }
+  if (!inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw 'Expected exception';
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.strong.expect
new file mode 100644
index 0000000..9c7ebb5
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.strong.expect
@@ -0,0 +1,67 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart:25:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f1a(42, 87); // error
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  final field core::int field;
+  constructor •([core::int field = #C1]) → self::Class1
+    : self::Class1::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff([core::int field = #C1]) → self::Class1
+    return new self::Class1::•(field);
+}
+static final field core::bool inSoundMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testDefaultValues();
+}
+static method testDefaultValues() → void {
+  ([core::int]) → self::Class1 f1a = #C2;
+  self::Class1 c1a = f1a(){([core::int]) → self::Class1};
+  self::expect(42, c1a.{self::Class1::field}{core::int});
+  self::Class1 c1b = f1a(87){([core::int]) → self::Class1};
+  self::expect(87, c1b.{self::Class1::field}{core::int});
+  () → Null {
+    let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart:25:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f1a(42, 87); // error
+       ^" in f1a{<inapplicable>}.(42, 87);
+  };
+  dynamic f1b = #C2;
+  dynamic c1c = f1b{dynamic}.call();
+  self::expect(42, c1c{dynamic}.field);
+  dynamic c1d = f1b{dynamic}.call(87);
+  self::expect(87, c1d{dynamic}.field);
+  self::throws(() → dynamic => f1b{dynamic}.call(42, 87));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C3}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = 42
+  #C2 = tearoff self::Class1::_#new#tearOff
+  #C3 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.strong.transformed.expect
new file mode 100644
index 0000000..dfe46c0
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.strong.transformed.expect
@@ -0,0 +1,67 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart:25:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f1a(42, 87); // error
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  final field core::int field;
+  constructor •([core::int field = #C1]) → self::Class1
+    : self::Class1::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff([core::int field = #C1]) → self::Class1
+    return new self::Class1::•(field);
+}
+static final field core::bool inSoundMode = !(core::_GrowableList::•<core::int?>(0) is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testDefaultValues();
+}
+static method testDefaultValues() → void {
+  ([core::int]) → self::Class1 f1a = #C2;
+  self::Class1 c1a = f1a(){([core::int]) → self::Class1};
+  self::expect(42, c1a.{self::Class1::field}{core::int});
+  self::Class1 c1b = f1a(87){([core::int]) → self::Class1};
+  self::expect(87, c1b.{self::Class1::field}{core::int});
+  () → Null {
+    let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart:25:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f1a(42, 87); // error
+       ^" in f1a{<inapplicable>}.(42, 87);
+  };
+  dynamic f1b = #C2;
+  dynamic c1c = f1b{dynamic}.call();
+  self::expect(42, c1c{dynamic}.field);
+  dynamic c1d = f1b{dynamic}.call(87);
+  self::expect(87, c1d{dynamic}.field);
+  self::throws(() → dynamic => f1b{dynamic}.call(42, 87));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C3}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = 42
+  #C2 = tearoff self::Class1::_#new#tearOff
+  #C3 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..cd95744
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+final bool inSoundMode = <int?>[] is! List<int>;
+main() {}
+
+class Class1 {
+  final int field;
+  Class1([this.field = 42]);
+}
+
+void testDefaultValues() {}
+expect(expected, actual) {}
+throws(Function() f, {bool inSoundModeOnly: false}) {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0426153
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.textual_outline_modelled.expect
@@ -0,0 +1,10 @@
+class Class1 {
+  Class1([this.field = 42]);
+  final int field;
+}
+
+expect(expected, actual) {}
+final bool inSoundMode = <int?>[] is! List<int>;
+main() {}
+throws(Function() f, {bool inSoundModeOnly: false}) {}
+void testDefaultValues() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.weak.expect
new file mode 100644
index 0000000..9c7ebb5
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.weak.expect
@@ -0,0 +1,67 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart:25:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f1a(42, 87); // error
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  final field core::int field;
+  constructor •([core::int field = #C1]) → self::Class1
+    : self::Class1::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff([core::int field = #C1]) → self::Class1
+    return new self::Class1::•(field);
+}
+static final field core::bool inSoundMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testDefaultValues();
+}
+static method testDefaultValues() → void {
+  ([core::int]) → self::Class1 f1a = #C2;
+  self::Class1 c1a = f1a(){([core::int]) → self::Class1};
+  self::expect(42, c1a.{self::Class1::field}{core::int});
+  self::Class1 c1b = f1a(87){([core::int]) → self::Class1};
+  self::expect(87, c1b.{self::Class1::field}{core::int});
+  () → Null {
+    let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart:25:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f1a(42, 87); // error
+       ^" in f1a{<inapplicable>}.(42, 87);
+  };
+  dynamic f1b = #C2;
+  dynamic c1c = f1b{dynamic}.call();
+  self::expect(42, c1c{dynamic}.field);
+  dynamic c1d = f1b{dynamic}.call(87);
+  self::expect(87, c1d{dynamic}.field);
+  self::throws(() → dynamic => f1b{dynamic}.call(42, 87));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C3}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = 42
+  #C2 = tearoff self::Class1::_#new#tearOff
+  #C3 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.weak.outline.expect
new file mode 100644
index 0000000..7554ec1
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.weak.outline.expect
@@ -0,0 +1,20 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  final field core::int field;
+  constructor •([core::int field]) → self::Class1
+    ;
+  static method _#new#tearOff([core::int field]) → self::Class1
+    return new self::Class1::•(field);
+}
+static final field core::bool inSoundMode;
+static method main() → dynamic
+  ;
+static method testDefaultValues() → void
+  ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
+static method throws(() → dynamic f, {core::bool inSoundModeOnly}) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.weak.transformed.expect
new file mode 100644
index 0000000..dfe46c0
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart.weak.transformed.expect
@@ -0,0 +1,67 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart:25:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//     f1a(42, 87); // error
+//        ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  final field core::int field;
+  constructor •([core::int field = #C1]) → self::Class1
+    : self::Class1::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff([core::int field = #C1]) → self::Class1
+    return new self::Class1::•(field);
+}
+static final field core::bool inSoundMode = !(core::_GrowableList::•<core::int?>(0) is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testDefaultValues();
+}
+static method testDefaultValues() → void {
+  ([core::int]) → self::Class1 f1a = #C2;
+  self::Class1 c1a = f1a(){([core::int]) → self::Class1};
+  self::expect(42, c1a.{self::Class1::field}{core::int});
+  self::Class1 c1b = f1a(87){([core::int]) → self::Class1};
+  self::expect(87, c1b.{self::Class1::field}{core::int});
+  () → Null {
+    let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_default_values.dart:25:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+    f1a(42, 87); // error
+       ^" in f1a{<inapplicable>}.(42, 87);
+  };
+  dynamic f1b = #C2;
+  dynamic c1c = f1b{dynamic}.call();
+  self::expect(42, c1c{dynamic}.field);
+  dynamic c1d = f1b{dynamic}.call(87);
+  self::expect(87, c1d{dynamic}.field);
+  self::throws(() → dynamic => f1b{dynamic}.call(42, 87));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C3}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = 42
+  #C2 = tearoff self::Class1::_#new#tearOff
+  #C3 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_inferred_types.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_inferred_types.dart.weak.expect
new file mode 100644
index 0000000..30628ef
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_inferred_types.dart.weak.expect
@@ -0,0 +1,2 @@
+library /*isNonNullableByDefault*/;
+import self as self;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_inferred_types.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_inferred_types.dart.weak.transformed.expect
new file mode 100644
index 0000000..30628ef
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/constructor_tear_off_inferred_types.dart.weak.transformed.expect
@@ -0,0 +1,2 @@
+library /*isNonNullableByDefault*/;
+import self as self;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/folder.options b/pkg/front_end/testcases/constructor_tearoffs/lowering/folder.options
new file mode 100644
index 0000000..8b3469f
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/folder.options
@@ -0,0 +1,2 @@
+--enable-experiment=constructor-tearoffs
+--force-constructor-tear-off-lowering
\ No newline at end of file
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart
new file mode 100644
index 0000000..12a4640
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart
@@ -0,0 +1,119 @@
+// 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.
+
+final bool inSoundMode = <int?>[] is! List<int>;
+
+main() {
+  print('inSoundMode: $inSoundMode');
+  testGeneric();
+  testBounded();
+}
+
+class Class1<T> {}
+
+testGeneric() {
+  var f1a = Class1.new;
+  var c1a = f1a();
+  expect(true, c1a is Class1<dynamic>);
+  expect(false, c1a is Class1<int>);
+  var c1b = f1a<int>();
+  expect(true, c1b is Class1<int>);
+  expect(false, c1b is Class1<String>);
+  () {
+    f1a<int, String>(); // error
+  };
+
+  var f1b = f1a<int>;
+  var c1c = f1b();
+  expect(true, c1c is Class1<int>);
+  expect(false, c1c is Class1<String>);
+  () {
+    f1b<int>(); // error
+  };
+
+  dynamic f1c = Class1.new;
+  var c1d = f1c();
+  expect(true, c1a is Class1<dynamic>);
+  expect(false, c1a is Class1<int>);
+  throws(() => f1c<int, String>());
+}
+
+class Class2<T extends num> {}
+
+class Class3<T extends S, S> {}
+
+class Class4<T extends Class4<T>> {}
+
+class Class4int extends Class4<Class4int> {}
+
+testBounded() {
+  var f2a = Class2.new;
+  var c2a = f2a();
+  expect(true, c2a is Class2<num>);
+  expect(false, c2a is Class2<int>);
+  var c2b = f2a<int>();
+  expect(true, c2b is Class2<int>);
+  expect(false, c2b is Class2<double>);
+  () {
+    f2a<String>(); // error
+    f2a<int, String>(); // error
+  };
+
+  dynamic f2b = Class2.new;
+  var c2c = f2b();
+  expect(true, c2c is Class2<num>);
+  expect(false, c2c is Class2<int>);
+  var c2d = f2b<int>();
+  expect(true, c2d is Class2<int>);
+  expect(false, c2d is Class2<double>);
+  throws(() => f2b<String>());
+  throws(() => f2b<int, String>());
+
+  var f3a = Class3.new;
+  var c3a = f3a();
+  expect(true, c3a is Class3<dynamic, dynamic>);
+  expect(false, c3a is Class3<int, num>);
+  var c3b = f3a<int, num>();
+  expect(true, c3b is Class3<int, num>);
+  expect(false, c3b is Class3<double, num>);
+  () {
+    f3a<num, int>(); // error
+  };
+
+  dynamic f3b = Class3.new;
+  var c3c = f3b();
+  expect(true, c3c is Class3<dynamic, dynamic>);
+  expect(false, c3c is Class3<int, num>);
+  var c3d = f3b<int, num>();
+  expect(true, c3d is Class3<int, num>);
+  expect(false, c3d is Class3<double, num>);
+  throws(() => f3b<num, int>());
+
+  var f4a = Class4.new;
+  () {
+    var c4a = f4a(); // error
+  };
+
+  dynamic f4b = Class4.new;
+  throws(() => f4b());
+  var c4b = f4b<Class4int>();
+  expect(true, c4b is Class4<Class4int>);
+}
+
+expect(expected, actual) {
+  if (expected != actual) throw 'Expected $expected, actual $actual';
+}
+
+throws(Function() f, {bool inSoundModeOnly: false}) {
+  try {
+    f();
+  } catch (e) {
+    print('Thrown: $e');
+    return;
+  }
+  if (!inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw 'Expected exception';
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.strong.expect
new file mode 100644
index 0000000..d686ae7
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.strong.expect
@@ -0,0 +1,180 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:24:8: Error: Expected 1 type arguments.
+//     f1a<int, String>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:32:8: Error: Expected 0 type arguments.
+//     f1b<int>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:59:8: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'call'.
+// Try changing type arguments so that they conform to the bounds.
+//     f2a<String>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:60:8: Error: Expected 1 type arguments.
+//     f2a<int, String>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:81:8: Error: Type argument 'num' doesn't conform to the bound 'S' of the type variable 'T' on 'call'.
+// Try changing type arguments so that they conform to the bounds.
+//     f3a<num, int>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:95:18: Error: Inferred type argument 'Class4<Object?>' doesn't conform to the bound 'Class4<T>' of the type variable 'T' on 'call'.
+//  - 'Class4' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     var c4a = f4a(); // error
+//                  ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class1<self::Class1::T%>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends core::Object? = dynamic>() → self::Class1<self::Class1::_#new#tearOff::T%>
+    return new self::Class1::•<self::Class1::_#new#tearOff::T%>();
+}
+class Class2<T extends core::num> extends core::Object {
+  synthetic constructor •() → self::Class2<self::Class2::T>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends core::num>() → self::Class2<self::Class2::_#new#tearOff::T>
+    return new self::Class2::•<self::Class2::_#new#tearOff::T>();
+}
+class Class3<T extends self::Class3::S% = dynamic, S extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class3<self::Class3::T%, self::Class3::S%>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends self::Class3::_#new#tearOff::S% = dynamic, S extends core::Object? = dynamic>() → self::Class3<self::Class3::_#new#tearOff::T%, self::Class3::_#new#tearOff::S%>
+    return new self::Class3::•<self::Class3::_#new#tearOff::T%, self::Class3::_#new#tearOff::S%>();
+}
+class Class4<T extends self::Class4<self::Class4::T> = self::Class4<dynamic>> extends core::Object {
+  synthetic constructor •() → self::Class4<self::Class4::T>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends self::Class4<self::Class4::_#new#tearOff::T> = self::Class4<dynamic>>() → self::Class4<self::Class4::_#new#tearOff::T>
+    return new self::Class4::•<self::Class4::_#new#tearOff::T>();
+}
+class Class4int extends self::Class4<self::Class4int> {
+  synthetic constructor •() → self::Class4int
+    : super self::Class4::•()
+    ;
+  static method _#new#tearOff() → self::Class4int
+    return new self::Class4int::•();
+}
+static final field core::bool inSoundMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testGeneric();
+  self::testBounded();
+}
+static method testGeneric() → dynamic {
+  <T extends core::Object? = dynamic>() → self::Class1<T%> f1a = #C1;
+  self::Class1<dynamic> c1a = f1a<dynamic>(){() → self::Class1<dynamic>};
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1<dynamic>);
+  self::expect(false, c1a is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::Class1<core::int> c1b = f1a<core::int>(){() → self::Class1<core::int>};
+  self::expect(true, c1b is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::expect(false, c1b is{ForNonNullableByDefault} self::Class1<core::String>);
+  () → Null {
+    let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:24:8: Error: Expected 1 type arguments.
+    f1a<int, String>(); // error
+       ^" in f1a{<inapplicable>}.<core::int, core::String>();
+  };
+  () → self::Class1<core::int> f1b = f1a<core::int>;
+  self::Class1<core::int> c1c = f1b(){() → self::Class1<core::int>};
+  self::expect(true, c1c is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::expect(false, c1c is{ForNonNullableByDefault} self::Class1<core::String>);
+  () → Null {
+    let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:32:8: Error: Expected 0 type arguments.
+    f1b<int>(); // error
+       ^" in f1b{<inapplicable>}.<core::int>();
+  };
+  dynamic f1c = #C1;
+  dynamic c1d = f1c{dynamic}.call();
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1<dynamic>);
+  self::expect(false, c1a is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::throws(() → dynamic => f1c{dynamic}.call<core::int, core::String>());
+}
+static method testBounded() → dynamic {
+  <T extends core::num>() → self::Class2<T> f2a = #C2;
+  self::Class2<core::num> c2a = f2a<core::num>(){() → self::Class2<core::num>};
+  self::expect(true, c2a is{ForNonNullableByDefault} self::Class2<core::num>);
+  self::expect(false, c2a is{ForNonNullableByDefault} self::Class2<core::int>);
+  self::Class2<core::int> c2b = f2a<core::int>(){() → self::Class2<core::int>};
+  self::expect(true, c2b is{ForNonNullableByDefault} self::Class2<core::int>);
+  self::expect(false, c2b is{ForNonNullableByDefault} self::Class2<core::double>);
+  () → Null {
+    f2a<core::String>(){() → self::Class2<core::String>};
+    let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:60:8: Error: Expected 1 type arguments.
+    f2a<int, String>(); // error
+       ^" in f2a{<inapplicable>}.<core::int, core::String>();
+  };
+  dynamic f2b = #C2;
+  dynamic c2c = f2b{dynamic}.call();
+  self::expect(true, c2c is{ForNonNullableByDefault} self::Class2<core::num>);
+  self::expect(false, c2c is{ForNonNullableByDefault} self::Class2<core::int>);
+  dynamic c2d = f2b{dynamic}.call<core::int>();
+  self::expect(true, c2d is{ForNonNullableByDefault} self::Class2<core::int>);
+  self::expect(false, c2d is{ForNonNullableByDefault} self::Class2<core::double>);
+  self::throws(() → dynamic => f2b{dynamic}.call<core::String>());
+  self::throws(() → dynamic => f2b{dynamic}.call<core::int, core::String>());
+  <T extends S% = dynamic, S extends core::Object? = dynamic>() → self::Class3<T%, S%> f3a = #C3;
+  self::Class3<dynamic, dynamic> c3a = f3a<dynamic, dynamic>(){() → self::Class3<dynamic, dynamic>};
+  self::expect(true, c3a is{ForNonNullableByDefault} self::Class3<dynamic, dynamic>);
+  self::expect(false, c3a is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  self::Class3<core::int, core::num> c3b = f3a<core::int, core::num>(){() → self::Class3<core::int, core::num>};
+  self::expect(true, c3b is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  self::expect(false, c3b is{ForNonNullableByDefault} self::Class3<core::double, core::num>);
+  () → Null {
+    f3a<core::num, core::int>(){() → self::Class3<core::num, core::int>};
+  };
+  dynamic f3b = #C3;
+  dynamic c3c = f3b{dynamic}.call();
+  self::expect(true, c3c is{ForNonNullableByDefault} self::Class3<dynamic, dynamic>);
+  self::expect(false, c3c is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  dynamic c3d = f3b{dynamic}.call<core::int, core::num>();
+  self::expect(true, c3d is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  self::expect(false, c3d is{ForNonNullableByDefault} self::Class3<core::double, core::num>);
+  self::throws(() → dynamic => f3b{dynamic}.call<core::num, core::int>());
+  <T extends self::Class4<T> = self::Class4<dynamic>>() → self::Class4<T> f4a = #C4;
+  () → Null {
+    self::Class4<self::Class4<core::Object?>> c4a = f4a<self::Class4<core::Object?>>(){() → self::Class4<self::Class4<core::Object?>>};
+  };
+  dynamic f4b = #C4;
+  self::throws(() → dynamic => f4b{dynamic}.call());
+  dynamic c4b = f4b{dynamic}.call<self::Class4int>();
+  self::expect(true, c4b is{ForNonNullableByDefault} self::Class4<self::Class4int>);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C5}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = tearoff self::Class1::_#new#tearOff
+  #C2 = tearoff self::Class2::_#new#tearOff
+  #C3 = tearoff self::Class3::_#new#tearOff
+  #C4 = tearoff self::Class4::_#new#tearOff
+  #C5 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.strong.transformed.expect
new file mode 100644
index 0000000..d58a81e
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.strong.transformed.expect
@@ -0,0 +1,180 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:24:8: Error: Expected 1 type arguments.
+//     f1a<int, String>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:32:8: Error: Expected 0 type arguments.
+//     f1b<int>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:59:8: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'call'.
+// Try changing type arguments so that they conform to the bounds.
+//     f2a<String>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:60:8: Error: Expected 1 type arguments.
+//     f2a<int, String>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:81:8: Error: Type argument 'num' doesn't conform to the bound 'S' of the type variable 'T' on 'call'.
+// Try changing type arguments so that they conform to the bounds.
+//     f3a<num, int>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:95:18: Error: Inferred type argument 'Class4<Object?>' doesn't conform to the bound 'Class4<T>' of the type variable 'T' on 'call'.
+//  - 'Class4' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     var c4a = f4a(); // error
+//                  ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class1<self::Class1::T%>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends core::Object? = dynamic>() → self::Class1<self::Class1::_#new#tearOff::T%>
+    return new self::Class1::•<self::Class1::_#new#tearOff::T%>();
+}
+class Class2<T extends core::num> extends core::Object {
+  synthetic constructor •() → self::Class2<self::Class2::T>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends core::num>() → self::Class2<self::Class2::_#new#tearOff::T>
+    return new self::Class2::•<self::Class2::_#new#tearOff::T>();
+}
+class Class3<T extends self::Class3::S% = dynamic, S extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class3<self::Class3::T%, self::Class3::S%>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends self::Class3::_#new#tearOff::S% = dynamic, S extends core::Object? = dynamic>() → self::Class3<self::Class3::_#new#tearOff::T%, self::Class3::_#new#tearOff::S%>
+    return new self::Class3::•<self::Class3::_#new#tearOff::T%, self::Class3::_#new#tearOff::S%>();
+}
+class Class4<T extends self::Class4<self::Class4::T> = self::Class4<dynamic>> extends core::Object {
+  synthetic constructor •() → self::Class4<self::Class4::T>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends self::Class4<self::Class4::_#new#tearOff::T> = self::Class4<dynamic>>() → self::Class4<self::Class4::_#new#tearOff::T>
+    return new self::Class4::•<self::Class4::_#new#tearOff::T>();
+}
+class Class4int extends self::Class4<self::Class4int> {
+  synthetic constructor •() → self::Class4int
+    : super self::Class4::•()
+    ;
+  static method _#new#tearOff() → self::Class4int
+    return new self::Class4int::•();
+}
+static final field core::bool inSoundMode = !(core::_GrowableList::•<core::int?>(0) is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testGeneric();
+  self::testBounded();
+}
+static method testGeneric() → dynamic {
+  <T extends core::Object? = dynamic>() → self::Class1<T%> f1a = #C1;
+  self::Class1<dynamic> c1a = f1a<dynamic>(){() → self::Class1<dynamic>};
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1<dynamic>);
+  self::expect(false, c1a is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::Class1<core::int> c1b = f1a<core::int>(){() → self::Class1<core::int>};
+  self::expect(true, c1b is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::expect(false, c1b is{ForNonNullableByDefault} self::Class1<core::String>);
+  () → Null {
+    let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:24:8: Error: Expected 1 type arguments.
+    f1a<int, String>(); // error
+       ^" in f1a{<inapplicable>}.<core::int, core::String>();
+  };
+  () → self::Class1<core::int> f1b = f1a<core::int>;
+  self::Class1<core::int> c1c = f1b(){() → self::Class1<core::int>};
+  self::expect(true, c1c is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::expect(false, c1c is{ForNonNullableByDefault} self::Class1<core::String>);
+  () → Null {
+    let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:32:8: Error: Expected 0 type arguments.
+    f1b<int>(); // error
+       ^" in f1b{<inapplicable>}.<core::int>();
+  };
+  dynamic f1c = #C1;
+  dynamic c1d = f1c{dynamic}.call();
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1<dynamic>);
+  self::expect(false, c1a is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::throws(() → dynamic => f1c{dynamic}.call<core::int, core::String>());
+}
+static method testBounded() → dynamic {
+  <T extends core::num>() → self::Class2<T> f2a = #C2;
+  self::Class2<core::num> c2a = f2a<core::num>(){() → self::Class2<core::num>};
+  self::expect(true, c2a is{ForNonNullableByDefault} self::Class2<core::num>);
+  self::expect(false, c2a is{ForNonNullableByDefault} self::Class2<core::int>);
+  self::Class2<core::int> c2b = f2a<core::int>(){() → self::Class2<core::int>};
+  self::expect(true, c2b is{ForNonNullableByDefault} self::Class2<core::int>);
+  self::expect(false, c2b is{ForNonNullableByDefault} self::Class2<core::double>);
+  () → Null {
+    f2a<core::String>(){() → self::Class2<core::String>};
+    let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:60:8: Error: Expected 1 type arguments.
+    f2a<int, String>(); // error
+       ^" in f2a{<inapplicable>}.<core::int, core::String>();
+  };
+  dynamic f2b = #C2;
+  dynamic c2c = f2b{dynamic}.call();
+  self::expect(true, c2c is{ForNonNullableByDefault} self::Class2<core::num>);
+  self::expect(false, c2c is{ForNonNullableByDefault} self::Class2<core::int>);
+  dynamic c2d = f2b{dynamic}.call<core::int>();
+  self::expect(true, c2d is{ForNonNullableByDefault} self::Class2<core::int>);
+  self::expect(false, c2d is{ForNonNullableByDefault} self::Class2<core::double>);
+  self::throws(() → dynamic => f2b{dynamic}.call<core::String>());
+  self::throws(() → dynamic => f2b{dynamic}.call<core::int, core::String>());
+  <T extends S% = dynamic, S extends core::Object? = dynamic>() → self::Class3<T%, S%> f3a = #C3;
+  self::Class3<dynamic, dynamic> c3a = f3a<dynamic, dynamic>(){() → self::Class3<dynamic, dynamic>};
+  self::expect(true, c3a is{ForNonNullableByDefault} self::Class3<dynamic, dynamic>);
+  self::expect(false, c3a is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  self::Class3<core::int, core::num> c3b = f3a<core::int, core::num>(){() → self::Class3<core::int, core::num>};
+  self::expect(true, c3b is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  self::expect(false, c3b is{ForNonNullableByDefault} self::Class3<core::double, core::num>);
+  () → Null {
+    f3a<core::num, core::int>(){() → self::Class3<core::num, core::int>};
+  };
+  dynamic f3b = #C3;
+  dynamic c3c = f3b{dynamic}.call();
+  self::expect(true, c3c is{ForNonNullableByDefault} self::Class3<dynamic, dynamic>);
+  self::expect(false, c3c is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  dynamic c3d = f3b{dynamic}.call<core::int, core::num>();
+  self::expect(true, c3d is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  self::expect(false, c3d is{ForNonNullableByDefault} self::Class3<core::double, core::num>);
+  self::throws(() → dynamic => f3b{dynamic}.call<core::num, core::int>());
+  <T extends self::Class4<T> = self::Class4<dynamic>>() → self::Class4<T> f4a = #C4;
+  () → Null {
+    self::Class4<self::Class4<core::Object?>> c4a = f4a<self::Class4<core::Object?>>(){() → self::Class4<self::Class4<core::Object?>>};
+  };
+  dynamic f4b = #C4;
+  self::throws(() → dynamic => f4b{dynamic}.call());
+  dynamic c4b = f4b{dynamic}.call<self::Class4int>();
+  self::expect(true, c4b is{ForNonNullableByDefault} self::Class4<self::Class4int>);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C5}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = tearoff self::Class1::_#new#tearOff
+  #C2 = tearoff self::Class2::_#new#tearOff
+  #C3 = tearoff self::Class3::_#new#tearOff
+  #C4 = tearoff self::Class4::_#new#tearOff
+  #C5 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..7eeba1a
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+final bool inSoundMode = <int?>[] is! List<int>;
+main() {}
+
+class Class1<T> {}
+
+testGeneric() {}
+
+class Class2<T extends num> {}
+
+class Class3<T extends S, S> {}
+
+class Class4<T extends Class4<T>> {}
+
+class Class4int extends Class4<Class4int> {}
+
+testBounded() {}
+expect(expected, actual) {}
+throws(Function() f, {bool inSoundModeOnly: false}) {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..02d0ff2
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,16 @@
+class Class1<T> {}
+
+class Class2<T extends num> {}
+
+class Class3<T extends S, S> {}
+
+class Class4<T extends Class4<T>> {}
+
+class Class4int extends Class4<Class4int> {}
+
+expect(expected, actual) {}
+final bool inSoundMode = <int?>[] is! List<int>;
+main() {}
+testBounded() {}
+testGeneric() {}
+throws(Function() f, {bool inSoundModeOnly: false}) {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.weak.expect
new file mode 100644
index 0000000..d686ae7
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.weak.expect
@@ -0,0 +1,180 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:24:8: Error: Expected 1 type arguments.
+//     f1a<int, String>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:32:8: Error: Expected 0 type arguments.
+//     f1b<int>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:59:8: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'call'.
+// Try changing type arguments so that they conform to the bounds.
+//     f2a<String>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:60:8: Error: Expected 1 type arguments.
+//     f2a<int, String>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:81:8: Error: Type argument 'num' doesn't conform to the bound 'S' of the type variable 'T' on 'call'.
+// Try changing type arguments so that they conform to the bounds.
+//     f3a<num, int>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:95:18: Error: Inferred type argument 'Class4<Object?>' doesn't conform to the bound 'Class4<T>' of the type variable 'T' on 'call'.
+//  - 'Class4' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     var c4a = f4a(); // error
+//                  ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class1<self::Class1::T%>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends core::Object? = dynamic>() → self::Class1<self::Class1::_#new#tearOff::T%>
+    return new self::Class1::•<self::Class1::_#new#tearOff::T%>();
+}
+class Class2<T extends core::num> extends core::Object {
+  synthetic constructor •() → self::Class2<self::Class2::T>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends core::num>() → self::Class2<self::Class2::_#new#tearOff::T>
+    return new self::Class2::•<self::Class2::_#new#tearOff::T>();
+}
+class Class3<T extends self::Class3::S% = dynamic, S extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class3<self::Class3::T%, self::Class3::S%>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends self::Class3::_#new#tearOff::S% = dynamic, S extends core::Object? = dynamic>() → self::Class3<self::Class3::_#new#tearOff::T%, self::Class3::_#new#tearOff::S%>
+    return new self::Class3::•<self::Class3::_#new#tearOff::T%, self::Class3::_#new#tearOff::S%>();
+}
+class Class4<T extends self::Class4<self::Class4::T> = self::Class4<dynamic>> extends core::Object {
+  synthetic constructor •() → self::Class4<self::Class4::T>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends self::Class4<self::Class4::_#new#tearOff::T> = self::Class4<dynamic>>() → self::Class4<self::Class4::_#new#tearOff::T>
+    return new self::Class4::•<self::Class4::_#new#tearOff::T>();
+}
+class Class4int extends self::Class4<self::Class4int> {
+  synthetic constructor •() → self::Class4int
+    : super self::Class4::•()
+    ;
+  static method _#new#tearOff() → self::Class4int
+    return new self::Class4int::•();
+}
+static final field core::bool inSoundMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testGeneric();
+  self::testBounded();
+}
+static method testGeneric() → dynamic {
+  <T extends core::Object? = dynamic>() → self::Class1<T%> f1a = #C1;
+  self::Class1<dynamic> c1a = f1a<dynamic>(){() → self::Class1<dynamic>};
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1<dynamic>);
+  self::expect(false, c1a is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::Class1<core::int> c1b = f1a<core::int>(){() → self::Class1<core::int>};
+  self::expect(true, c1b is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::expect(false, c1b is{ForNonNullableByDefault} self::Class1<core::String>);
+  () → Null {
+    let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:24:8: Error: Expected 1 type arguments.
+    f1a<int, String>(); // error
+       ^" in f1a{<inapplicable>}.<core::int, core::String>();
+  };
+  () → self::Class1<core::int> f1b = f1a<core::int>;
+  self::Class1<core::int> c1c = f1b(){() → self::Class1<core::int>};
+  self::expect(true, c1c is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::expect(false, c1c is{ForNonNullableByDefault} self::Class1<core::String>);
+  () → Null {
+    let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:32:8: Error: Expected 0 type arguments.
+    f1b<int>(); // error
+       ^" in f1b{<inapplicable>}.<core::int>();
+  };
+  dynamic f1c = #C1;
+  dynamic c1d = f1c{dynamic}.call();
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1<dynamic>);
+  self::expect(false, c1a is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::throws(() → dynamic => f1c{dynamic}.call<core::int, core::String>());
+}
+static method testBounded() → dynamic {
+  <T extends core::num>() → self::Class2<T> f2a = #C2;
+  self::Class2<core::num> c2a = f2a<core::num>(){() → self::Class2<core::num>};
+  self::expect(true, c2a is{ForNonNullableByDefault} self::Class2<core::num>);
+  self::expect(false, c2a is{ForNonNullableByDefault} self::Class2<core::int>);
+  self::Class2<core::int> c2b = f2a<core::int>(){() → self::Class2<core::int>};
+  self::expect(true, c2b is{ForNonNullableByDefault} self::Class2<core::int>);
+  self::expect(false, c2b is{ForNonNullableByDefault} self::Class2<core::double>);
+  () → Null {
+    f2a<core::String>(){() → self::Class2<core::String>};
+    let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:60:8: Error: Expected 1 type arguments.
+    f2a<int, String>(); // error
+       ^" in f2a{<inapplicable>}.<core::int, core::String>();
+  };
+  dynamic f2b = #C2;
+  dynamic c2c = f2b{dynamic}.call();
+  self::expect(true, c2c is{ForNonNullableByDefault} self::Class2<core::num>);
+  self::expect(false, c2c is{ForNonNullableByDefault} self::Class2<core::int>);
+  dynamic c2d = f2b{dynamic}.call<core::int>();
+  self::expect(true, c2d is{ForNonNullableByDefault} self::Class2<core::int>);
+  self::expect(false, c2d is{ForNonNullableByDefault} self::Class2<core::double>);
+  self::throws(() → dynamic => f2b{dynamic}.call<core::String>());
+  self::throws(() → dynamic => f2b{dynamic}.call<core::int, core::String>());
+  <T extends S% = dynamic, S extends core::Object? = dynamic>() → self::Class3<T%, S%> f3a = #C3;
+  self::Class3<dynamic, dynamic> c3a = f3a<dynamic, dynamic>(){() → self::Class3<dynamic, dynamic>};
+  self::expect(true, c3a is{ForNonNullableByDefault} self::Class3<dynamic, dynamic>);
+  self::expect(false, c3a is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  self::Class3<core::int, core::num> c3b = f3a<core::int, core::num>(){() → self::Class3<core::int, core::num>};
+  self::expect(true, c3b is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  self::expect(false, c3b is{ForNonNullableByDefault} self::Class3<core::double, core::num>);
+  () → Null {
+    f3a<core::num, core::int>(){() → self::Class3<core::num, core::int>};
+  };
+  dynamic f3b = #C3;
+  dynamic c3c = f3b{dynamic}.call();
+  self::expect(true, c3c is{ForNonNullableByDefault} self::Class3<dynamic, dynamic>);
+  self::expect(false, c3c is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  dynamic c3d = f3b{dynamic}.call<core::int, core::num>();
+  self::expect(true, c3d is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  self::expect(false, c3d is{ForNonNullableByDefault} self::Class3<core::double, core::num>);
+  self::throws(() → dynamic => f3b{dynamic}.call<core::num, core::int>());
+  <T extends self::Class4<T> = self::Class4<dynamic>>() → self::Class4<T> f4a = #C4;
+  () → Null {
+    self::Class4<self::Class4<core::Object?>> c4a = f4a<self::Class4<core::Object?>>(){() → self::Class4<self::Class4<core::Object?>>};
+  };
+  dynamic f4b = #C4;
+  self::throws(() → dynamic => f4b{dynamic}.call());
+  dynamic c4b = f4b{dynamic}.call<self::Class4int>();
+  self::expect(true, c4b is{ForNonNullableByDefault} self::Class4<self::Class4int>);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C5}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = tearoff self::Class1::_#new#tearOff
+  #C2 = tearoff self::Class2::_#new#tearOff
+  #C3 = tearoff self::Class3::_#new#tearOff
+  #C4 = tearoff self::Class4::_#new#tearOff
+  #C5 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.weak.outline.expect
new file mode 100644
index 0000000..e986061
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.weak.outline.expect
@@ -0,0 +1,45 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class1<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class1<self::Class1::T%>
+    ;
+  static method _#new#tearOff<T extends core::Object? = dynamic>() → self::Class1<self::Class1::_#new#tearOff::T%>
+    return new self::Class1::•<self::Class1::_#new#tearOff::T%>();
+}
+class Class2<T extends core::num> extends core::Object {
+  synthetic constructor •() → self::Class2<self::Class2::T>
+    ;
+  static method _#new#tearOff<T extends core::num>() → self::Class2<self::Class2::_#new#tearOff::T>
+    return new self::Class2::•<self::Class2::_#new#tearOff::T>();
+}
+class Class3<T extends self::Class3::S% = dynamic, S extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class3<self::Class3::T%, self::Class3::S%>
+    ;
+  static method _#new#tearOff<T extends self::Class3::_#new#tearOff::S% = dynamic, S extends core::Object? = dynamic>() → self::Class3<self::Class3::_#new#tearOff::T%, self::Class3::_#new#tearOff::S%>
+    return new self::Class3::•<self::Class3::_#new#tearOff::T%, self::Class3::_#new#tearOff::S%>();
+}
+class Class4<T extends self::Class4<self::Class4::T> = self::Class4<dynamic>> extends core::Object {
+  synthetic constructor •() → self::Class4<self::Class4::T>
+    ;
+  static method _#new#tearOff<T extends self::Class4<self::Class4::_#new#tearOff::T> = self::Class4<dynamic>>() → self::Class4<self::Class4::_#new#tearOff::T>
+    return new self::Class4::•<self::Class4::_#new#tearOff::T>();
+}
+class Class4int extends self::Class4<self::Class4int> {
+  synthetic constructor •() → self::Class4int
+    ;
+  static method _#new#tearOff() → self::Class4int
+    return new self::Class4int::•();
+}
+static final field core::bool inSoundMode;
+static method main() → dynamic
+  ;
+static method testGeneric() → dynamic
+  ;
+static method testBounded() → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
+static method throws(() → dynamic f, {core::bool inSoundModeOnly}) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.weak.transformed.expect
new file mode 100644
index 0000000..d58a81e
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart.weak.transformed.expect
@@ -0,0 +1,180 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:24:8: Error: Expected 1 type arguments.
+//     f1a<int, String>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:32:8: Error: Expected 0 type arguments.
+//     f1b<int>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:59:8: Error: Type argument 'String' doesn't conform to the bound 'num' of the type variable 'T' on 'call'.
+// Try changing type arguments so that they conform to the bounds.
+//     f2a<String>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:60:8: Error: Expected 1 type arguments.
+//     f2a<int, String>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:81:8: Error: Type argument 'num' doesn't conform to the bound 'S' of the type variable 'T' on 'call'.
+// Try changing type arguments so that they conform to the bounds.
+//     f3a<num, int>(); // error
+//        ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:95:18: Error: Inferred type argument 'Class4<Object?>' doesn't conform to the bound 'Class4<T>' of the type variable 'T' on 'call'.
+//  - 'Class4' is from 'pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart'.
+//  - 'Object' is from 'dart:core'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//     var c4a = f4a(); // error
+//                  ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1<T extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class1<self::Class1::T%>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends core::Object? = dynamic>() → self::Class1<self::Class1::_#new#tearOff::T%>
+    return new self::Class1::•<self::Class1::_#new#tearOff::T%>();
+}
+class Class2<T extends core::num> extends core::Object {
+  synthetic constructor •() → self::Class2<self::Class2::T>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends core::num>() → self::Class2<self::Class2::_#new#tearOff::T>
+    return new self::Class2::•<self::Class2::_#new#tearOff::T>();
+}
+class Class3<T extends self::Class3::S% = dynamic, S extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::Class3<self::Class3::T%, self::Class3::S%>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends self::Class3::_#new#tearOff::S% = dynamic, S extends core::Object? = dynamic>() → self::Class3<self::Class3::_#new#tearOff::T%, self::Class3::_#new#tearOff::S%>
+    return new self::Class3::•<self::Class3::_#new#tearOff::T%, self::Class3::_#new#tearOff::S%>();
+}
+class Class4<T extends self::Class4<self::Class4::T> = self::Class4<dynamic>> extends core::Object {
+  synthetic constructor •() → self::Class4<self::Class4::T>
+    : super core::Object::•()
+    ;
+  static method _#new#tearOff<T extends self::Class4<self::Class4::_#new#tearOff::T> = self::Class4<dynamic>>() → self::Class4<self::Class4::_#new#tearOff::T>
+    return new self::Class4::•<self::Class4::_#new#tearOff::T>();
+}
+class Class4int extends self::Class4<self::Class4int> {
+  synthetic constructor •() → self::Class4int
+    : super self::Class4::•()
+    ;
+  static method _#new#tearOff() → self::Class4int
+    return new self::Class4int::•();
+}
+static final field core::bool inSoundMode = !(core::_GrowableList::•<core::int?>(0) is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testGeneric();
+  self::testBounded();
+}
+static method testGeneric() → dynamic {
+  <T extends core::Object? = dynamic>() → self::Class1<T%> f1a = #C1;
+  self::Class1<dynamic> c1a = f1a<dynamic>(){() → self::Class1<dynamic>};
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1<dynamic>);
+  self::expect(false, c1a is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::Class1<core::int> c1b = f1a<core::int>(){() → self::Class1<core::int>};
+  self::expect(true, c1b is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::expect(false, c1b is{ForNonNullableByDefault} self::Class1<core::String>);
+  () → Null {
+    let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:24:8: Error: Expected 1 type arguments.
+    f1a<int, String>(); // error
+       ^" in f1a{<inapplicable>}.<core::int, core::String>();
+  };
+  () → self::Class1<core::int> f1b = f1a<core::int>;
+  self::Class1<core::int> c1c = f1b(){() → self::Class1<core::int>};
+  self::expect(true, c1c is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::expect(false, c1c is{ForNonNullableByDefault} self::Class1<core::String>);
+  () → Null {
+    let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:32:8: Error: Expected 0 type arguments.
+    f1b<int>(); // error
+       ^" in f1b{<inapplicable>}.<core::int>();
+  };
+  dynamic f1c = #C1;
+  dynamic c1d = f1c{dynamic}.call();
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1<dynamic>);
+  self::expect(false, c1a is{ForNonNullableByDefault} self::Class1<core::int>);
+  self::throws(() → dynamic => f1c{dynamic}.call<core::int, core::String>());
+}
+static method testBounded() → dynamic {
+  <T extends core::num>() → self::Class2<T> f2a = #C2;
+  self::Class2<core::num> c2a = f2a<core::num>(){() → self::Class2<core::num>};
+  self::expect(true, c2a is{ForNonNullableByDefault} self::Class2<core::num>);
+  self::expect(false, c2a is{ForNonNullableByDefault} self::Class2<core::int>);
+  self::Class2<core::int> c2b = f2a<core::int>(){() → self::Class2<core::int>};
+  self::expect(true, c2b is{ForNonNullableByDefault} self::Class2<core::int>);
+  self::expect(false, c2b is{ForNonNullableByDefault} self::Class2<core::double>);
+  () → Null {
+    f2a<core::String>(){() → self::Class2<core::String>};
+    let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/generic_constructor_tear_off.dart:60:8: Error: Expected 1 type arguments.
+    f2a<int, String>(); // error
+       ^" in f2a{<inapplicable>}.<core::int, core::String>();
+  };
+  dynamic f2b = #C2;
+  dynamic c2c = f2b{dynamic}.call();
+  self::expect(true, c2c is{ForNonNullableByDefault} self::Class2<core::num>);
+  self::expect(false, c2c is{ForNonNullableByDefault} self::Class2<core::int>);
+  dynamic c2d = f2b{dynamic}.call<core::int>();
+  self::expect(true, c2d is{ForNonNullableByDefault} self::Class2<core::int>);
+  self::expect(false, c2d is{ForNonNullableByDefault} self::Class2<core::double>);
+  self::throws(() → dynamic => f2b{dynamic}.call<core::String>());
+  self::throws(() → dynamic => f2b{dynamic}.call<core::int, core::String>());
+  <T extends S% = dynamic, S extends core::Object? = dynamic>() → self::Class3<T%, S%> f3a = #C3;
+  self::Class3<dynamic, dynamic> c3a = f3a<dynamic, dynamic>(){() → self::Class3<dynamic, dynamic>};
+  self::expect(true, c3a is{ForNonNullableByDefault} self::Class3<dynamic, dynamic>);
+  self::expect(false, c3a is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  self::Class3<core::int, core::num> c3b = f3a<core::int, core::num>(){() → self::Class3<core::int, core::num>};
+  self::expect(true, c3b is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  self::expect(false, c3b is{ForNonNullableByDefault} self::Class3<core::double, core::num>);
+  () → Null {
+    f3a<core::num, core::int>(){() → self::Class3<core::num, core::int>};
+  };
+  dynamic f3b = #C3;
+  dynamic c3c = f3b{dynamic}.call();
+  self::expect(true, c3c is{ForNonNullableByDefault} self::Class3<dynamic, dynamic>);
+  self::expect(false, c3c is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  dynamic c3d = f3b{dynamic}.call<core::int, core::num>();
+  self::expect(true, c3d is{ForNonNullableByDefault} self::Class3<core::int, core::num>);
+  self::expect(false, c3d is{ForNonNullableByDefault} self::Class3<core::double, core::num>);
+  self::throws(() → dynamic => f3b{dynamic}.call<core::num, core::int>());
+  <T extends self::Class4<T> = self::Class4<dynamic>>() → self::Class4<T> f4a = #C4;
+  () → Null {
+    self::Class4<self::Class4<core::Object?>> c4a = f4a<self::Class4<core::Object?>>(){() → self::Class4<self::Class4<core::Object?>>};
+  };
+  dynamic f4b = #C4;
+  self::throws(() → dynamic => f4b{dynamic}.call());
+  dynamic c4b = f4b{dynamic}.call<self::Class4int>();
+  self::expect(true, c4b is{ForNonNullableByDefault} self::Class4<self::Class4int>);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C5}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = tearoff self::Class1::_#new#tearOff
+  #C2 = tearoff self::Class2::_#new#tearOff
+  #C3 = tearoff self::Class3::_#new#tearOff
+  #C4 = tearoff self::Class4::_#new#tearOff
+  #C5 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart
new file mode 100644
index 0000000..fc8cba1
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart
@@ -0,0 +1,73 @@
+// 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.
+
+final bool inSoundMode = <int?>[] is! List<int>;
+
+main() {
+  print('inSoundMode: $inSoundMode');
+  testInferred();
+}
+
+class Class1 {
+  int field;
+
+  Class1(this.field);
+}
+
+abstract class Interface2 {
+  int get field;
+}
+
+class Class2 implements Interface2 {
+  final field;
+
+  Class2(this.field);
+}
+
+testInferred() {
+  var f1a = Class1.new;
+  expect(true, f1a is Class1 Function(int));
+  expect(false, f1a is Class1 Function(String));
+  var c1a = f1a(0);
+  expect(true, c1a is Class1);
+  () {
+    f1a(''); // error
+  };
+
+  dynamic f1b = Class1.new;
+  var c1b = f1b(0);
+  expect(true, c1b is Class1);
+  throws(() => f1b(''));
+
+  var f2a = Class2.new;
+  expect(true, f2a is Class2 Function(int));
+  expect(false, f2a is Class2 Function(String));
+  var c2a = f2a(0);
+  expect(true, c2a is Class2);
+  () {
+    f2a(''); // error
+  };
+
+  dynamic f2b = Class2.new;
+  var c2b = f2b(0);
+  expect(true, c2b is Class2);
+  throws(() => f2b(''));
+}
+
+expect(expected, actual) {
+  if (expected != actual) throw 'Expected $expected, actual $actual';
+}
+
+throws(Function() f, {bool inSoundModeOnly: false}) {
+  try {
+    f();
+  } catch (e) {
+    print('Thrown: $e');
+    return;
+  }
+  if (!inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw 'Expected exception';
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.strong.expect
new file mode 100644
index 0000000..edd7977
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.strong.expect
@@ -0,0 +1,95 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:35:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+//     f1a(''); // error
+//         ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:49:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+//     f2a(''); // error
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  field core::int field;
+  constructor •(core::int field) → self::Class1
+    : self::Class1::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field) → self::Class1
+    return new self::Class1::•(field);
+}
+abstract class Interface2 extends core::Object {
+  synthetic constructor •() → self::Interface2
+    : super core::Object::•()
+    ;
+  abstract get field() → core::int;
+}
+class Class2 extends core::Object implements self::Interface2 {
+  final field core::int field;
+  constructor •(core::int field) → self::Class2
+    : self::Class2::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field) → self::Class2
+    return new self::Class2::•(field);
+}
+static final field core::bool inSoundMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testInferred();
+}
+static method testInferred() → dynamic {
+  (core::int) → self::Class1 f1a = #C1;
+  self::expect(true, f1a is{ForNonNullableByDefault} (core::int) → self::Class1);
+  self::expect(false, f1a is{ForNonNullableByDefault} (core::String) → self::Class1);
+  self::Class1 c1a = f1a(0){(core::int) → self::Class1};
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1);
+  () → Null {
+    f1a(let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:35:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+    f1a(''); // error
+        ^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class1};
+  };
+  dynamic f1b = #C1;
+  dynamic c1b = f1b{dynamic}.call(0);
+  self::expect(true, c1b is{ForNonNullableByDefault} self::Class1);
+  self::throws(() → dynamic => f1b{dynamic}.call(""));
+  (core::int) → self::Class2 f2a = #C2;
+  self::expect(true, f2a is{ForNonNullableByDefault} (core::int) → self::Class2);
+  self::expect(false, f2a is{ForNonNullableByDefault} (core::String) → self::Class2);
+  self::Class2 c2a = f2a(0){(core::int) → self::Class2};
+  self::expect(true, c2a is{ForNonNullableByDefault} self::Class2);
+  () → Null {
+    f2a(let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:49:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+    f2a(''); // error
+        ^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class2};
+  };
+  dynamic f2b = #C2;
+  dynamic c2b = f2b{dynamic}.call(0);
+  self::expect(true, c2b is{ForNonNullableByDefault} self::Class2);
+  self::throws(() → dynamic => f2b{dynamic}.call(""));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C3}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = tearoff self::Class1::_#new#tearOff
+  #C2 = tearoff self::Class2::_#new#tearOff
+  #C3 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.strong.transformed.expect
new file mode 100644
index 0000000..9297490
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.strong.transformed.expect
@@ -0,0 +1,95 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:35:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+//     f1a(''); // error
+//         ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:49:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+//     f2a(''); // error
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  field core::int field;
+  constructor •(core::int field) → self::Class1
+    : self::Class1::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field) → self::Class1
+    return new self::Class1::•(field);
+}
+abstract class Interface2 extends core::Object {
+  synthetic constructor •() → self::Interface2
+    : super core::Object::•()
+    ;
+  abstract get field() → core::int;
+}
+class Class2 extends core::Object implements self::Interface2 {
+  final field core::int field;
+  constructor •(core::int field) → self::Class2
+    : self::Class2::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field) → self::Class2
+    return new self::Class2::•(field);
+}
+static final field core::bool inSoundMode = !(core::_GrowableList::•<core::int?>(0) is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testInferred();
+}
+static method testInferred() → dynamic {
+  (core::int) → self::Class1 f1a = #C1;
+  self::expect(true, f1a is{ForNonNullableByDefault} (core::int) → self::Class1);
+  self::expect(false, f1a is{ForNonNullableByDefault} (core::String) → self::Class1);
+  self::Class1 c1a = f1a(0){(core::int) → self::Class1};
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1);
+  () → Null {
+    f1a(let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:35:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+    f1a(''); // error
+        ^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class1};
+  };
+  dynamic f1b = #C1;
+  dynamic c1b = f1b{dynamic}.call(0);
+  self::expect(true, c1b is{ForNonNullableByDefault} self::Class1);
+  self::throws(() → dynamic => f1b{dynamic}.call(""));
+  (core::int) → self::Class2 f2a = #C2;
+  self::expect(true, f2a is{ForNonNullableByDefault} (core::int) → self::Class2);
+  self::expect(false, f2a is{ForNonNullableByDefault} (core::String) → self::Class2);
+  self::Class2 c2a = f2a(0){(core::int) → self::Class2};
+  self::expect(true, c2a is{ForNonNullableByDefault} self::Class2);
+  () → Null {
+    f2a(let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:49:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+    f2a(''); // error
+        ^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class2};
+  };
+  dynamic f2b = #C2;
+  dynamic c2b = f2b{dynamic}.call(0);
+  self::expect(true, c2b is{ForNonNullableByDefault} self::Class2);
+  self::throws(() → dynamic => f2b{dynamic}.call(""));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C3}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = tearoff self::Class1::_#new#tearOff
+  #C2 = tearoff self::Class2::_#new#tearOff
+  #C3 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.textual_outline.expect
new file mode 100644
index 0000000..9e086db
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.textual_outline.expect
@@ -0,0 +1,20 @@
+final bool inSoundMode = <int?>[] is! List<int>;
+main() {}
+
+class Class1 {
+  int field;
+  Class1(this.field);
+}
+
+abstract class Interface2 {
+  int get field;
+}
+
+class Class2 implements Interface2 {
+  final field;
+  Class2(this.field);
+}
+
+testInferred() {}
+expect(expected, actual) {}
+throws(Function() f, {bool inSoundModeOnly: false}) {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..8944ae7
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.textual_outline_modelled.expect
@@ -0,0 +1,19 @@
+abstract class Interface2 {
+  int get field;
+}
+
+class Class1 {
+  Class1(this.field);
+  int field;
+}
+
+class Class2 implements Interface2 {
+  Class2(this.field);
+  final field;
+}
+
+expect(expected, actual) {}
+final bool inSoundMode = <int?>[] is! List<int>;
+main() {}
+testInferred() {}
+throws(Function() f, {bool inSoundModeOnly: false}) {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.expect
new file mode 100644
index 0000000..edd7977
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.expect
@@ -0,0 +1,95 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:35:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+//     f1a(''); // error
+//         ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:49:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+//     f2a(''); // error
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  field core::int field;
+  constructor •(core::int field) → self::Class1
+    : self::Class1::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field) → self::Class1
+    return new self::Class1::•(field);
+}
+abstract class Interface2 extends core::Object {
+  synthetic constructor •() → self::Interface2
+    : super core::Object::•()
+    ;
+  abstract get field() → core::int;
+}
+class Class2 extends core::Object implements self::Interface2 {
+  final field core::int field;
+  constructor •(core::int field) → self::Class2
+    : self::Class2::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field) → self::Class2
+    return new self::Class2::•(field);
+}
+static final field core::bool inSoundMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testInferred();
+}
+static method testInferred() → dynamic {
+  (core::int) → self::Class1 f1a = #C1;
+  self::expect(true, f1a is{ForNonNullableByDefault} (core::int) → self::Class1);
+  self::expect(false, f1a is{ForNonNullableByDefault} (core::String) → self::Class1);
+  self::Class1 c1a = f1a(0){(core::int) → self::Class1};
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1);
+  () → Null {
+    f1a(let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:35:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+    f1a(''); // error
+        ^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class1};
+  };
+  dynamic f1b = #C1;
+  dynamic c1b = f1b{dynamic}.call(0);
+  self::expect(true, c1b is{ForNonNullableByDefault} self::Class1);
+  self::throws(() → dynamic => f1b{dynamic}.call(""));
+  (core::int) → self::Class2 f2a = #C2;
+  self::expect(true, f2a is{ForNonNullableByDefault} (core::int) → self::Class2);
+  self::expect(false, f2a is{ForNonNullableByDefault} (core::String) → self::Class2);
+  self::Class2 c2a = f2a(0){(core::int) → self::Class2};
+  self::expect(true, c2a is{ForNonNullableByDefault} self::Class2);
+  () → Null {
+    f2a(let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:49:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+    f2a(''); // error
+        ^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class2};
+  };
+  dynamic f2b = #C2;
+  dynamic c2b = f2b{dynamic}.call(0);
+  self::expect(true, c2b is{ForNonNullableByDefault} self::Class2);
+  self::throws(() → dynamic => f2b{dynamic}.call(""));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C3}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = tearoff self::Class1::_#new#tearOff
+  #C2 = tearoff self::Class2::_#new#tearOff
+  #C3 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.outline.expect
new file mode 100644
index 0000000..802525c
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.outline.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  field core::int field;
+  constructor •(core::int field) → self::Class1
+    ;
+  static method _#new#tearOff(core::int field) → self::Class1
+    return new self::Class1::•(field);
+}
+abstract class Interface2 extends core::Object {
+  synthetic constructor •() → self::Interface2
+    ;
+  abstract get field() → core::int;
+}
+class Class2 extends core::Object implements self::Interface2 {
+  final field core::int field;
+  constructor •(core::int field) → self::Class2
+    ;
+  static method _#new#tearOff(core::int field) → self::Class2
+    return new self::Class2::•(field);
+}
+static final field core::bool inSoundMode;
+static method main() → dynamic
+  ;
+static method testInferred() → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
+static method throws(() → dynamic f, {core::bool inSoundModeOnly}) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.transformed.expect
new file mode 100644
index 0000000..9297490
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart.weak.transformed.expect
@@ -0,0 +1,95 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:35:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+//     f1a(''); // error
+//         ^
+//
+// pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:49:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+//     f2a(''); // error
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+  field core::int field;
+  constructor •(core::int field) → self::Class1
+    : self::Class1::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field) → self::Class1
+    return new self::Class1::•(field);
+}
+abstract class Interface2 extends core::Object {
+  synthetic constructor •() → self::Interface2
+    : super core::Object::•()
+    ;
+  abstract get field() → core::int;
+}
+class Class2 extends core::Object implements self::Interface2 {
+  final field core::int field;
+  constructor •(core::int field) → self::Class2
+    : self::Class2::field = field, super core::Object::•()
+    ;
+  static method _#new#tearOff(core::int field) → self::Class2
+    return new self::Class2::•(field);
+}
+static final field core::bool inSoundMode = !(core::_GrowableList::•<core::int?>(0) is{ForNonNullableByDefault} core::List<core::int>);
+static method main() → dynamic {
+  core::print("inSoundMode: ${self::inSoundMode}");
+  self::testInferred();
+}
+static method testInferred() → dynamic {
+  (core::int) → self::Class1 f1a = #C1;
+  self::expect(true, f1a is{ForNonNullableByDefault} (core::int) → self::Class1);
+  self::expect(false, f1a is{ForNonNullableByDefault} (core::String) → self::Class1);
+  self::Class1 c1a = f1a(0){(core::int) → self::Class1};
+  self::expect(true, c1a is{ForNonNullableByDefault} self::Class1);
+  () → Null {
+    f1a(let final Never #t1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:35:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+    f1a(''); // error
+        ^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class1};
+  };
+  dynamic f1b = #C1;
+  dynamic c1b = f1b{dynamic}.call(0);
+  self::expect(true, c1b is{ForNonNullableByDefault} self::Class1);
+  self::throws(() → dynamic => f1b{dynamic}.call(""));
+  (core::int) → self::Class2 f2a = #C2;
+  self::expect(true, f2a is{ForNonNullableByDefault} (core::int) → self::Class2);
+  self::expect(false, f2a is{ForNonNullableByDefault} (core::String) → self::Class2);
+  self::Class2 c2a = f2a(0){(core::int) → self::Class2};
+  self::expect(true, c2a is{ForNonNullableByDefault} self::Class2);
+  () → Null {
+    f2a(let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_constructor_tear_off.dart:49:9: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+    f2a(''); // error
+        ^" in "" as{TypeError,ForNonNullableByDefault} core::int){(core::int) → self::Class2};
+  };
+  dynamic f2b = #C2;
+  dynamic c2b = f2b{dynamic}.call(0);
+  self::expect(true, c2b is{ForNonNullableByDefault} self::Class2);
+  self::throws(() → dynamic => f2b{dynamic}.call(""));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, {core::bool inSoundModeOnly = #C3}) → dynamic {
+  try {
+    f(){() → dynamic};
+  }
+  on core::Object catch(final core::Object e) {
+    core::print("Thrown: ${e}");
+    return;
+  }
+  if(!self::inSoundMode && inSoundModeOnly) {
+    return;
+  }
+  throw "Expected exception";
+}
+
+constants  {
+  #C1 = tearoff self::Class1::_#new#tearOff
+  #C2 = tearoff self::Class2::_#new#tearOff
+  #C3 = false
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.strong.expect
index 66b9517..c87e29d 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.strong.expect
@@ -7,13 +7,10 @@
 // A Function() test2() => A.foo2; // Error.
 //                         ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:13:27: Error: Getter not found: 'new'.
-// A Function() test3() => A.new; // Ok.
-//                           ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:30: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:28: Error: A value of type 'A Function()' can't be returned from a function with return type 'A Function(int)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart'.
 // A Function(int) test4() => A.new; // Error.
-//                              ^^^
+//                            ^
 //
 import self as self;
 import "dart:core" as core;
@@ -34,11 +31,10 @@
 A Function() test2() => A.foo2; // Error.
                         ^" in self::A::foo2 as{TypeError,ForNonNullableByDefault} () → self::A;
 static method test3() → () → self::A
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:13:27: Error: Getter not found: 'new'.
-A Function() test3() => A.new; // Ok.
-                          ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} () → self::A;
+  return self::A::•;
 static method test4() → (core::int) → self::A
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:30: Error: Getter not found: 'new'.
+  return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:28: Error: A value of type 'A Function()' can't be returned from a function with return type 'A Function(int)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart'.
 A Function(int) test4() => A.new; // Error.
-                             ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} (core::int) → self::A;
+                           ^" in self::A::• as{TypeError,ForNonNullableByDefault} (core::int) → self::A;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.strong.transformed.expect
index 3a31a79..c87e29d 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.strong.transformed.expect
@@ -7,13 +7,10 @@
 // A Function() test2() => A.foo2; // Error.
 //                         ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:13:27: Error: Getter not found: 'new'.
-// A Function() test3() => A.new; // Ok.
-//                           ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:30: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:28: Error: A value of type 'A Function()' can't be returned from a function with return type 'A Function(int)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart'.
 // A Function(int) test4() => A.new; // Error.
-//                              ^^^
+//                            ^
 //
 import self as self;
 import "dart:core" as core;
@@ -34,11 +31,10 @@
 A Function() test2() => A.foo2; // Error.
                         ^" in self::A::foo2 as{TypeError,ForNonNullableByDefault} () → self::A;
 static method test3() → () → self::A
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:13:27: Error: Getter not found: 'new'.
-A Function() test3() => A.new; // Ok.
-                          ^^^";
+  return self::A::•;
 static method test4() → (core::int) → self::A
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:30: Error: Getter not found: 'new'.
+  return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:28: Error: A value of type 'A Function()' can't be returned from a function with return type 'A Function(int)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart'.
 A Function(int) test4() => A.new; // Error.
-                             ^^^";
+                           ^" in self::A::• as{TypeError,ForNonNullableByDefault} (core::int) → self::A;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.weak.expect
index 66b9517..c87e29d 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.weak.expect
@@ -7,13 +7,10 @@
 // A Function() test2() => A.foo2; // Error.
 //                         ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:13:27: Error: Getter not found: 'new'.
-// A Function() test3() => A.new; // Ok.
-//                           ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:30: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:28: Error: A value of type 'A Function()' can't be returned from a function with return type 'A Function(int)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart'.
 // A Function(int) test4() => A.new; // Error.
-//                              ^^^
+//                            ^
 //
 import self as self;
 import "dart:core" as core;
@@ -34,11 +31,10 @@
 A Function() test2() => A.foo2; // Error.
                         ^" in self::A::foo2 as{TypeError,ForNonNullableByDefault} () → self::A;
 static method test3() → () → self::A
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:13:27: Error: Getter not found: 'new'.
-A Function() test3() => A.new; // Ok.
-                          ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} () → self::A;
+  return self::A::•;
 static method test4() → (core::int) → self::A
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:30: Error: Getter not found: 'new'.
+  return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:28: Error: A value of type 'A Function()' can't be returned from a function with return type 'A Function(int)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart'.
 A Function(int) test4() => A.new; // Error.
-                             ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} (core::int) → self::A;
+                           ^" in self::A::• as{TypeError,ForNonNullableByDefault} (core::int) → self::A;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.weak.transformed.expect
index 3a31a79..c87e29d 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart.weak.transformed.expect
@@ -7,13 +7,10 @@
 // A Function() test2() => A.foo2; // Error.
 //                         ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:13:27: Error: Getter not found: 'new'.
-// A Function() test3() => A.new; // Ok.
-//                           ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:30: Error: Getter not found: 'new'.
+// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:28: Error: A value of type 'A Function()' can't be returned from a function with return type 'A Function(int)'.
+//  - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart'.
 // A Function(int) test4() => A.new; // Error.
-//                              ^^^
+//                            ^
 //
 import self as self;
 import "dart:core" as core;
@@ -34,11 +31,10 @@
 A Function() test2() => A.foo2; // Error.
                         ^" in self::A::foo2 as{TypeError,ForNonNullableByDefault} () → self::A;
 static method test3() → () → self::A
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:13:27: Error: Getter not found: 'new'.
-A Function() test3() => A.new; // Ok.
-                          ^^^";
+  return self::A::•;
 static method test4() → (core::int) → self::A
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:30: Error: Getter not found: 'new'.
+  return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart:14:28: Error: A value of type 'A Function()' can't be returned from a function with return type 'A Function(int)'.
+ - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_with_context.dart'.
 A Function(int) test4() => A.new; // Error.
-                             ^^^";
+                           ^" in self::A::• as{TypeError,ForNonNullableByDefault} (core::int) → self::A;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.strong.expect
index 58372ea..c89079b 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.strong.expect
@@ -1,15 +1,4 @@
 library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:11:16: Error: Getter not found: 'new'.
-// testNew() => A.new; // Ok.
-//                ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:14:30: Error: Getter not found: 'new'.
-// testNewExtraArgs() => A<int>.new; // Error.
-//                              ^^^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -22,13 +11,9 @@
 static method testFoo() → dynamic
   return self::A::foo;
 static method testNew() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:11:16: Error: Getter not found: 'new'.
-testNew() => A.new; // Ok.
-               ^^^";
+  return self::A::•;
 static method testFooExtraArgs() → dynamic
   return self::A::foo;
 static method testNewExtraArgs() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:14:30: Error: Getter not found: 'new'.
-testNewExtraArgs() => A<int>.new; // Error.
-                             ^^^";
+  return self::A::•;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.strong.transformed.expect
index 58372ea..c89079b 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.strong.transformed.expect
@@ -1,15 +1,4 @@
 library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:11:16: Error: Getter not found: 'new'.
-// testNew() => A.new; // Ok.
-//                ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:14:30: Error: Getter not found: 'new'.
-// testNewExtraArgs() => A<int>.new; // Error.
-//                              ^^^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -22,13 +11,9 @@
 static method testFoo() → dynamic
   return self::A::foo;
 static method testNew() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:11:16: Error: Getter not found: 'new'.
-testNew() => A.new; // Ok.
-               ^^^";
+  return self::A::•;
 static method testFooExtraArgs() → dynamic
   return self::A::foo;
 static method testNewExtraArgs() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:14:30: Error: Getter not found: 'new'.
-testNewExtraArgs() => A<int>.new; // Error.
-                             ^^^";
+  return self::A::•;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.weak.expect
index 58372ea..c89079b 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.weak.expect
@@ -1,15 +1,4 @@
 library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:11:16: Error: Getter not found: 'new'.
-// testNew() => A.new; // Ok.
-//                ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:14:30: Error: Getter not found: 'new'.
-// testNewExtraArgs() => A<int>.new; // Error.
-//                              ^^^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -22,13 +11,9 @@
 static method testFoo() → dynamic
   return self::A::foo;
 static method testNew() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:11:16: Error: Getter not found: 'new'.
-testNew() => A.new; // Ok.
-               ^^^";
+  return self::A::•;
 static method testFooExtraArgs() → dynamic
   return self::A::foo;
 static method testNewExtraArgs() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:14:30: Error: Getter not found: 'new'.
-testNewExtraArgs() => A<int>.new; // Error.
-                             ^^^";
+  return self::A::•;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.weak.transformed.expect
index 58372ea..c89079b 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart.weak.transformed.expect
@@ -1,15 +1,4 @@
 library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:11:16: Error: Getter not found: 'new'.
-// testNew() => A.new; // Ok.
-//                ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:14:30: Error: Getter not found: 'new'.
-// testNewExtraArgs() => A<int>.new; // Error.
-//                              ^^^
-//
 import self as self;
 import "dart:core" as core;
 
@@ -22,13 +11,9 @@
 static method testFoo() → dynamic
   return self::A::foo;
 static method testNew() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:11:16: Error: Getter not found: 'new'.
-testNew() => A.new; // Ok.
-               ^^^";
+  return self::A::•;
 static method testFooExtraArgs() → dynamic
   return self::A::foo;
 static method testNewExtraArgs() → dynamic
-  return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/nongeneric_tearoff_without_context.dart:14:30: Error: Getter not found: 'new'.
-testNewExtraArgs() => A<int>.new; // Error.
-                             ^^^";
+  return self::A::•;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.strong.expect
index 93e586a..145140e 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.strong.expect
@@ -17,9 +17,9 @@
 //   factory A.redirectingFactoryChild() = B.new;
 //                                           ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart:8:41: Error: Redirection constructor target not found: 'B.new'
-//   factory A.redirectingFactoryChild() = B.new;
-//                                         ^
+// pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart:7:36: Error: Redirection constructor target not found: 'A.new'
+//   factory A.redirectingFactory() = A.new;
+//                                    ^
 //
 // pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart:15:23: Error: Getter not found: 'redirectingFactory'.
 //   A Function() f1 = A.redirectingFactory;
@@ -50,9 +50,9 @@
     : super core::Object::•()
     ;
   static factory redirectingFactory() → self::A
-    let dynamic #redirecting_factory = self::A::new in invalid-expression;
+    let dynamic #redirecting_factory = "A.new" in invalid-expression;
   static factory redirectingFactoryChild() → self::A
-    let dynamic #redirecting_factory = "B.new" in invalid-expression;
+    let dynamic #redirecting_factory = self::B::• in invalid-expression;
   static factory redirectingTwice() → self::A
     let dynamic #redirecting_factory = self::A::redirectingFactory in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.strong.transformed.expect
index dbc8412..943d69c 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.strong.transformed.expect
@@ -17,9 +17,9 @@
 //   factory A.redirectingFactoryChild() = B.new;
 //                                           ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart:8:41: Error: Redirection constructor target not found: 'B.new'
-//   factory A.redirectingFactoryChild() = B.new;
-//                                         ^
+// pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart:7:36: Error: Redirection constructor target not found: 'A.new'
+//   factory A.redirectingFactory() = A.new;
+//                                    ^
 //
 // pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart:15:23: Error: Getter not found: 'redirectingFactory'.
 //   A Function() f1 = A.redirectingFactory;
@@ -50,9 +50,9 @@
     : super core::Object::•()
     ;
   static factory redirectingFactory() → self::A
-    let Never #redirecting_factory = self::A::new in invalid-expression;
+    let core::String* #redirecting_factory = "A.new" in invalid-expression;
   static factory redirectingFactoryChild() → self::A
-    let core::String* #redirecting_factory = "B.new" in invalid-expression;
+    let Never #redirecting_factory = self::B::• in invalid-expression;
   static factory redirectingTwice() → self::A
     let () → self::A #redirecting_factory = self::A::redirectingFactory in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.weak.expect
index 93e586a..145140e 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.weak.expect
@@ -17,9 +17,9 @@
 //   factory A.redirectingFactoryChild() = B.new;
 //                                           ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart:8:41: Error: Redirection constructor target not found: 'B.new'
-//   factory A.redirectingFactoryChild() = B.new;
-//                                         ^
+// pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart:7:36: Error: Redirection constructor target not found: 'A.new'
+//   factory A.redirectingFactory() = A.new;
+//                                    ^
 //
 // pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart:15:23: Error: Getter not found: 'redirectingFactory'.
 //   A Function() f1 = A.redirectingFactory;
@@ -50,9 +50,9 @@
     : super core::Object::•()
     ;
   static factory redirectingFactory() → self::A
-    let dynamic #redirecting_factory = self::A::new in invalid-expression;
+    let dynamic #redirecting_factory = "A.new" in invalid-expression;
   static factory redirectingFactoryChild() → self::A
-    let dynamic #redirecting_factory = "B.new" in invalid-expression;
+    let dynamic #redirecting_factory = self::B::• in invalid-expression;
   static factory redirectingTwice() → self::A
     let dynamic #redirecting_factory = self::A::redirectingFactory in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.weak.outline.expect
index a8e0129..b9415d3 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.weak.outline.expect
@@ -17,9 +17,9 @@
 //   factory A.redirectingFactoryChild() = B.new;
 //                                           ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart:8:41: Error: Redirection constructor target not found: 'B.new'
-//   factory A.redirectingFactoryChild() = B.new;
-//                                         ^
+// pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart:7:36: Error: Redirection constructor target not found: 'A.new'
+//   factory A.redirectingFactory() = A.new;
+//                                    ^
 //
 import self as self;
 import "dart:core" as core;
@@ -29,9 +29,9 @@
   constructor new() → self::A
     ;
   static factory redirectingFactory() → self::A
-    let dynamic #redirecting_factory = self::A::new in invalid-expression;
+    let dynamic #redirecting_factory = "A.new" in invalid-expression;
   static factory redirectingFactoryChild() → self::A
-    let dynamic #redirecting_factory = "B.new" in invalid-expression;
+    let dynamic #redirecting_factory = self::B::• in invalid-expression;
   static factory redirectingTwice() → self::A
     let dynamic #redirecting_factory = self::A::redirectingFactory in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.weak.transformed.expect
index dbc8412..943d69c 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart.weak.transformed.expect
@@ -17,9 +17,9 @@
 //   factory A.redirectingFactoryChild() = B.new;
 //                                           ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart:8:41: Error: Redirection constructor target not found: 'B.new'
-//   factory A.redirectingFactoryChild() = B.new;
-//                                         ^
+// pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart:7:36: Error: Redirection constructor target not found: 'A.new'
+//   factory A.redirectingFactory() = A.new;
+//                                    ^
 //
 // pkg/front_end/testcases/constructor_tearoffs/redirecting_constructors.dart:15:23: Error: Getter not found: 'redirectingFactory'.
 //   A Function() f1 = A.redirectingFactory;
@@ -50,9 +50,9 @@
     : super core::Object::•()
     ;
   static factory redirectingFactory() → self::A
-    let Never #redirecting_factory = self::A::new in invalid-expression;
+    let core::String* #redirecting_factory = "A.new" in invalid-expression;
   static factory redirectingFactoryChild() → self::A
-    let core::String* #redirecting_factory = "B.new" in invalid-expression;
+    let Never #redirecting_factory = self::B::• in invalid-expression;
   static factory redirectingTwice() → self::A
     let () → self::A #redirecting_factory = self::A::redirectingFactory in invalid-expression;
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.strong.expect
index 0a35e7f..74eb491 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.strong.expect
@@ -36,89 +36,38 @@
 //   D(int x) : super.new(x * 2);
 //                    ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:8:41: Error: Redirection constructor target not found: 'B.new'
-//   factory A.redirectingFactoryChild() = B.new;
-//                                         ^
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:7:36: Error: Redirection constructor target not found: 'A.new'
+//   factory A.redirectingFactory() = A.new;
+//                                    ^
 //
 // pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:20:14: Error: Superclass has no constructor named 'Object.new'.
 //   D(int x) : super.new(x * 2);
 //              ^^^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:24:5: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   D.new(1);
-//     ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:24:5: Error: Method not found: 'D.new'.
-//   D.new(1);
-//     ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:25:11: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:25:11: Error: Method not found: 'C.new'.
 //   const C.new(1);
 //           ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:26:9: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:26:9: Error: Method not found: 'C.new'.
 //   new C.new(1);
 //         ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:28:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:28:14: Error: Getter not found: 'new'.
 //   var f1 = A.new;
 //              ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:29:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   var f2 = B.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:29:14: Error: Getter not found: 'new'.
-//   var f2 = B.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:30:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:30:14: Error: Getter not found: 'new'.
 //   var f3 = C.new;
 //              ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:31:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   var f4 = D.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:31:14: Error: Getter not found: 'new'.
-//   var f4 = D.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:37:23: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:37:23: Error: Getter not found: 'new'.
 //   A Function() g1 = A.new;
 //                       ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:38:23: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   B Function() g2 = B.new;
-//                       ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:38:23: Error: Getter not found: 'new'.
-//   B Function() g2 = B.new;
-//                       ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:39:28: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:39:28: Error: Getter not found: 'new'.
 //   C Function(int x) g3 = C.new;
 //                            ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:40:28: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   D Function(int x) g4 = D.new;
-//                            ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:40:28: Error: Getter not found: 'new'.
-//   D Function(int x) g4 = D.new;
-//                            ^^^
-//
 // pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:12:7: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
 // class B extends A {}
 //       ^
@@ -135,9 +84,9 @@
     : this self::A::new()
     ;
   static factory redirectingFactory() → self::A
-    let dynamic #redirecting_factory = self::A::new in invalid-expression;
+    let dynamic #redirecting_factory = "A.new" in invalid-expression;
   static factory redirectingFactoryChild() → self::A
-    let dynamic #redirecting_factory = "B.new" in invalid-expression;
+    let dynamic #redirecting_factory = self::B::• in invalid-expression;
 }
 class B extends self::A {
   synthetic constructor •() → self::B
@@ -158,45 +107,36 @@
     ;
 }
 static method test() → dynamic {
-  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:24:5: Error: Method not found: 'D.new'.
-  D.new(1);
-    ^^^";
-  #C2;
-  new self::C::new(1);
-  () → self::A f1 = self::A::new;
-  dynamic f2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:29:14: Error: Getter not found: 'new'.
-  var f2 = B.new;
+  new self::D::•(1);
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:25:11: Error: Method not found: 'C.new'.
+  const C.new(1);
+          ^^^";
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:26:9: Error: Method not found: 'C.new'.
+  new C.new(1);
+        ^^^";
+  dynamic f1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:28:14: Error: Getter not found: 'new'.
+  var f1 = A.new;
              ^^^";
-  (core::int) → self::C f3 = self::C::new;
-  dynamic f4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:31:14: Error: Getter not found: 'new'.
-  var f4 = D.new;
+  () → self::B f2 = self::B::•;
+  dynamic f3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:30:14: Error: Getter not found: 'new'.
+  var f3 = C.new;
              ^^^";
-  f1(){() → self::A};
-  f2{dynamic}.call();
-  f3(1){(core::int) → self::C};
-  f4{dynamic}.call(1);
-  () → self::A g1 = self::A::new;
-  () → self::B g2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:38:23: Error: Getter not found: 'new'.
-  B Function() g2 = B.new;
-                      ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} () → self::B;
-  (core::int) → self::C g3 = self::C::new;
-  (core::int) → self::D g4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:40:28: Error: Getter not found: 'new'.
-  D Function(int x) g4 = D.new;
-                           ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} (core::int) → self::D;
+  (core::int) → self::D f4 = self::D::•;
+  f1{dynamic}.call();
+  f2(){() → self::B};
+  f3{dynamic}.call(1);
+  f4(1){(core::int) → self::D};
+  () → self::A g1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:37:23: Error: Getter not found: 'new'.
+  A Function() g1 = A.new;
+                      ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} () → self::A;
+  () → self::B g2 = self::B::•;
+  (core::int) → self::C g3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:39:28: Error: Getter not found: 'new'.
+  C Function(int x) g3 = C.new;
+                           ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} (core::int) → self::C;
+  (core::int) → self::D g4 = self::D::•;
   g1(){() → self::A};
   g2(){() → self::B};
   g3(1){(core::int) → self::C};
   g4(1){(core::int) → self::D};
 }
 static method main() → dynamic {}
-
-constants  {
-  #C1 = 1
-  #C2 = self::C {x:#C1}
-}
-
-
-Constructor coverage from constants:
-org-dartlang-testcase:///unnamed_constructor.dart:
-- C.new (from org-dartlang-testcase:///unnamed_constructor.dart:16:9)
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.strong.transformed.expect
index 77763cb..5779400 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.strong.transformed.expect
@@ -36,89 +36,38 @@
 //   D(int x) : super.new(x * 2);
 //                    ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:8:41: Error: Redirection constructor target not found: 'B.new'
-//   factory A.redirectingFactoryChild() = B.new;
-//                                         ^
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:7:36: Error: Redirection constructor target not found: 'A.new'
+//   factory A.redirectingFactory() = A.new;
+//                                    ^
 //
 // pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:20:14: Error: Superclass has no constructor named 'Object.new'.
 //   D(int x) : super.new(x * 2);
 //              ^^^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:24:5: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   D.new(1);
-//     ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:24:5: Error: Method not found: 'D.new'.
-//   D.new(1);
-//     ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:25:11: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:25:11: Error: Method not found: 'C.new'.
 //   const C.new(1);
 //           ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:26:9: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:26:9: Error: Method not found: 'C.new'.
 //   new C.new(1);
 //         ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:28:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:28:14: Error: Getter not found: 'new'.
 //   var f1 = A.new;
 //              ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:29:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   var f2 = B.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:29:14: Error: Getter not found: 'new'.
-//   var f2 = B.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:30:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:30:14: Error: Getter not found: 'new'.
 //   var f3 = C.new;
 //              ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:31:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   var f4 = D.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:31:14: Error: Getter not found: 'new'.
-//   var f4 = D.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:37:23: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:37:23: Error: Getter not found: 'new'.
 //   A Function() g1 = A.new;
 //                       ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:38:23: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   B Function() g2 = B.new;
-//                       ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:38:23: Error: Getter not found: 'new'.
-//   B Function() g2 = B.new;
-//                       ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:39:28: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:39:28: Error: Getter not found: 'new'.
 //   C Function(int x) g3 = C.new;
 //                            ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:40:28: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   D Function(int x) g4 = D.new;
-//                            ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:40:28: Error: Getter not found: 'new'.
-//   D Function(int x) g4 = D.new;
-//                            ^^^
-//
 // pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:12:7: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
 // class B extends A {}
 //       ^
@@ -135,9 +84,9 @@
     : this self::A::new()
     ;
   static factory redirectingFactory() → self::A
-    let Never #redirecting_factory = self::A::new in invalid-expression;
+    let core::String* #redirecting_factory = "A.new" in invalid-expression;
   static factory redirectingFactoryChild() → self::A
-    let core::String* #redirecting_factory = "B.new" in invalid-expression;
+    let Never #redirecting_factory = self::B::• in invalid-expression;
 }
 class B extends self::A {
   synthetic constructor •() → self::B
@@ -158,45 +107,36 @@
     ;
 }
 static method test() → dynamic {
-  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:24:5: Error: Method not found: 'D.new'.
-  D.new(1);
-    ^^^";
-  #C2;
-  new self::C::new(1);
-  () → self::A f1 = self::A::new;
-  dynamic f2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:29:14: Error: Getter not found: 'new'.
-  var f2 = B.new;
+  new self::D::•(1);
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:25:11: Error: Method not found: 'C.new'.
+  const C.new(1);
+          ^^^";
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:26:9: Error: Method not found: 'C.new'.
+  new C.new(1);
+        ^^^";
+  dynamic f1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:28:14: Error: Getter not found: 'new'.
+  var f1 = A.new;
              ^^^";
-  (core::int) → self::C f3 = self::C::new;
-  dynamic f4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:31:14: Error: Getter not found: 'new'.
-  var f4 = D.new;
+  () → self::B f2 = self::B::•;
+  dynamic f3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:30:14: Error: Getter not found: 'new'.
+  var f3 = C.new;
              ^^^";
-  f1(){() → self::A};
-  f2{dynamic}.call();
-  f3(1){(core::int) → self::C};
-  f4{dynamic}.call(1);
-  () → self::A g1 = self::A::new;
-  () → self::B g2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:38:23: Error: Getter not found: 'new'.
-  B Function() g2 = B.new;
+  (core::int) → self::D f4 = self::D::•;
+  f1{dynamic}.call();
+  f2(){() → self::B};
+  f3{dynamic}.call(1);
+  f4(1){(core::int) → self::D};
+  () → self::A g1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:37:23: Error: Getter not found: 'new'.
+  A Function() g1 = A.new;
                       ^^^";
-  (core::int) → self::C g3 = self::C::new;
-  (core::int) → self::D g4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:40:28: Error: Getter not found: 'new'.
-  D Function(int x) g4 = D.new;
+  () → self::B g2 = self::B::•;
+  (core::int) → self::C g3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:39:28: Error: Getter not found: 'new'.
+  C Function(int x) g3 = C.new;
                            ^^^";
+  (core::int) → self::D g4 = self::D::•;
   g1(){() → self::A};
   g2(){() → self::B};
   g3(1){(core::int) → self::C};
   g4(1){(core::int) → self::D};
 }
 static method main() → dynamic {}
-
-constants  {
-  #C1 = 1
-  #C2 = self::C {x:#C1}
-}
-
-
-Constructor coverage from constants:
-org-dartlang-testcase:///unnamed_constructor.dart:
-- C.new (from org-dartlang-testcase:///unnamed_constructor.dart:16:9)
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.weak.expect
index 0a35e7f..74eb491 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.weak.expect
@@ -36,89 +36,38 @@
 //   D(int x) : super.new(x * 2);
 //                    ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:8:41: Error: Redirection constructor target not found: 'B.new'
-//   factory A.redirectingFactoryChild() = B.new;
-//                                         ^
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:7:36: Error: Redirection constructor target not found: 'A.new'
+//   factory A.redirectingFactory() = A.new;
+//                                    ^
 //
 // pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:20:14: Error: Superclass has no constructor named 'Object.new'.
 //   D(int x) : super.new(x * 2);
 //              ^^^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:24:5: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   D.new(1);
-//     ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:24:5: Error: Method not found: 'D.new'.
-//   D.new(1);
-//     ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:25:11: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:25:11: Error: Method not found: 'C.new'.
 //   const C.new(1);
 //           ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:26:9: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:26:9: Error: Method not found: 'C.new'.
 //   new C.new(1);
 //         ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:28:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:28:14: Error: Getter not found: 'new'.
 //   var f1 = A.new;
 //              ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:29:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   var f2 = B.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:29:14: Error: Getter not found: 'new'.
-//   var f2 = B.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:30:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:30:14: Error: Getter not found: 'new'.
 //   var f3 = C.new;
 //              ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:31:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   var f4 = D.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:31:14: Error: Getter not found: 'new'.
-//   var f4 = D.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:37:23: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:37:23: Error: Getter not found: 'new'.
 //   A Function() g1 = A.new;
 //                       ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:38:23: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   B Function() g2 = B.new;
-//                       ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:38:23: Error: Getter not found: 'new'.
-//   B Function() g2 = B.new;
-//                       ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:39:28: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:39:28: Error: Getter not found: 'new'.
 //   C Function(int x) g3 = C.new;
 //                            ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:40:28: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   D Function(int x) g4 = D.new;
-//                            ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:40:28: Error: Getter not found: 'new'.
-//   D Function(int x) g4 = D.new;
-//                            ^^^
-//
 // pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:12:7: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
 // class B extends A {}
 //       ^
@@ -135,9 +84,9 @@
     : this self::A::new()
     ;
   static factory redirectingFactory() → self::A
-    let dynamic #redirecting_factory = self::A::new in invalid-expression;
+    let dynamic #redirecting_factory = "A.new" in invalid-expression;
   static factory redirectingFactoryChild() → self::A
-    let dynamic #redirecting_factory = "B.new" in invalid-expression;
+    let dynamic #redirecting_factory = self::B::• in invalid-expression;
 }
 class B extends self::A {
   synthetic constructor •() → self::B
@@ -158,45 +107,36 @@
     ;
 }
 static method test() → dynamic {
-  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:24:5: Error: Method not found: 'D.new'.
-  D.new(1);
-    ^^^";
-  #C2;
-  new self::C::new(1);
-  () → self::A f1 = self::A::new;
-  dynamic f2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:29:14: Error: Getter not found: 'new'.
-  var f2 = B.new;
+  new self::D::•(1);
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:25:11: Error: Method not found: 'C.new'.
+  const C.new(1);
+          ^^^";
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:26:9: Error: Method not found: 'C.new'.
+  new C.new(1);
+        ^^^";
+  dynamic f1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:28:14: Error: Getter not found: 'new'.
+  var f1 = A.new;
              ^^^";
-  (core::int) → self::C f3 = self::C::new;
-  dynamic f4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:31:14: Error: Getter not found: 'new'.
-  var f4 = D.new;
+  () → self::B f2 = self::B::•;
+  dynamic f3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:30:14: Error: Getter not found: 'new'.
+  var f3 = C.new;
              ^^^";
-  f1(){() → self::A};
-  f2{dynamic}.call();
-  f3(1){(core::int) → self::C};
-  f4{dynamic}.call(1);
-  () → self::A g1 = self::A::new;
-  () → self::B g2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:38:23: Error: Getter not found: 'new'.
-  B Function() g2 = B.new;
-                      ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} () → self::B;
-  (core::int) → self::C g3 = self::C::new;
-  (core::int) → self::D g4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:40:28: Error: Getter not found: 'new'.
-  D Function(int x) g4 = D.new;
-                           ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} (core::int) → self::D;
+  (core::int) → self::D f4 = self::D::•;
+  f1{dynamic}.call();
+  f2(){() → self::B};
+  f3{dynamic}.call(1);
+  f4(1){(core::int) → self::D};
+  () → self::A g1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:37:23: Error: Getter not found: 'new'.
+  A Function() g1 = A.new;
+                      ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} () → self::A;
+  () → self::B g2 = self::B::•;
+  (core::int) → self::C g3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:39:28: Error: Getter not found: 'new'.
+  C Function(int x) g3 = C.new;
+                           ^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} (core::int) → self::C;
+  (core::int) → self::D g4 = self::D::•;
   g1(){() → self::A};
   g2(){() → self::B};
   g3(1){(core::int) → self::C};
   g4(1){(core::int) → self::D};
 }
 static method main() → dynamic {}
-
-constants  {
-  #C1 = 1
-  #C2 = self::C {x:#C1}
-}
-
-
-Constructor coverage from constants:
-org-dartlang-testcase:///unnamed_constructor.dart:
-- C.new (from org-dartlang-testcase:///unnamed_constructor.dart:16:9)
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.weak.outline.expect
index 286b949..aa40cc6 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.weak.outline.expect
@@ -36,9 +36,9 @@
 //   D(int x) : super.new(x * 2);
 //                    ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:8:41: Error: Redirection constructor target not found: 'B.new'
-//   factory A.redirectingFactoryChild() = B.new;
-//                                         ^
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:7:36: Error: Redirection constructor target not found: 'A.new'
+//   factory A.redirectingFactory() = A.new;
+//                                    ^
 //
 import self as self;
 import "dart:core" as core;
@@ -50,9 +50,9 @@
   constructor redirecting() → self::A
     ;
   static factory redirectingFactory() → self::A
-    let dynamic #redirecting_factory = self::A::new in invalid-expression;
+    let dynamic #redirecting_factory = "A.new" in invalid-expression;
   static factory redirectingFactoryChild() → self::A
-    let dynamic #redirecting_factory = "B.new" in invalid-expression;
+    let dynamic #redirecting_factory = self::B::• in invalid-expression;
 }
 class B extends self::A {
   synthetic constructor •() → self::B
diff --git a/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.weak.transformed.expect
index 77763cb..5779400 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart.weak.transformed.expect
@@ -36,89 +36,38 @@
 //   D(int x) : super.new(x * 2);
 //                    ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:8:41: Error: Redirection constructor target not found: 'B.new'
-//   factory A.redirectingFactoryChild() = B.new;
-//                                         ^
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:7:36: Error: Redirection constructor target not found: 'A.new'
+//   factory A.redirectingFactory() = A.new;
+//                                    ^
 //
 // pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:20:14: Error: Superclass has no constructor named 'Object.new'.
 //   D(int x) : super.new(x * 2);
 //              ^^^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:24:5: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   D.new(1);
-//     ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:24:5: Error: Method not found: 'D.new'.
-//   D.new(1);
-//     ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:25:11: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:25:11: Error: Method not found: 'C.new'.
 //   const C.new(1);
 //           ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:26:9: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:26:9: Error: Method not found: 'C.new'.
 //   new C.new(1);
 //         ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:28:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:28:14: Error: Getter not found: 'new'.
 //   var f1 = A.new;
 //              ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:29:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   var f2 = B.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:29:14: Error: Getter not found: 'new'.
-//   var f2 = B.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:30:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:30:14: Error: Getter not found: 'new'.
 //   var f3 = C.new;
 //              ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:31:14: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   var f4 = D.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:31:14: Error: Getter not found: 'new'.
-//   var f4 = D.new;
-//              ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:37:23: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:37:23: Error: Getter not found: 'new'.
 //   A Function() g1 = A.new;
 //                       ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:38:23: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   B Function() g2 = B.new;
-//                       ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:38:23: Error: Getter not found: 'new'.
-//   B Function() g2 = B.new;
-//                       ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:39:28: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
+// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:39:28: Error: Getter not found: 'new'.
 //   C Function(int x) g3 = C.new;
 //                            ^^^
 //
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:40:28: Error: This requires the 'constructor-tearoffs' language feature to be enabled.
-// Try updating your pubspec.yaml to set the minimum SDK constraint to 2.14 or higher, and running 'pub get'.
-//   D Function(int x) g4 = D.new;
-//                            ^^^
-//
-// pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:40:28: Error: Getter not found: 'new'.
-//   D Function(int x) g4 = D.new;
-//                            ^^^
-//
 // pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:12:7: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
 // class B extends A {}
 //       ^
@@ -135,9 +84,9 @@
     : this self::A::new()
     ;
   static factory redirectingFactory() → self::A
-    let Never #redirecting_factory = self::A::new in invalid-expression;
+    let core::String* #redirecting_factory = "A.new" in invalid-expression;
   static factory redirectingFactoryChild() → self::A
-    let core::String* #redirecting_factory = "B.new" in invalid-expression;
+    let Never #redirecting_factory = self::B::• in invalid-expression;
 }
 class B extends self::A {
   synthetic constructor •() → self::B
@@ -158,45 +107,36 @@
     ;
 }
 static method test() → dynamic {
-  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:24:5: Error: Method not found: 'D.new'.
-  D.new(1);
-    ^^^";
-  #C2;
-  new self::C::new(1);
-  () → self::A f1 = self::A::new;
-  dynamic f2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:29:14: Error: Getter not found: 'new'.
-  var f2 = B.new;
+  new self::D::•(1);
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:25:11: Error: Method not found: 'C.new'.
+  const C.new(1);
+          ^^^";
+  invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:26:9: Error: Method not found: 'C.new'.
+  new C.new(1);
+        ^^^";
+  dynamic f1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:28:14: Error: Getter not found: 'new'.
+  var f1 = A.new;
              ^^^";
-  (core::int) → self::C f3 = self::C::new;
-  dynamic f4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:31:14: Error: Getter not found: 'new'.
-  var f4 = D.new;
+  () → self::B f2 = self::B::•;
+  dynamic f3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:30:14: Error: Getter not found: 'new'.
+  var f3 = C.new;
              ^^^";
-  f1(){() → self::A};
-  f2{dynamic}.call();
-  f3(1){(core::int) → self::C};
-  f4{dynamic}.call(1);
-  () → self::A g1 = self::A::new;
-  () → self::B g2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:38:23: Error: Getter not found: 'new'.
-  B Function() g2 = B.new;
+  (core::int) → self::D f4 = self::D::•;
+  f1{dynamic}.call();
+  f2(){() → self::B};
+  f3{dynamic}.call(1);
+  f4(1){(core::int) → self::D};
+  () → self::A g1 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:37:23: Error: Getter not found: 'new'.
+  A Function() g1 = A.new;
                       ^^^";
-  (core::int) → self::C g3 = self::C::new;
-  (core::int) → self::D g4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:40:28: Error: Getter not found: 'new'.
-  D Function(int x) g4 = D.new;
+  () → self::B g2 = self::B::•;
+  (core::int) → self::C g3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/unnamed_constructor.dart:39:28: Error: Getter not found: 'new'.
+  C Function(int x) g3 = C.new;
                            ^^^";
+  (core::int) → self::D g4 = self::D::•;
   g1(){() → self::A};
   g2(){() → self::B};
   g3(1){(core::int) → self::C};
   g4(1){(core::int) → self::D};
 }
 static method main() → dynamic {}
-
-constants  {
-  #C1 = 1
-  #C2 = self::C {x:#C1}
-}
-
-
-Constructor coverage from constants:
-org-dartlang-testcase:///unnamed_constructor.dart:
-- C.new (from org-dartlang-testcase:///unnamed_constructor.dart:16:9)
-- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 322bacf..a694e4f 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/abstract_class_constructor_tear_off: TextSerializationFailure
 constructor_tearoffs/generic_tearoff_with_context: TextSerializationFailure
 constructor_tearoffs/generic_tearoff_without_context: TextSerializationFailure
 constructor_tearoffs/instantiation: TypeCheckError
diff --git a/pkg/front_end/tool/_fasta/command_line.dart b/pkg/front_end/tool/_fasta/command_line.dart
index 2dc1077..d4b5b05 100644
--- a/pkg/front_end/tool/_fasta/command_line.dart
+++ b/pkg/front_end/tool/_fasta/command_line.dart
@@ -53,7 +53,13 @@
     show SchemeBasedFileSystem;
 
 import 'package:kernel/target/targets.dart'
-    show LateLowering, Target, getTarget, TargetFlags, targets;
+    show
+        ConstructorTearOffLowering,
+        LateLowering,
+        Target,
+        TargetFlags,
+        getTarget,
+        targets;
 
 class CommandLineProblem {
   final Message message;
@@ -181,6 +187,7 @@
   Flags.forceLateLowering: const BoolValue(false),
   Flags.forceStaticFieldLowering: const BoolValue(false),
   Flags.forceNoExplicitGetterCalls: const BoolValue(false),
+  Flags.forceConstructorTearOffLowering: const BoolValue(false),
   Flags.help: const BoolValue(false),
   Flags.librariesJson: const UriValue(),
   Flags.noDefines: const BoolValue(false),
@@ -254,6 +261,10 @@
           options[Flags.forceStaticFieldLowering],
       forceNoExplicitGetterCallsForTesting:
           options[Flags.forceNoExplicitGetterCalls],
+      forceConstructorTearOffLoweringForTesting:
+          options[Flags.forceConstructorTearOffLowering]
+              ? ConstructorTearOffLowering.all
+              : ConstructorTearOffLowering.none,
       enableNullSafety: isExperimentEnabled(ExperimentalFlag.nonNullable,
           explicitExperimentalFlags: explicitExperimentalFlags));
 
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 56ce4b2..90615e8 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -18,6 +18,7 @@
   final bool forceLateLoweringSentinelForTesting;
   final bool forceStaticFieldLoweringForTesting;
   final bool forceNoExplicitGetterCallsForTesting;
+  final int forceConstructorTearOffLoweringForTesting;
   final bool enableNullSafety;
 
   const TargetFlags(
@@ -26,6 +27,8 @@
       this.forceLateLoweringSentinelForTesting = false,
       this.forceStaticFieldLoweringForTesting = false,
       this.forceNoExplicitGetterCallsForTesting = false,
+      this.forceConstructorTearOffLoweringForTesting =
+          ConstructorTearOffLowering.none,
       this.enableNullSafety = false});
 
   bool operator ==(other) {
@@ -344,6 +347,29 @@
     return enabledLateLowerings & mask != 0;
   }
 
+  /// Bit mask of [ConstructorTearOffLowering] values for the constructor tear
+  /// off lowerings that should be performed by the CFE.
+  ///
+  /// For the selected lowerings, constructor tear offs are encoded using
+  /// synthesized top level functions.
+  int get enabledConstructorTearOffLowerings;
+
+  /// Returns `true` if lowering of constructor tear offs is enabled.
+  ///
+  /// This is determined by the [enabledConstructorTearOffLowerings] mask.
+  bool get isConstructorTearOffLoweringEnabled =>
+      (enabledConstructorTearOffLowerings &
+          ConstructorTearOffLowering.constructors) !=
+      0;
+
+  /// Returns `true` if lowering of typedef tear offs is enabled.
+  ///
+  /// This is determined by the [enabledConstructorTearOffLowerings] mask.
+  bool get isTypedefTearOffLoweringEnabled =>
+      (enabledConstructorTearOffLowerings &
+          ConstructorTearOffLowering.typedefs) !=
+      0;
+
   /// Returns `true` if the CFE should lower a late local variable given it
   /// [hasInitializer], [isFinal], and its type [isPotentiallyNullable].
   ///
@@ -455,6 +481,10 @@
   bool get supportsNewMethodInvocationEncoding => true;
 
   @override
+  int get enabledConstructorTearOffLowerings =>
+      flags.forceConstructorTearOffLoweringForTesting;
+
+  @override
   String get name => 'none';
 
   @override
@@ -603,3 +633,15 @@
     }
   }
 }
+
+class ConstructorTearOffLowering {
+  /// Create top level functions to use as tear offs of constructors.
+  static const int constructors = 1 << 0;
+
+  /// Create top level functions to use as tear offs of non trivial redirecting
+  /// factory constructors and typedefs.
+  static const int typedefs = 1 << 1;
+
+  static const int none = 0;
+  static const int all = (1 << 2) - 1;
+}
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index 4d28929..4439705 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -111,31 +111,38 @@
   List<TypeParameter> freshParameters = new List<TypeParameter>.generate(
       typeParameters.length, (i) => new TypeParameter(typeParameters[i].name),
       growable: true);
-  Map<TypeParameter, DartType> map = <TypeParameter, DartType>{};
-  for (int i = 0; i < typeParameters.length; ++i) {
-    map[typeParameters[i]] = new TypeParameterType.forAlphaRenaming(
+  List<DartType> freshTypeArguments =
+      new List<DartType>.generate(typeParameters.length, (int i) {
+    return new TypeParameterType.forAlphaRenaming(
         typeParameters[i], freshParameters[i]);
-  }
+  }, growable: true);
+  Substitution substitution =
+      Substitution.fromPairs(typeParameters, freshTypeArguments);
   for (int i = 0; i < typeParameters.length; ++i) {
     TypeParameter typeParameter = typeParameters[i];
     TypeParameter freshTypeParameter = freshParameters[i];
 
-    freshTypeParameter.bound = substitute(typeParameter.bound, map);
-    freshTypeParameter.defaultType = substitute(typeParameter.defaultType, map);
+    freshTypeParameter.bound = substitution.substituteType(typeParameter.bound);
+    freshTypeParameter.defaultType =
+        substitution.substituteType(typeParameter.defaultType);
     freshTypeParameter.variance =
         typeParameter.isLegacyCovariant ? null : typeParameter.variance;
     // Annotations on a type parameter are specific to the declaration of the
     // type parameter, rather than the type parameter as such, and therefore
     // should not be copied here.
   }
-  return new FreshTypeParameters(freshParameters, Substitution.fromMap(map));
+  return new FreshTypeParameters(
+      freshParameters, freshTypeArguments, substitution);
 }
 
 class FreshTypeParameters {
+  ///
   final List<TypeParameter> freshTypeParameters;
+  final List<DartType> freshTypeArguments;
   final Substitution substitution;
 
-  FreshTypeParameters(this.freshTypeParameters, this.substitution);
+  FreshTypeParameters(
+      this.freshTypeParameters, this.freshTypeArguments, this.substitution);
 
   FunctionType applyToFunctionType(FunctionType type) {
     return new FunctionType(type.positionalParameters.map(substitute).toList(),
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index 547e14a..3230605 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -68,6 +68,10 @@
   bool get supportsNewMethodInvocationEncoding => true;
 
   @override
+  int get enabledConstructorTearOffLowerings =>
+      flags.forceConstructorTearOffLoweringForTesting;
+
+  @override
   String get name => 'vm';
 
   // This is the order that bootstrap libraries are loaded according to
diff --git a/tests/language/const/map_hashcode_override2_test.dart b/tests/language/const/map_hashcode_override2_test.dart
new file mode 100644
index 0000000..b747a97
--- /dev/null
+++ b/tests/language/const/map_hashcode_override2_test.dart
@@ -0,0 +1,50 @@
+// 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 'package:expect/expect.dart';
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+getValueNonOptimized(x) {
+  // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
+  if (new DateTime.now() == 42) return getValueNonOptimized(2);
+  return x;
+}
+
+class MyClass {
+  final int n;
+
+  const MyClass(this.n);
+
+  int get hashCode => super.hashCode + 1;
+}
+
+main() {
+  const constInstance = MyClass(1);
+  final nonConstInstance = MyClass(1);
+
+  const constMap = {MyClass(1): 11};
+  final nonConstMap = {constInstance: 11};
+  final nonConstMap2 = {nonConstInstance: 11};
+
+  // operator== is _not_ overridden, so instances are not equal.
+  Expect.notEquals(constInstance, nonConstInstance);
+
+  Expect.isTrue(constMap.containsKey(getValueNonOptimized(constInstance)));
+  Expect.isFalse(constMap.containsKey(getValueNonOptimized(nonConstInstance)));
+  Expect.isTrue(nonConstMap.containsKey(getValueNonOptimized(constInstance)));
+  Expect.isFalse(
+      nonConstMap.containsKey(getValueNonOptimized(nonConstInstance)));
+  Expect.isFalse(nonConstMap2.containsKey(getValueNonOptimized(constInstance)));
+  Expect.isTrue(
+      nonConstMap2.containsKey(getValueNonOptimized(nonConstInstance)));
+
+  Expect.equals(11, constMap[getValueNonOptimized(constInstance)]);
+  Expect.isNull(constMap[getValueNonOptimized(nonConstInstance)]);
+  Expect.equals(11, nonConstMap[getValueNonOptimized(constInstance)]);
+  Expect.isNull(nonConstMap[getValueNonOptimized(nonConstInstance)]);
+  Expect.isNull(nonConstMap2[getValueNonOptimized(constInstance)]);
+  Expect.equals(11, nonConstMap2[getValueNonOptimized(nonConstInstance)]);
+}
diff --git a/tests/language/const/map_hashcode_override_test.dart b/tests/language/const/map_hashcode_override_test.dart
new file mode 100644
index 0000000..e378e05
--- /dev/null
+++ b/tests/language/const/map_hashcode_override_test.dart
@@ -0,0 +1,34 @@
+// 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 'package:expect/expect.dart';
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+getValueNonOptimized(x) {
+  // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
+  if (new DateTime.now() == 42) return getValueNonOptimized(2);
+  return x;
+}
+
+class Nasty {
+  final int n;
+
+  const Nasty(this.n);
+
+  int get hashCode {
+    while (true) {}
+  }
+}
+
+main() {
+  final map = const {1: 42, 'foo': 499, 2: 'bar', Nasty(1): 'baz'};
+  Expect.equals(42, map[getValueNonOptimized(1.0)]);
+  Expect.equals(
+      499, map[getValueNonOptimized(new String.fromCharCodes('foo'.runes))]);
+  Expect.equals('bar', map[getValueNonOptimized(2)]);
+  Expect.isNull(map[getValueNonOptimized(Nasty(1))]);
+  Expect.equals('baz', map[getValueNonOptimized(const Nasty(1))]);
+}
diff --git a/tests/language/const/set_hashcode_override2_test.dart b/tests/language/const/set_hashcode_override2_test.dart
new file mode 100644
index 0000000..1fc8665
--- /dev/null
+++ b/tests/language/const/set_hashcode_override2_test.dart
@@ -0,0 +1,41 @@
+// 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 'package:expect/expect.dart';
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+getValueNonOptimized(x) {
+  // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
+  if (new DateTime.now() == 42) return getValueNonOptimized(2);
+  return x;
+}
+
+class MyClass {
+  final int n;
+
+  const MyClass(this.n);
+
+  int get hashCode => super.hashCode + 1;
+}
+
+main() {
+  const constInstance = MyClass(1);
+  final nonConstInstance = MyClass(1);
+
+  const constSet = {MyClass(1)};
+  final nonConstSet = {constInstance};
+  final nonConstSet2 = {nonConstInstance};
+
+  // operator== is _not_ overridden, so instances are not equal.
+  Expect.notEquals(constInstance, nonConstInstance);
+
+  Expect.isTrue(constSet.contains(getValueNonOptimized(constInstance)));
+  Expect.isFalse(constSet.contains(getValueNonOptimized(nonConstInstance)));
+  Expect.isTrue(nonConstSet.contains(getValueNonOptimized(constInstance)));
+  Expect.isFalse(nonConstSet.contains(getValueNonOptimized(nonConstInstance)));
+  Expect.isFalse(nonConstSet2.contains(getValueNonOptimized(constInstance)));
+  Expect.isTrue(nonConstSet2.contains(getValueNonOptimized(nonConstInstance)));
+}
diff --git a/tests/language_2/const/map_hashcode_override2_test.dart b/tests/language_2/const/map_hashcode_override2_test.dart
new file mode 100644
index 0000000..86ced20
--- /dev/null
+++ b/tests/language_2/const/map_hashcode_override2_test.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.
+
+// @dart = 2.9
+
+import 'package:expect/expect.dart';
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+getValueNonOptimized(x) {
+  // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
+  if (new DateTime.now() == 42) return getValueNonOptimized(2);
+  return x;
+}
+
+class MyClass {
+  final int n;
+
+  const MyClass(this.n);
+
+  int get hashCode => super.hashCode + 1;
+}
+
+main() {
+  const constInstance = MyClass(1);
+  final nonConstInstance = MyClass(1);
+
+  const constMap = {MyClass(1): 11};
+  final nonConstMap = {constInstance: 11};
+  final nonConstMap2 = {nonConstInstance: 11};
+
+  // operator== is _not_ overridden, so instances are not equal.
+  Expect.notEquals(constInstance, nonConstInstance);
+
+  Expect.isTrue(constMap.containsKey(getValueNonOptimized(constInstance)));
+  Expect.isFalse(constMap.containsKey(getValueNonOptimized(nonConstInstance)));
+  Expect.isTrue(nonConstMap.containsKey(getValueNonOptimized(constInstance)));
+  Expect.isFalse(
+      nonConstMap.containsKey(getValueNonOptimized(nonConstInstance)));
+  Expect.isFalse(nonConstMap2.containsKey(getValueNonOptimized(constInstance)));
+  Expect.isTrue(
+      nonConstMap2.containsKey(getValueNonOptimized(nonConstInstance)));
+
+  Expect.equals(11, constMap[getValueNonOptimized(constInstance)]);
+  Expect.isNull(constMap[getValueNonOptimized(nonConstInstance)]);
+  Expect.equals(11, nonConstMap[getValueNonOptimized(constInstance)]);
+  Expect.isNull(nonConstMap[getValueNonOptimized(nonConstInstance)]);
+  Expect.isNull(nonConstMap2[getValueNonOptimized(constInstance)]);
+  Expect.equals(11, nonConstMap2[getValueNonOptimized(nonConstInstance)]);
+}
diff --git a/tests/language_2/const/map_hashcode_override_test.dart b/tests/language_2/const/map_hashcode_override_test.dart
new file mode 100644
index 0000000..47223e7
--- /dev/null
+++ b/tests/language_2/const/map_hashcode_override_test.dart
@@ -0,0 +1,36 @@
+// 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.
+
+// @dart = 2.9
+
+import 'package:expect/expect.dart';
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+getValueNonOptimized(x) {
+  // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
+  if (new DateTime.now() == 42) return getValueNonOptimized(2);
+  return x;
+}
+
+class Nasty {
+  final int n;
+
+  const Nasty(this.n);
+
+  int get hashCode {
+    while (true) {}
+  }
+}
+
+main() {
+  final map = const {1: 42, 'foo': 499, 2: 'bar', Nasty(1): 'baz'};
+  Expect.equals(42, map[getValueNonOptimized(1.0)]);
+  Expect.equals(
+      499, map[getValueNonOptimized(new String.fromCharCodes('foo'.runes))]);
+  Expect.equals('bar', map[getValueNonOptimized(2)]);
+  Expect.isNull(map[getValueNonOptimized(Nasty(1))]);
+  Expect.equals('baz', map[getValueNonOptimized(const Nasty(1))]);
+}
diff --git a/tests/language_2/const/set_hashcode_override2_test.dart b/tests/language_2/const/set_hashcode_override2_test.dart
new file mode 100644
index 0000000..7035373
--- /dev/null
+++ b/tests/language_2/const/set_hashcode_override2_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.
+
+// @dart = 2.9
+
+import 'package:expect/expect.dart';
+
+/// Returns its argument.
+///
+/// Prevents static optimizations and inlining.
+getValueNonOptimized(x) {
+  // DateTime.now() cannot be predicted statically, never equal to ASCII 42 '*'.
+  if (new DateTime.now() == 42) return getValueNonOptimized(2);
+  return x;
+}
+
+class MyClass {
+  final int n;
+
+  const MyClass(this.n);
+
+  int get hashCode => super.hashCode + 1;
+}
+
+main() {
+  const constInstance = MyClass(1);
+  final nonConstInstance = MyClass(1);
+
+  const constSet = {MyClass(1)};
+  final nonConstSet = {constInstance};
+  final nonConstSet2 = {nonConstInstance};
+
+  // operator== is _not_ overridden, so instances are not equal.
+  Expect.notEquals(constInstance, nonConstInstance);
+
+  Expect.isTrue(constSet.contains(getValueNonOptimized(constInstance)));
+  Expect.isFalse(constSet.contains(getValueNonOptimized(nonConstInstance)));
+  Expect.isTrue(nonConstSet.contains(getValueNonOptimized(constInstance)));
+  Expect.isFalse(nonConstSet.contains(getValueNonOptimized(nonConstInstance)));
+  Expect.isFalse(nonConstSet2.contains(getValueNonOptimized(constInstance)));
+  Expect.isTrue(nonConstSet2.contains(getValueNonOptimized(nonConstInstance)));
+}
diff --git a/tools/VERSION b/tools/VERSION
index e08126e..44af46c 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 289
+PRERELEASE 290
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/spec_parser/Dart.g b/tools/spec_parser/Dart.g
index f166720..5f79d24 100644
--- a/tools/spec_parser/Dart.g
+++ b/tools/spec_parser/Dart.g
@@ -420,11 +420,11 @@
     ;
 
 constructorName
-    :    typeIdentifier ('.' identifier)?
+    :    typeIdentifier ('.' (identifier | NEW))?
     ;
 
 redirection
-    :    ':' THIS ('.' identifier)? arguments
+    :    ':' THIS ('.' (identifier | NEW))? arguments
     ;
 
 initializers
@@ -433,7 +433,7 @@
 
 initializerListEntry
     :    SUPER arguments
-    |    SUPER '.' identifier arguments
+    |    SUPER '.' (identifier | NEW) arguments
     |    fieldInitializer
     |    assertion
     ;
@@ -519,10 +519,12 @@
     |    '(' expression ')'
     |    literal
     |    identifier
+    |    constructorTearoff
     ;
 
 constructorInvocation
-    :    typeName typeArguments '.' identifier arguments
+    :    typeName typeArguments '.' NEW arguments
+    |    typeName '.' NEW arguments
     ;
 
 literal
@@ -598,6 +600,10 @@
     : AWAIT? FOR '(' forLoopParts ')' element
     ;
 
+constructorTearoff
+    :    typeName typeArguments? '.' NEW
+    ;
+
 throwExpression
     :    THROW expression
     ;
@@ -850,6 +856,7 @@
     :    '!'
     |    assignableSelector
     |    argumentPart
+    |    typeArguments
     ;
 
 argumentPart
@@ -900,8 +907,8 @@
     ;
 
 qualifiedName
-    :    typeIdentifier '.' identifier
-    |    typeIdentifier '.' typeIdentifier '.' identifier
+    :    typeIdentifier '.' (identifier | NEW)
+    |    typeIdentifier '.' typeIdentifier '.' (identifier | NEW)
     ;
 
 typeIdentifier
@@ -1249,7 +1256,7 @@
 constructorDesignation
     :    typeIdentifier
     |    qualifiedName
-    |    typeName typeArguments ('.' identifier)?
+    |    typeName typeArguments ('.' (identifier | NEW))?
     ;
 
 symbolLiteral