Version 2.14.0-390.0.dev

Merge commit '0b1ddaa598d4fcc2fdf2eb750623d30326191d46' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b1dcdb8..55bd6d1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -82,6 +82,7 @@
 - `convertNativeToDart_Dictionary()` now converts objects recursively, this
   fixes APIs like MediaStreamTrack.getCapabilities that convert between Maps and
   browser Dictionaries. [#44319]
+- Added some access-control HTTP header names to `HttpHeaders`.
 
 [#44319]: https://github.com/dart-lang/sdk/issues/44319
 
@@ -90,6 +91,7 @@
 - BREAKING CHANGE (for pre-migrated null safe code): `HttpClient`'s
   `.authenticate` and `.authenticateProxy` setter callbacks must now accept a
   nullable `realm` argument.
+- Added some access-control HTTP header names to `HttpHeaders`.
 
 #### `dart:typed_data`
 
diff --git a/benchmarks/IsolateFibonacci/dart/IsolateFibonacci.dart b/benchmarks/IsolateFibonacci/dart/IsolateFibonacci.dart
new file mode 100644
index 0000000..84b7572
--- /dev/null
+++ b/benchmarks/IsolateFibonacci/dart/IsolateFibonacci.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+import 'dart:isolate';
+import 'dart:math';
+
+import 'package:expect/expect.dart';
+
+// Implements recursive summation via tail calls:
+//   fib(n) => n <= 1 ? 1
+//                    : fib(n-1) + fib(n-2);
+Future fibonacciRecursive(List args) async {
+  final SendPort port = args[0];
+  final n = args[1];
+  if (n <= 1) {
+    port.send(1);
+    return;
+  }
+  final left = ReceivePort();
+  final right = ReceivePort();
+  await Future.wait([
+    Isolate.spawn(fibonacciRecursive, [left.sendPort, n - 1]),
+    Isolate.spawn(fibonacciRecursive, [right.sendPort, n - 2]),
+  ]);
+  final results = await Future.wait([left.first, right.first]);
+  port.send(results[0] + results[1]);
+}
+
+Future<void> main() async {
+  final rpWarmup = ReceivePort();
+  final rpRun = ReceivePort();
+  final int nWarmup = 17; // enough runs to trigger optimized compilation
+  final int nWarmupFactorial = 2584;
+  // With --enable-isolate-groups runs for about 8 seconds.
+  // Should not be run witout --enable-isolate-groups as it would be too slow.
+  final int n = 21;
+  final int nFactorial = 17711;
+  final beforeRss = ProcessInfo.currentRss;
+
+  int maxRss = beforeRss;
+  final rssTimer = Timer.periodic(const Duration(milliseconds: 10), (_) {
+    maxRss = max(ProcessInfo.currentRss, maxRss);
+  });
+
+  final watch = Stopwatch();
+  watch.start();
+
+  // For the benefit of enable-isolate-groups configuration, warm up target
+  // isolate code by running couple iterations in the main isolate.
+  await Isolate.spawn(fibonacciRecursive, [rpWarmup.sendPort, nWarmup]);
+  Expect.equals(nWarmupFactorial, await rpWarmup.first);
+
+  final warmup = watch.elapsedMicroseconds;
+
+  await Isolate.spawn(fibonacciRecursive, [rpRun.sendPort, n]);
+  Expect.equals(nFactorial, await rpRun.first);
+
+  final done = watch.elapsedMicroseconds;
+
+  print('IsolateFibonacci_$n.Calculation(RunTimeRaw): ${done-warmup} us.');
+  print('IsolateFibonacci_$n.DeltaPeak(MemoryUse): ${maxRss-beforeRss}');
+  rssTimer.cancel();
+}
diff --git a/benchmarks/IsolateFibonacci/dart2/IsolateFibonacci.dart b/benchmarks/IsolateFibonacci/dart2/IsolateFibonacci.dart
new file mode 100644
index 0000000..84b7572
--- /dev/null
+++ b/benchmarks/IsolateFibonacci/dart2/IsolateFibonacci.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+import 'dart:isolate';
+import 'dart:math';
+
+import 'package:expect/expect.dart';
+
+// Implements recursive summation via tail calls:
+//   fib(n) => n <= 1 ? 1
+//                    : fib(n-1) + fib(n-2);
+Future fibonacciRecursive(List args) async {
+  final SendPort port = args[0];
+  final n = args[1];
+  if (n <= 1) {
+    port.send(1);
+    return;
+  }
+  final left = ReceivePort();
+  final right = ReceivePort();
+  await Future.wait([
+    Isolate.spawn(fibonacciRecursive, [left.sendPort, n - 1]),
+    Isolate.spawn(fibonacciRecursive, [right.sendPort, n - 2]),
+  ]);
+  final results = await Future.wait([left.first, right.first]);
+  port.send(results[0] + results[1]);
+}
+
+Future<void> main() async {
+  final rpWarmup = ReceivePort();
+  final rpRun = ReceivePort();
+  final int nWarmup = 17; // enough runs to trigger optimized compilation
+  final int nWarmupFactorial = 2584;
+  // With --enable-isolate-groups runs for about 8 seconds.
+  // Should not be run witout --enable-isolate-groups as it would be too slow.
+  final int n = 21;
+  final int nFactorial = 17711;
+  final beforeRss = ProcessInfo.currentRss;
+
+  int maxRss = beforeRss;
+  final rssTimer = Timer.periodic(const Duration(milliseconds: 10), (_) {
+    maxRss = max(ProcessInfo.currentRss, maxRss);
+  });
+
+  final watch = Stopwatch();
+  watch.start();
+
+  // For the benefit of enable-isolate-groups configuration, warm up target
+  // isolate code by running couple iterations in the main isolate.
+  await Isolate.spawn(fibonacciRecursive, [rpWarmup.sendPort, nWarmup]);
+  Expect.equals(nWarmupFactorial, await rpWarmup.first);
+
+  final warmup = watch.elapsedMicroseconds;
+
+  await Isolate.spawn(fibonacciRecursive, [rpRun.sendPort, n]);
+  Expect.equals(nFactorial, await rpRun.first);
+
+  final done = watch.elapsedMicroseconds;
+
+  print('IsolateFibonacci_$n.Calculation(RunTimeRaw): ${done-warmup} us.');
+  print('IsolateFibonacci_$n.DeltaPeak(MemoryUse): ${maxRss-beforeRss}');
+  rssTimer.cancel();
+}
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index a8fcbf3..79abc75 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -141,6 +141,7 @@
   CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS,
   CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR,
   CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
+  CompileTimeErrorCode.CONSTRUCTOR_TEAROFFS_NOT_ENABLED,
   CompileTimeErrorCode.CONTINUE_LABEL_ON_SWITCH,
   CompileTimeErrorCode.COULD_NOT_INFER,
   CompileTimeErrorCode.DEFAULT_LIST_CONSTRUCTOR,
diff --git a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
index 6d38db2..9f3a4db 100644
--- a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
@@ -12,10 +12,6 @@
 import 'package:pub_semver/pub_semver.dart';
 
 class FeatureSetProvider {
-  /// This flag will be turned to `true` and inlined when we un-fork SDK,
-  /// so that the only SDK is the Null Safe SDK.
-  static const isNullSafetySdk = true;
-
   final Version _sdkLanguageVersion;
   final AllowedExperiments _allowedExperiments;
   final ResourceProvider _resourceProvider;
diff --git a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
index a2428b1..090d0ad 100644
--- a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
@@ -19,6 +19,8 @@
 
   AstRewriter(this._errorReporter);
 
+  /// Possibly rewrites [node] as an [ExtensionOverride] or as an
+  /// [InstanceCreationExpression].
   AstNode methodInvocation(Scope nameScope, MethodInvocation node) {
     SimpleIdentifier methodName = node.methodName;
     if (methodName.isSynthetic) {
@@ -140,6 +142,44 @@
     return node;
   }
 
+  /// Possibly rewrites [node] as a [ConstructorReference].
+  AstNode prefixedIdentifier(Scope nameScope, PrefixedIdentifier node) {
+    if (node.parent is Annotation) {
+      // An annotations which is a const constructor invocation can initially be
+      // represented with a [PrefixedIdentifier]. Do not rewrite such nodes.
+      return node;
+    }
+    if (node.parent is CommentReference) {
+      // TODO(srawlins): This probably should be rewritten to a
+      // [ConstructorReference] at some point.
+      return node;
+    }
+    var identifier = node.identifier;
+    if (identifier.isSynthetic) {
+      // This isn't a constructor reference.
+      return node;
+    }
+    var prefix = node.prefix;
+    var element = nameScope.lookup(prefix.name).getter;
+    if (element is ClassElement) {
+      // Example:
+      //     class C { C.named(); }
+      //     C.named
+      return _toConstructorReference(node: node, classElement: element);
+    } else if (element is TypeAliasElement) {
+      var aliasedType = element.aliasedType;
+      if (aliasedType is InterfaceType) {
+        // Example:
+        //     class C { C.named(); }
+        //     typedef X = C;
+        //     X.named
+        return _toConstructorReference(
+            node: node, classElement: aliasedType.element);
+      }
+    }
+    return node;
+  }
+
   AstNode _instanceCreation_prefix_type_name({
     required MethodInvocation node,
     required PrefixedIdentifier typeNameIdentifier,
@@ -170,6 +210,25 @@
     return instanceCreationExpression;
   }
 
+  AstNode _toConstructorReference(
+      {required PrefixedIdentifier node, required ClassElement classElement}) {
+    var name = node.identifier.name;
+    var constructorElement = name == 'new'
+        ? classElement.unnamedConstructor
+        : classElement.getNamedConstructor(name);
+    if (constructorElement == null) {
+      return node;
+    }
+
+    var typeName = astFactory.typeName(node.prefix, null);
+    var constructorName =
+        astFactory.constructorName(typeName, node.period, node.identifier);
+    var constructorReference =
+        astFactory.constructorReference(constructorName: constructorName);
+    NodeReplacer.replace(node, constructorReference);
+    return constructorReference;
+  }
+
   InstanceCreationExpression _toInstanceCreation_prefix_type({
     required MethodInvocation node,
     required SimpleIdentifier prefixIdentifier,
diff --git a/pkg/analyzer/lib/src/dart/resolver/constructor_reference_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/constructor_reference_resolver.dart
new file mode 100644
index 0000000..0d82de1
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/resolver/constructor_reference_resolver.dart
@@ -0,0 +1,76 @@
+// 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+
+/// A resolver for [ConstructorReference] nodes.
+class ConstructorReferenceResolver {
+  /// The resolver driving this participant.
+  final ResolverVisitor _resolver;
+
+  ConstructorReferenceResolver(this._resolver);
+
+  void resolve(ConstructorReferenceImpl node) {
+    if (!_resolver.isConstructorTearoffsEnabled) {
+      _resolver.errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.CONSTRUCTOR_TEAROFFS_NOT_ENABLED, node, []);
+    }
+    node.constructorName.accept(_resolver);
+    _inferArgumentTypes(node);
+  }
+
+  void _inferArgumentTypes(ConstructorReferenceImpl node) {
+    var constructorName = node.constructorName;
+    var typeName = constructorName.type;
+    var elementToInfer = _resolver.inferenceHelper.constructorElementToInfer(
+      constructorName: constructorName,
+      definingLibrary: _resolver.definingLibrary,
+    );
+
+    // If the constructor is generic, we'll have a ConstructorMember that
+    // substitutes in type arguments (possibly `dynamic`) from earlier in
+    // resolution.
+    //
+    // Otherwise we'll have a ConstructorElement, and we can skip inference
+    // because there's nothing to infer in a non-generic type.
+    if (elementToInfer != null) {
+      // TODO(leafp): Currently, we may re-infer types here, since we
+      // sometimes resolve multiple times.  We should really check that we
+      // have not already inferred something.  However, the obvious ways to
+      // check this don't work, since we may have been instantiated
+      // to bounds in an earlier phase, and we *do* want to do inference
+      // in that case.
+
+      // Get back to the uninstantiated generic constructor.
+      // TODO(jmesserly): should we store this earlier in resolution?
+      // Or look it up, instead of jumping backwards through the Member?
+      var rawElement = elementToInfer.element;
+      var constructorType = elementToInfer.asType;
+
+      var inferred = _resolver.inferenceHelper.inferTearOff(
+          node, constructorName.name!, constructorType) as FunctionType?;
+
+      if (inferred != null) {
+        typeName.type = inferred.returnType;
+
+        // Update the static element as well. This is used in some cases, such
+        // as computing constant values. It is stored in two places.
+        var constructorElement = ConstructorMember.from(
+          rawElement,
+          inferred.returnType as InterfaceType,
+        );
+        constructorName.staticElement = constructorElement;
+        constructorName.name?.staticElement = constructorElement;
+        node.staticType = inferred;
+      }
+    } else {
+      node.staticType = node.constructorName.staticElement!.type;
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart b/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart
index adb9ff5..f1a6fd8 100644
--- a/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart
@@ -129,6 +129,9 @@
   }
 
   @override
+  bool visitConstructorReference(ConstructorReference node) => false;
+
+  @override
   bool visitContinueStatement(ContinueStatement node) {
     _enclosingBlockContainsContinue = true;
     return false;
diff --git a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
index 1bc11bc..a73cf65 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
@@ -50,7 +50,7 @@
       typeFormals: typeParameters,
       parameters: element.parameters,
       returnType: element.returnType,
-      nullabilitySuffix: NullabilitySuffix.star,
+      nullabilitySuffix: NullabilitySuffix.none,
     );
   }
 }
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index f08fb8d..357caa6 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -860,6 +860,16 @@
   }
 
   @override
+  void visitPrefixedIdentifier(PrefixedIdentifier node) {
+    var newNode = _astRewriter.prefixedIdentifier(_nameScope, node);
+    if (newNode != node) {
+      return newNode.accept(this);
+    }
+
+    super.visitPrefixedIdentifier(node);
+  }
+
+  @override
   void visitSimpleFormalParameter(covariant SimpleFormalParameterImpl node) {
     ParameterElementImpl element;
     if (node.parent is DefaultFormalParameter) {
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 819f901..7a9de95 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -2263,6 +2263,23 @@
               "IntegerDivisionByZeroException.");
 
   /**
+   * A constructor cannot be torn off without the 'constructor-tearoffs'
+   * language feature.
+   *
+   * There is also a [ParserError.EXPERIMENT_NOT_ENABLED] code which catches
+   * some cases of constructor tearoff features (like `List<int>.filled;`).
+   * Other constructor tearoff cases are not realized until resolution
+   * (like `List.filled;`).
+   */
+  static const CompileTimeErrorCode CONSTRUCTOR_TEAROFFS_NOT_ENABLED =
+      CompileTimeErrorCode(
+          'CONSTRUCTOR_TEAROFFS_NOT_ENABLED',
+          "Tearing off a constructor requires the 'constructor-tearoffs' "
+              "language feature.",
+          correction: "Try updating your pubspec.yaml to set the minimum SDK "
+              "constraint to 2.14 or higher, and running 'pub get'.");
+
+  /**
    * 16.12.2 Const: An expression of one of the forms !e, e1 && e2 or e1 || e2,
    * where e, e1 and e2 are constant expressions that evaluate to a boolean
    * value.
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 209b132..158edb0 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -31,6 +31,7 @@
 import 'package:analyzer/src/dart/resolver/assignment_expression_resolver.dart';
 import 'package:analyzer/src/dart/resolver/binary_expression_resolver.dart';
 import 'package:analyzer/src/dart/resolver/body_inference_context.dart';
+import 'package:analyzer/src/dart/resolver/constructor_reference_resolver.dart';
 import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
 import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
 import 'package:analyzer/src/dart/resolver/for_resolver.dart';
@@ -186,6 +187,8 @@
 
   late final AssignmentExpressionResolver _assignmentExpressionResolver;
   late final BinaryExpressionResolver _binaryExpressionResolver;
+  late final ConstructorReferenceResolver _constructorReferenceResolver =
+      ConstructorReferenceResolver(this);
   late final FunctionExpressionInvocationResolver
       _functionExpressionInvocationResolver;
   late final FunctionExpressionResolver _functionExpressionResolver;
@@ -250,7 +253,8 @@
   late final FunctionReferenceResolver _functionReferenceResolver;
 
   late final InstanceCreationExpressionResolver
-      _instanceCreationExpressionResolver;
+      _instanceCreationExpressionResolver =
+      InstanceCreationExpressionResolver(this);
 
   /// Initialize a newly created visitor to resolve the nodes in an AST node.
   ///
@@ -372,8 +376,6 @@
     typeAnalyzer = StaticTypeAnalyzer(this, migrationResolutionHooks);
     _functionReferenceResolver =
         FunctionReferenceResolver(this, _isNonNullableByDefault);
-    _instanceCreationExpressionResolver =
-        InstanceCreationExpressionResolver(this);
   }
 
   bool get isConstructorTearoffsEnabled =>
@@ -1227,6 +1229,11 @@
   }
 
   @override
+  void visitConstructorReference(covariant ConstructorReferenceImpl node) {
+    _constructorReferenceResolver.resolve(node);
+  }
+
+  @override
   void visitContinueStatement(ContinueStatement node) {
     //
     // We do not visit the label because it needs to be visited in the context
diff --git a/pkg/analyzer/lib/src/test_utilities/find_node.dart b/pkg/analyzer/lib/src/test_utilities/find_node.dart
index 1a71750..aeea523 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_node.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_node.dart
@@ -92,6 +92,10 @@
     return _node(search, (n) => n is ConstructorName);
   }
 
+  ConstructorReference constructorReference(String search) {
+    return _node(search, (n) => n is ConstructorReference);
+  }
+
   ContinueStatement continueStatement(String search) {
     return _node(search, (n) => n is ContinueStatement);
   }
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 9fe7223..367f7ef 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -2643,7 +2643,7 @@
       invocation.methodName,
       elementMatcher(
         stringElement.getMethod('codeUnitAt'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
     );
 
@@ -8532,7 +8532,7 @@
         prefixed,
         element: elementMatcher(
           objectHashCode,
-          isLegacy: isNullSafetySdkAndLegacyLibrary,
+          isLegacy: isLegacyLibrary,
         ),
         type: 'int',
       );
@@ -8546,7 +8546,7 @@
         identifier,
         element: elementMatcher(
           objectHashCode,
-          isLegacy: isNullSafetySdkAndLegacyLibrary,
+          isLegacy: isLegacyLibrary,
         ),
         type: 'int',
       );
diff --git a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
index 1581d51..ce3713b 100644
--- a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
@@ -103,7 +103,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -129,7 +129,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -155,7 +155,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'double',
     );
@@ -228,7 +228,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -254,7 +254,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -733,7 +733,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -925,7 +925,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -963,7 +963,7 @@
       writeType: 'int',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -1072,7 +1072,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -1134,7 +1134,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -1176,7 +1176,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -1271,7 +1271,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -1306,7 +1306,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -1623,7 +1623,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'num', // num + int = num
     );
@@ -2144,7 +2144,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -2184,7 +2184,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -2281,7 +2281,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -2349,7 +2349,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
diff --git a/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart
index f3f1dea..5be34e4 100644
--- a/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/binary_expression_test.dart
@@ -123,7 +123,7 @@
       findNode.binary('a != b'),
       element: elementMatcher(
         numElement.getMethod('=='),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'bool',
     );
@@ -177,7 +177,7 @@
       findNode.binary('a == b'),
       element: elementMatcher(
         numElement.getMethod('=='),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'bool',
     );
@@ -287,7 +287,7 @@
       findNode.binary('a - b'),
       element: elementMatcher(
         numElement.getMethod('-'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'double',
     );
@@ -304,7 +304,7 @@
       findNode.binary('a - b'),
       element: elementMatcher(
         numElement.getMethod('-'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -334,7 +334,7 @@
       findNode.binary('a % b'),
       element: elementMatcher(
         numElement.getMethod('%'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'double',
     );
@@ -351,7 +351,7 @@
       findNode.binary('a % b'),
       element: elementMatcher(
         numElement.getMethod('%'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -405,7 +405,7 @@
       findNode.binary('a + b'),
       element: elementMatcher(
         doubleElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'double',
     );
@@ -489,7 +489,7 @@
       findNode.binary('a + b'),
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'double',
     );
@@ -506,7 +506,7 @@
       findNode.binary('a + b'),
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'num',
     );
@@ -523,7 +523,7 @@
       findNode.binary('a + b'),
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -540,7 +540,7 @@
       findNode.binary('a() + b'),
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -577,7 +577,7 @@
       findNode.binary('a + b'),
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'num',
     );
@@ -741,7 +741,7 @@
       findNode.binary('a + 0'),
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'num',
     );
@@ -758,7 +758,7 @@
       findNode.binary('a / b'),
       element: elementMatcher(
         numElement.getMethod('/'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'double',
     );
@@ -788,7 +788,7 @@
       findNode.binary('a * b'),
       element: elementMatcher(
         numElement.getMethod('*'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'double',
     );
@@ -805,7 +805,7 @@
       findNode.binary('a * b'),
       element: elementMatcher(
         numElement.getMethod('*'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
diff --git a/pkg/analyzer/test/src/dart/resolution/constructor_reference_test.dart b/pkg/analyzer/test/src/dart/resolution/constructor_reference_test.dart
new file mode 100644
index 0000000..b52a502
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/constructor_reference_test.dart
@@ -0,0 +1,227 @@
+// 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:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'context_collection_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConstructorReferenceResolutionTest);
+    defineReflectiveTests(
+        ConstructorReferenceResolutionWithoutConstructorTearoffsTest);
+  });
+}
+
+@reflectiveTest
+class ConstructorReferenceResolutionTest extends PubPackageResolutionTest {
+  test_class_generic_inferFromContext_badTypeArgument() async {
+    await assertErrorsInCode('''
+class A<T extends num> {
+  A.foo();
+}
+
+A<String> Function() bar() {
+  return A.foo;
+}
+''', [
+      error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 41, 6),
+    ]);
+
+    var classElement = findElement.class_('A');
+    var constructorElement = classElement.getNamedConstructor('foo')!;
+    assertConstructorReference(
+      findNode.constructorReference('A.foo;'),
+      elementMatcher(constructorElement, substitution: {'T': 'Never'}),
+      classElement,
+      'A<Never> Function()',
+      expectedTypeNameType: 'A<Never>',
+    );
+  }
+
+  test_class_generic_named_uninstantiated() async {
+    await assertNoErrorsInCode('''
+class A<T> {
+  A.foo();
+}
+
+void bar() {
+  A.foo;
+}
+''');
+
+    var classElement = findElement.class_('A');
+    var constructorElement = classElement.getNamedConstructor('foo')!;
+    assertConstructorReference(
+      findNode.constructorReference('A.foo;'),
+      elementMatcher(constructorElement, substitution: {'T': 'T'}),
+      classElement,
+      'A<T> Function<T>()',
+      expectedTypeNameType: 'A<T>',
+    );
+  }
+
+  test_class_generic_named_uninstantiated_bound() async {
+    await assertNoErrorsInCode('''
+class A<T extends num> {
+  A.foo();
+}
+
+void bar() {
+  A.foo;
+}
+''');
+
+    var classElement = findElement.class_('A');
+    var constructorElement = classElement.getNamedConstructor('foo')!;
+    assertConstructorReference(
+      findNode.constructorReference('A.foo;'),
+      elementMatcher(constructorElement, substitution: {'T': 'T'}),
+      classElement,
+      'A<T> Function<T extends num>()',
+      expectedTypeNameType: 'A<T>',
+    );
+  }
+
+  test_class_nonGeneric_named() async {
+    await assertNoErrorsInCode('''
+class A {
+  A.foo();
+}
+
+void bar() {
+  A.foo;
+}
+''');
+
+    var classElement = findElement.class_('A');
+    assertConstructorReference(
+      findNode.constructorReference('A.foo;'),
+      classElement.getNamedConstructor('foo')!,
+      classElement,
+      'A Function()',
+      expectedTypeNameType: 'A',
+    );
+  }
+
+  test_class_nonGeneric_unnamed() async {
+    await assertNoErrorsInCode('''
+class A {
+  A();
+}
+
+bar() {
+  A.new;
+}
+''');
+
+    var classElement = findElement.class_('A');
+    assertConstructorReference(
+      findNode.constructorReference('A.new;'),
+      classElement.unnamedConstructor,
+      classElement,
+      'A Function()',
+      expectedTypeNameType: 'A',
+    );
+  }
+
+  test_classs_generic_named_inferTypeFromContext() async {
+    await assertNoErrorsInCode('''
+class A<T> {
+  A.foo();
+}
+
+A<int> Function() bar() {
+  return A.foo;
+}
+''');
+
+    var classElement = findElement.class_('A');
+    var constructorElement = classElement.getNamedConstructor('foo')!;
+    assertConstructorReference(
+      findNode.constructorReference('A.foo;'),
+      elementMatcher(constructorElement, substitution: {'T': 'int'}),
+      classElement,
+      'A<int> Function()',
+      expectedTypeNameType: 'A<int>',
+    );
+  }
+
+  test_typeAlias_generic_named_uninstantiated() async {
+    await assertNoErrorsInCode('''
+class A<T, U> {
+  A.foo();
+}
+typedef TA<U> = A<String, U>;
+
+bar() {
+  TA.foo;
+}
+''');
+
+    var classElement = findElement.class_('A');
+    var constructorElement = classElement.getNamedConstructor('foo')!;
+    assertConstructorReference(
+      findNode.constructorReference('TA.foo;'),
+      elementMatcher(constructorElement,
+          substitution: {'T': 'String', 'U': 'U'}),
+      findElement.class_('A'),
+      'A<String, U> Function<U>()',
+      expectedTypeNameType: 'A<String, U>',
+      expectedTypeNameElement: findElement.typeAlias('TA'),
+    );
+  }
+
+  test_typeAlias_instantiated_named() async {
+    await assertNoErrorsInCode('''
+class A<T> {
+  A.foo();
+}
+typedef TA = A<int>;
+
+bar() {
+  TA.foo;
+}
+''');
+
+    var classElement = findElement.class_('A');
+    var constructorElement = classElement.getNamedConstructor('foo')!;
+    assertConstructorReference(
+      findNode.constructorReference('TA.foo;'),
+      elementMatcher(constructorElement, substitution: {'T': 'int'}),
+      classElement,
+      'A<int> Function()',
+      expectedTypeNameType: 'A<int>',
+      expectedTypeNameElement: findElement.typeAlias('TA'),
+    );
+  }
+}
+
+@reflectiveTest
+class ConstructorReferenceResolutionWithoutConstructorTearoffsTest
+    extends PubPackageResolutionTest with WithoutConstructorTearoffsMixin {
+  test_constructorTearoff() async {
+    await assertErrorsInCode('''
+class A {
+  A.foo();
+}
+
+void bar() {
+  A.foo;
+}
+''', [
+      error(CompileTimeErrorCode.CONSTRUCTOR_TEAROFFS_NOT_ENABLED, 39, 5),
+    ]);
+
+    var classElement = findElement.class_('A');
+    assertConstructorReference(
+      findNode.constructorReference('A.foo;'),
+      classElement.getNamedConstructor('foo')!,
+      classElement,
+      'A Function()',
+      expectedTypeNameType: 'A',
+    );
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
index 946f223..3a737e2 100644
--- a/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
@@ -630,7 +630,7 @@
       writeType: 'int',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -664,7 +664,7 @@
       writeType: 'int',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -699,7 +699,7 @@
       writeType: 'int',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -740,7 +740,7 @@
       writeType: 'int',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
diff --git a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
index e10926e..20e87bf 100644
--- a/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/index_expression_test.dart
@@ -187,7 +187,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numPlusElement,
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: typeToStringWithNullability ? 'double' : 'num',
     );
@@ -248,7 +248,7 @@
       writeType: 'double',
       operatorElement: elementMatcher(
         doublePlusElement,
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'double',
     );
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index a76e41a..3b573d9 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -77,7 +77,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: typeToStringWithNullability ? 'double' : 'num');
   }
@@ -92,7 +92,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: 'num');
   }
@@ -107,7 +107,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: 'num');
   }
@@ -122,7 +122,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: 'num');
   }
@@ -181,7 +181,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: 'num');
   }
@@ -196,7 +196,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: 'num');
   }
@@ -211,7 +211,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: 'num');
   }
@@ -226,7 +226,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: 'num');
   }
@@ -241,7 +241,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: 'num');
   }
@@ -256,7 +256,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: 'num');
   }
@@ -271,7 +271,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: 'num');
   }
@@ -286,7 +286,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: typeToStringWithNullability ? 'int' : 'num');
   }
@@ -305,7 +305,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: typeToStringWithNullability ? 'int' : 'num');
   }
@@ -337,7 +337,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: 'num');
   }
@@ -356,7 +356,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('clamp'),
         elementMatcher(numElement.getMethod('clamp'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num, num)',
         expectedType: 'num');
   }
@@ -2122,7 +2122,7 @@
       findNode.methodInvocation('toString()'),
       element: elementMatcher(
         objectElement.getMethod('toString'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       typeArgumentTypes: [],
       invokeType: 'String Function()',
@@ -2223,7 +2223,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('remainder'),
         elementMatcher(numElement.getMethod('remainder'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num)',
         expectedType: typeToStringWithNullability ? 'double' : 'num');
   }
@@ -2238,7 +2238,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('remainder'),
         elementMatcher(numElement.getMethod('remainder'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num)',
         expectedType: typeToStringWithNullability ? 'int' : 'num');
   }
@@ -2253,7 +2253,7 @@
     assertMethodInvocation(
         findNode.methodInvocation('remainder'),
         elementMatcher(numElement.getMethod('remainder'),
-            isLegacy: isNullSafetySdkAndLegacyLibrary),
+            isLegacy: isLegacyLibrary),
         'num Function(num)',
         expectedType: typeToStringWithNullability ? 'int' : 'num');
   }
diff --git a/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
index 2c5f443..3cfabd6 100644
--- a/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
@@ -319,7 +319,7 @@
       writeType: 'int',
       element: elementMatcher(
         numElement.getMethod('-'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -345,7 +345,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -373,7 +373,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -399,7 +399,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -489,7 +489,7 @@
       writeType: 'int',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -518,7 +518,7 @@
       writeType: 'int',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -546,7 +546,7 @@
       writeType: 'int',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -577,7 +577,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -603,7 +603,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -624,7 +624,7 @@
       writeType: 'double',
       element: elementMatcher(
         doubleElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'double',
     );
@@ -645,7 +645,7 @@
       writeType: 'int',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -666,7 +666,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'num',
     );
@@ -695,7 +695,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -725,7 +725,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -757,7 +757,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
diff --git a/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
index 1fa6d56..3408237 100644
--- a/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/prefix_expression_test.dart
@@ -234,7 +234,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -262,7 +262,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -288,7 +288,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -309,7 +309,7 @@
       writeType: null,
       element: elementMatcher(
         intElement.getMethod('unary-'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -382,7 +382,7 @@
       writeType: 'int',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -411,7 +411,7 @@
       writeType: 'int',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -439,7 +439,7 @@
       writeType: 'int',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -470,7 +470,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -496,7 +496,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -517,7 +517,7 @@
       writeType: 'double',
       element: elementMatcher(
         doubleElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'double',
     );
@@ -538,7 +538,7 @@
       writeType: 'int',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -559,7 +559,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'num',
     );
@@ -585,7 +585,7 @@
       writeType: 'T',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'num',
     );
@@ -614,7 +614,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -644,7 +644,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -674,7 +674,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -706,7 +706,7 @@
       writeType: 'num',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -735,7 +735,7 @@
       writeType: 'int',
       element: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -756,7 +756,7 @@
       writeType: null,
       element: elementMatcher(
         intElement.getMethod('~'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
diff --git a/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart b/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart
index e1fcbcc..dc81aab 100644
--- a/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart
@@ -220,7 +220,7 @@
       writeType: 'int',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
diff --git a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
index e3ef89b..d57c5ea 100644
--- a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
@@ -223,7 +223,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -335,7 +335,7 @@
       writeType: 'int',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -472,7 +472,7 @@
       writeType: 'num',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -578,7 +578,7 @@
       writeType: 'int',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index 63a93db..514abe7 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/dart/analysis/feature_set_provider.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/element/element.dart';
@@ -57,11 +56,8 @@
 
   InterfaceType get intType => typeProvider.intType;
 
-  bool get isNullSafetySdkAndLegacyLibrary {
-    if (FeatureSetProvider.isNullSafetySdk) {
-      return !result.libraryElement.isNonNullableByDefault;
-    }
-    return false;
+  bool get isLegacyLibrary {
+    return !result.libraryElement.isNonNullableByDefault;
   }
 
   ClassElement get listElement => typeProvider.listElement;
@@ -165,6 +161,33 @@
     }
   }
 
+  void assertConstructorReference(
+    ConstructorReference node,
+    Object? expectedConstructorElement,
+    ClassElement expectedClassElement,
+    String expectedType, {
+    required String expectedTypeNameType,
+    PrefixElement? expectedPrefix,
+    Element? expectedTypeNameElement,
+  }) {
+    var actualConstructorElement = getNodeElement(node) as ConstructorElement?;
+    var actualConstructorName = node.constructorName.name;
+    if (actualConstructorName != null) {
+      assertConstructorElement(
+        actualConstructorName.staticElement as ConstructorElement?,
+        actualConstructorElement,
+      );
+    }
+
+    assertElement(node, expectedConstructorElement);
+    assertType(node, expectedType);
+
+    var typeName = node.constructorName.type;
+    expectedTypeNameElement ??= expectedClassElement;
+    assertTypeName(typeName, expectedTypeNameElement, expectedTypeNameType,
+        expectedPrefix: expectedPrefix);
+  }
+
   void assertConstructors(ClassElement class_, List<String> expected) {
     expect(
       class_.constructors.map((c) {
@@ -400,6 +423,9 @@
     }
   }
 
+  /// TODO(srawlins): Refactor to accept an `Object? expectedConstructor` which
+  /// can accept `elementMatcher` for generics, and simplify, similar to
+  /// [assertConstructorReference].
   void assertInstanceCreation(
     InstanceCreationExpression creation,
     ClassElement expectedClassElement,
@@ -410,22 +436,8 @@
     PrefixElement? expectedPrefix,
     Element? expectedTypeNameElement,
   }) {
-    String expectedClassName = expectedClassElement.name;
-
-    ConstructorElement? expectedConstructorElement;
-    if (constructorName != null) {
-      expectedConstructorElement =
-          expectedClassElement.getNamedConstructor(constructorName);
-      if (expectedConstructorElement == null) {
-        fail("No constructor '$constructorName' in class"
-            " '$expectedClassName'.");
-      }
-    } else {
-      expectedConstructorElement = expectedClassElement.unnamedConstructor;
-      if (expectedConstructorElement == null) {
-        fail("No unnamed constructor in class '$expectedClassName'.");
-      }
-    }
+    var expectedConstructorElement =
+        _getConstructorElement(expectedClassElement, constructorName);
 
     var actualConstructorElement =
         getNodeElement(creation) as ConstructorElement?;
@@ -870,6 +882,8 @@
       return node.staticElement;
     } else if (node is BinaryExpression) {
       return node.staticElement;
+    } else if (node is ConstructorReference) {
+      return node.constructorName.staticElement;
     } else if (node is Declaration) {
       return node.declaredElement;
     } else if (node is ExtensionOverride) {
@@ -982,6 +996,16 @@
     fail('Expected SimpleIdentifier: (${node.runtimeType}) $node');
   }
 
+  ConstructorElement _getConstructorElement(
+      ClassElement classElement, String? constructorName) {
+    var constructorElement = constructorName == null
+        ? classElement.unnamedConstructor
+        : classElement.getNamedConstructor(constructorName);
+    return constructorElement ??
+        fail("No constructor '${constructorName ?? '<unnamed>'}' in class "
+            "'${classElement.name}'.");
+  }
+
   static String _extractReturnType(String invokeType) {
     int functionIndex = invokeType.indexOf(' Function');
     expect(functionIndex, isNonNegative);
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index 08c23ad..186cac3 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -12,6 +12,7 @@
 import 'class_test.dart' as class_resolution;
 import 'comment_test.dart' as comment;
 import 'constant_test.dart' as constant;
+import 'constructor_reference_test.dart' as constructor_reference;
 import 'constructor_test.dart' as constructor;
 import 'enum_test.dart' as enum_resolution;
 import 'export_test.dart' as export_;
@@ -76,6 +77,7 @@
     comment.main();
     constant.main();
     constructor.main();
+    constructor_reference.main();
     enum_resolution.main();
     export_.main();
     extension_method.main();
diff --git a/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart b/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
index c64b592..a120a6f 100644
--- a/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/receiver_of_type_never_test.dart
@@ -571,7 +571,7 @@
       findNode.binary('=='),
       element: elementMatcher(
         objectElement.getMethod('=='),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'bool',
     );
@@ -621,7 +621,7 @@
       findNode.simple('toString'),
       element: elementMatcher(
         objectElement.getMethod('toString'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'String Function()',
     );
@@ -638,7 +638,7 @@
       findNode.simple('hashCode'),
       element: elementMatcher(
         objectElement.getGetter('hashCode'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
diff --git a/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart b/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
index ab0bbca..cfe8902 100644
--- a/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/return_of_invalid_type_test.dart
@@ -340,7 +340,7 @@
 
   @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38162')
   test_method_async_block_callable_class() async {
-    if (isNullSafetySdkAndLegacyLibrary) {
+    if (isLegacyLibrary) {
       throw 'Make it fail for Null Safety as well, for now.';
     }
 
diff --git a/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart b/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
index 64accd6..8eec4b2 100644
--- a/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/use_of_nullable_value_test.dart
@@ -505,7 +505,7 @@
       writeType: 'int',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -518,7 +518,7 @@
       writeType: 'int?',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -561,7 +561,7 @@
       writeType: 'int',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int?',
     );
@@ -574,7 +574,7 @@
       writeType: 'int',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -608,7 +608,7 @@
       writeType: 'int',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
@@ -621,7 +621,7 @@
       writeType: 'int?',
       operatorElement: elementMatcher(
         numElement.getMethod('+'),
-        isLegacy: isNullSafetySdkAndLegacyLibrary,
+        isLegacy: isLegacyLibrary,
       ),
       type: 'int',
     );
diff --git a/pkg/dds/lib/src/dap/adapters/dart.dart b/pkg/dds/lib/src/dap/adapters/dart.dart
index 72f7964..b8c01a5 100644
--- a/pkg/dds/lib/src/dap/adapters/dart.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart.dart
@@ -21,6 +21,14 @@
 import '../protocol_generated.dart';
 import '../protocol_stream.dart';
 
+/// The mime type to send with source responses to the client.
+///
+/// This is used so if the source name does not end with ".dart" the client can
+/// still tell which language to use (for syntax highlighting, etc.).
+///
+/// https://github.com/microsoft/vscode/issues/8182#issuecomment-231151640
+const dartMimeType = 'text/x-dart';
+
 /// Maximum number of toString()s to be called when responding to variables
 /// requests from the client.
 ///
@@ -174,6 +182,19 @@
   /// `null` if the `initialize` request has not yet been made.
   InitializeRequestArguments? get initializeArgs => _initializeArgs;
 
+  /// Whether the VM Service closing should be used as a signal to terminate the
+  /// debug session.
+  ///
+  /// It is generally better to handle termination when the debuggee terminates
+  /// instead, since this ensures the stdout/stderr streams have been drained.
+  /// However, that's not possible in some cases (for example 'runInTerminal'
+  /// or attaching), so this is the only signal we have.
+  ///
+  /// It is up to the subclass DA to provide this value correctly based on
+  /// whether it will call [handleSessionTerminate] itself upon process
+  /// termination.
+  bool get terminateOnVmServiceClose;
+
   /// [attachRequest] is called by the client when it wants us to to attach to
   /// an existing app. This will only be called once (and only one of this or
   /// launchRequest will be called).
@@ -710,6 +731,44 @@
     await _dds?.shutdown();
   }
 
+  /// [sourceRequest] is called by the client to request source code for a given
+  /// source.
+  ///
+  /// The client may provide a whole source or just an int sourceReference (the
+  /// spec originally had only sourceReference but now supports whole sources).
+  ///
+  /// The supplied sourceReference should correspond to a ScriptRef instance
+  /// that was stored to generate the sourceReference when sent to the client.
+  @override
+  Future<void> sourceRequest(
+    Request request,
+    SourceArguments args,
+    void Function(SourceResponseBody) sendResponse,
+  ) async {
+    final storedData = _isolateManager.getStoredData(
+      args.source?.sourceReference ?? args.sourceReference,
+    );
+    if (storedData == null) {
+      throw StateError('source reference is no longer valid');
+    }
+    final thread = storedData.thread;
+    final data = storedData.data;
+    final scriptRef = data is vm.ScriptRef ? data : null;
+    if (scriptRef == null) {
+      throw StateError('source reference was not a valid script');
+    }
+
+    final script = await thread.getScript(scriptRef);
+    final scriptSource = script.source;
+    if (scriptSource == null) {
+      throw DebugAdapterException('<source not available>');
+    }
+
+    sendResponse(
+      SourceResponseBody(content: scriptSource, mimeType: dartMimeType),
+    );
+  }
+
   /// Handles a request from the client for the call stack for [args.threadId].
   ///
   /// This is usually called after we sent a [StoppedEvent] to the client
@@ -1086,13 +1145,9 @@
   }
 
   Future<void> _handleVmServiceClosed() async {
-    // Usually termination is handled by the subclass, but we use VM Service
-    // termination as a fallback for cases where this isn't possible (such as
-    // using `runInTerminal`). However, if we end the session too quickly, the
-    // editor might drop messages from stdout that haven't yet been processed
-    // so we use a short delay before handling termination this way.
-    await Future.delayed(const Duration(seconds: 1));
-    handleSessionTerminate();
+    if (terminateOnVmServiceClose) {
+      handleSessionTerminate();
+    }
   }
 
   /// Performs some setup that is common to both [launchRequest] and
diff --git a/pkg/dds/lib/src/dap/adapters/dart_cli.dart b/pkg/dds/lib/src/dap/adapters/dart_cli.dart
index 80258ca..9ad8e80 100644
--- a/pkg/dds/lib/src/dap/adapters/dart_cli.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart_cli.dart
@@ -57,6 +57,13 @@
     channel.closed.then((_) => shutdown());
   }
 
+  /// Whether the VM Service closing should be used as a signal to terminate the
+  /// debug session.
+  ///
+  /// If we have a process, we will instead use its termination as a signal to
+  /// terminate the debug session. Otherwise, we will use the VM Service close.
+  bool get terminateOnVmServiceClose => _process == null;
+
   Future<void> debuggerConnected(vm.VM vmInfo) async {
     if (!isAttach) {
       // Capture the PID from the VM Service so that we can terminate it when
diff --git a/pkg/dds/lib/src/dap/base_debug_adapter.dart b/pkg/dds/lib/src/dap/base_debug_adapter.dart
index 0bfa738..6b15fac 100644
--- a/pkg/dds/lib/src/dap/base_debug_adapter.dart
+++ b/pkg/dds/lib/src/dap/base_debug_adapter.dart
@@ -204,6 +204,12 @@
     void Function(SetExceptionBreakpointsResponseBody) sendResponse,
   );
 
+  Future<void> sourceRequest(
+    Request request,
+    SourceArguments args,
+    void Function(SourceResponseBody) sendResponse,
+  );
+
   Future<void> stackTraceRequest(
     Request request,
     StackTraceArguments args,
@@ -312,6 +318,8 @@
       handle(request, threadsRequest, _voidArgs);
     } else if (request.command == 'stackTrace') {
       handle(request, stackTraceRequest, StackTraceArguments.fromJson);
+    } else if (request.command == 'source') {
+      handle(request, sourceRequest, SourceArguments.fromJson);
     } else if (request.command == 'scopes') {
       handle(request, scopesRequest, ScopesArguments.fromJson);
     } else if (request.command == 'variables') {
diff --git a/pkg/dds/test/dap/integration/debug_test.dart b/pkg/dds/test/dap/integration/debug_test.dart
index 2266f6f..1986253 100644
--- a/pkg/dds/test/dap/integration/debug_test.dart
+++ b/pkg/dds/test/dap/integration/debug_test.dart
@@ -129,6 +129,45 @@
       final vmServiceUri = _extractVmServiceUri(outputEvents.first);
       expect(vmServiceUri.path, matches(vmServiceAuthCodePathPattern));
     });
+
+    test('can download source code from the VM', () async {
+      final client = dap.client;
+      final testFile = dap.createTestFile(simpleBreakpointProgram);
+      final breakpointLine = lineWith(testFile, '// BREAKPOINT');
+
+      // Hit the initial breakpoint.
+      final stop = await dap.client.hitBreakpoint(
+        testFile,
+        breakpointLine,
+        launch: () => client.launch(
+          testFile.path,
+          debugSdkLibraries: true,
+        ),
+      );
+
+      // Step in to go into print.
+      final responses = await Future.wait([
+        client.expectStop('step', sourceName: 'dart:core/print.dart'),
+        client.stepIn(stop.threadId!),
+      ], eagerError: true);
+      final stopResponse = responses.first as StoppedEventBody;
+
+      // Fetch the top stack frame (which should be inside print).
+      final stack = await client.getValidStack(
+        stopResponse.threadId!,
+        startFrame: 0,
+        numFrames: 1,
+      );
+      final topFrame = stack.stackFrames.first;
+
+      // SDK sources should have a sourceReference and no path.
+      expect(topFrame.source!.path, isNull);
+      expect(topFrame.source!.sourceReference, greaterThan(0));
+
+      // Source code should contain the implementation/signature of print().
+      final source = await client.getValidSource(topFrame.source!);
+      expect(source.content, contains('void print(Object? object) {'));
+    });
     // These tests can be slow due to starting up the external server process.
   }, timeout: Timeout.none);
 
diff --git a/pkg/dds/test/dap/integration/test_client.dart b/pkg/dds/test/dap/integration/test_client.dart
index dbb9305..ffd3150 100644
--- a/pkg/dds/test/dap/integration/test_client.dart
+++ b/pkg/dds/test/dap/integration/test_client.dart
@@ -217,6 +217,18 @@
     _channel.sendResponse(response);
   }
 
+  /// Sends a source request to the server to request source code for a [source]
+  /// reference that may have come from a stack frame or similar.
+  ///
+  /// Returns a Future that completes when the server returns a corresponding
+  /// response.
+  Future<Response> source(Source source) => sendRequest(
+        SourceArguments(
+          source: source,
+          sourceReference: source.sourceReference!,
+        ),
+      );
+
   /// Sends a stackTrace request to the server to request the call stack for a
   /// given thread.
   ///
@@ -475,6 +487,14 @@
         response.body as Map<String, Object?>);
   }
 
+  /// Fetches source for a sourceReference and asserts it was a valid response.
+  Future<SourceResponseBody> getValidSource(Source source) async {
+    final response = await this.source(source);
+    expect(response.success, isTrue);
+    expect(response.command, equals('source'));
+    return SourceResponseBody.fromJson(response.body as Map<String, Object?>);
+  }
+
   /// Fetches threads and asserts a valid response.
   Future<ThreadsResponseBody> getValidThreads() async {
     final response = await threads();
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.expect
index 04e78be..f506785 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.expect
@@ -52,6 +52,12 @@
   <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
   () → self::A<core::int> r = #C6;
 }
+static method _#C#new#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return new self::A::•<core::int>();
+static method _#C#fact#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return self::A::fact<core::int>();
+static method _#C#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return self::A::redirect<core::int>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -60,7 +66,7 @@
   #C4 = instantiation self::A::fact <core::int>
   #C5 = redirecting-factory-tearoff self::A::redirect
   #C6 = instantiation self::A::redirect <core::int>
-  #C7 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
-  #C8 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C3<core::int>)
-  #C9 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C5<core::int>)
+  #C7 = static-tearoff self::_#C#new#tearOff
+  #C8 = static-tearoff self::_#C#fact#tearOff
+  #C9 = static-tearoff self::_#C#redirect#tearOff
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.transformed.expect
index 04e78be..f506785 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.strong.transformed.expect
@@ -52,6 +52,12 @@
   <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
   () → self::A<core::int> r = #C6;
 }
+static method _#C#new#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return new self::A::•<core::int>();
+static method _#C#fact#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return self::A::fact<core::int>();
+static method _#C#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return self::A::redirect<core::int>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -60,7 +66,7 @@
   #C4 = instantiation self::A::fact <core::int>
   #C5 = redirecting-factory-tearoff self::A::redirect
   #C6 = instantiation self::A::redirect <core::int>
-  #C7 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
-  #C8 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C3<core::int>)
-  #C9 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C5<core::int>)
+  #C7 = static-tearoff self::_#C#new#tearOff
+  #C8 = static-tearoff self::_#C#fact#tearOff
+  #C9 = static-tearoff self::_#C#redirect#tearOff
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.expect
index 0d1f1e3..baeca6e 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.expect
@@ -52,6 +52,12 @@
   <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
   () → self::A<core::int> r = #C6;
 }
+static method _#C#new#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return new self::A::•<core::int>();
+static method _#C#fact#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return self::A::fact<core::int>();
+static method _#C#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return self::A::redirect<core::int>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -60,7 +66,7 @@
   #C4 = instantiation self::A::fact <core::int*>
   #C5 = redirecting-factory-tearoff self::A::redirect
   #C6 = instantiation self::A::redirect <core::int*>
-  #C7 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
-  #C8 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C3<core::int>)
-  #C9 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C5<core::int>)
+  #C7 = static-tearoff self::_#C#new#tearOff
+  #C8 = static-tearoff self::_#C#fact#tearOff
+  #C9 = static-tearoff self::_#C#redirect#tearOff
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.outline.expect
index 960caf1..ddd2364 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.outline.expect
@@ -25,14 +25,20 @@
 static const field () → self::A<core::int> j = self::A::fact<core::int>;
 static const field <T extends core::Object? = dynamic>() → self::A<T%> k = self::A::redirect;
 static const field () → self::A<core::int> l = self::A::redirect<core::int>;
-static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> m = <unrelated T extends core::Object? = dynamic>.(self::A::•<core::int>);
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> m = self::_#C#new#tearOff;
 static const field () → self::A<core::int> n = self::A::•<core::int>;
-static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> o = <unrelated T extends core::Object? = dynamic>.(self::A::fact<core::int>);
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> o = self::_#C#fact#tearOff;
 static const field () → self::A<core::int> p = self::A::fact<core::int>;
-static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = <unrelated T extends core::Object? = dynamic>.(self::A::redirect<core::int>);
+static const field <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = self::_#C#redirect#tearOff;
 static const field () → self::A<core::int> r = self::A::redirect<core::int>;
 static method main() → dynamic
   ;
+static method _#C#new#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return new self::A::•<core::int>();
+static method _#C#fact#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return self::A::fact<core::int>();
+static method _#C#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return self::A::redirect<core::int>();
 
 
 Extra constant evaluation status:
@@ -48,10 +54,10 @@
 Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:23:11 -> InstantiationConstant(A.fact<int*>)
 Evaluated: RedirectingFactoryTearOff @ org-dartlang-testcase:///const_tear_off.dart:24:11 -> RedirectingFactoryTearOffConstant(A.redirect)
 Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:25:11 -> InstantiationConstant(A.redirect<int*>)
-Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:26:11 -> TypedefTearOffConstant(<T>A.<int>)
+Evaluated: StaticTearOff @ org-dartlang-testcase:///const_tear_off.dart:26:11 -> StaticTearOffConstant(_#C#new#tearOff)
 Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:27:11 -> InstantiationConstant(A.<int*>)
-Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:28:11 -> TypedefTearOffConstant(<T>A.fact<int>)
+Evaluated: StaticTearOff @ org-dartlang-testcase:///const_tear_off.dart:28:11 -> StaticTearOffConstant(_#C#fact#tearOff)
 Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:29:11 -> InstantiationConstant(A.fact<int*>)
-Evaluated: TypedefTearOff @ org-dartlang-testcase:///const_tear_off.dart:30:11 -> TypedefTearOffConstant(<T>A.redirect<int>)
+Evaluated: StaticTearOff @ org-dartlang-testcase:///const_tear_off.dart:30:11 -> StaticTearOffConstant(_#C#redirect#tearOff)
 Evaluated: Instantiation @ org-dartlang-testcase:///const_tear_off.dart:31:11 -> InstantiationConstant(A.redirect<int*>)
-Extra constant evaluation: evaluated: 21, effectively constant: 18
+Extra constant evaluation: evaluated: 24, effectively constant: 18
diff --git a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.transformed.expect
index 0d1f1e3..baeca6e 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/const_tear_off.dart.weak.transformed.expect
@@ -52,6 +52,12 @@
   <unrelated T extends core::Object? = dynamic>() → self::A<core::int> q = #C9;
   () → self::A<core::int> r = #C6;
 }
+static method _#C#new#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return new self::A::•<core::int>();
+static method _#C#fact#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return self::A::fact<core::int>();
+static method _#C#redirect#tearOff<unrelated T extends core::Object? = dynamic>() → self::A<core::int>
+  return self::A::redirect<core::int>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -60,7 +66,7 @@
   #C4 = instantiation self::A::fact <core::int*>
   #C5 = redirecting-factory-tearoff self::A::redirect
   #C6 = instantiation self::A::redirect <core::int*>
-  #C7 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C1<core::int>)
-  #C8 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C3<core::int>)
-  #C9 = typedef-tearoff <unrelated T extends core::Object? = dynamic>.(#C5<core::int>)
+  #C7 = static-tearoff self::_#C#new#tearOff
+  #C8 = static-tearoff self::_#C#fact#tearOff
+  #C9 = static-tearoff self::_#C#redirect#tearOff
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.expect
index ceaf4af..91acfd5 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.expect
@@ -90,6 +90,20 @@
   core::String typeName = (#C7).{core::Type::toString}(){() → core::String};
   core::String functionTypeName = (local<core::int>).{core::Object::runtimeType}{core::Type}.{core::Type::toString}(){() → core::String};
 }
+static method _#ListList#new#tearOff<T extends core::Object? = dynamic>([core::int? length = #C9]) → core::List<core::List<self::_#ListList#new#tearOff::T%>>
+  return core::List::•<core::List<self::_#ListList#new#tearOff::T%>>(length);
+static method _#ListList#filled#tearOff<T extends core::Object? = dynamic>(core::int length, core::List<self::_#ListList#filled#tearOff::T%> fill, {core::bool growable = #C10}) → core::List<core::List<self::_#ListList#filled#tearOff::T%>>
+  return core::List::filled<core::List<self::_#ListList#filled#tearOff::T%>>(length, fill, growable: growable);
+static method _#ListList#empty#tearOff<T extends core::Object? = dynamic>({core::bool growable = #C10}) → core::List<core::List<self::_#ListList#empty#tearOff::T%>>
+  return core::List::empty<core::List<self::_#ListList#empty#tearOff::T%>>(growable: growable);
+static method _#ListList#from#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#from#tearOff::T%>>
+  return core::List::from<core::List<self::_#ListList#from#tearOff::T%>>(elements, growable: growable);
+static method _#ListList#of#tearOff<T extends core::Object? = dynamic>(core::Iterable<core::List<self::_#ListList#of#tearOff::T%>> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#of#tearOff::T%>>
+  return core::List::of<core::List<self::_#ListList#of#tearOff::T%>>(elements, growable: growable);
+static method _#ListList#generate#tearOff<T extends core::Object? = dynamic>(core::int length, (core::int) → core::List<self::_#ListList#generate#tearOff::T%> generator, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#generate#tearOff::T%>>
+  return core::List::generate<core::List<self::_#ListList#generate#tearOff::T%>>(length, generator, growable: growable);
+static method _#ListList#unmodifiable#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements) → core::List<core::List<self::_#ListList#unmodifiable#tearOff::T%>>
+  return core::List::unmodifiable<core::List<self::_#ListList#unmodifiable#tearOff::T%>>(elements);
 
 constants  {
   #C1 = static-tearoff self::C::stat
@@ -100,4 +114,7 @@
   #C6 = instantiation self::Ext|estat <core::int>
   #C7 = TypeLiteralConstant(core::List<core::int>)
   #C8 = TypeLiteralConstant(core::List<core::List<core::int>>)
+  #C9 = null
+  #C10 = false
+  #C11 = true
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.transformed.expect
index aa394b3..5ba5c40 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.strong.transformed.expect
@@ -98,6 +98,20 @@
   core::String typeName = (#C7).{core::Type::toString}(){() → core::String};
   core::String functionTypeName = (local<core::int>).{core::Object::runtimeType}{core::Type}.{core::Type::toString}(){() → core::String};
 }
+static method _#ListList#new#tearOff<T extends core::Object? = dynamic>([core::int? length = #C9]) → core::List<core::List<self::_#ListList#new#tearOff::T%>>
+  return core::_List::•<core::List<self::_#ListList#new#tearOff::T%>>(length);
+static method _#ListList#filled#tearOff<T extends core::Object? = dynamic>(core::int length, core::List<self::_#ListList#filled#tearOff::T%> fill, {core::bool growable = #C10}) → core::List<core::List<self::_#ListList#filled#tearOff::T%>>
+  return core::List::filled<core::List<self::_#ListList#filled#tearOff::T%>>(length, fill, growable: growable);
+static method _#ListList#empty#tearOff<T extends core::Object? = dynamic>({core::bool growable = #C10}) → core::List<core::List<self::_#ListList#empty#tearOff::T%>>
+  return core::List::empty<core::List<self::_#ListList#empty#tearOff::T%>>(growable: growable);
+static method _#ListList#from#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#from#tearOff::T%>>
+  return core::List::from<core::List<self::_#ListList#from#tearOff::T%>>(elements, growable: growable);
+static method _#ListList#of#tearOff<T extends core::Object? = dynamic>(core::Iterable<core::List<self::_#ListList#of#tearOff::T%>> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#of#tearOff::T%>>
+  return core::List::of<core::List<self::_#ListList#of#tearOff::T%>>(elements, growable: growable);
+static method _#ListList#generate#tearOff<T extends core::Object? = dynamic>(core::int length, (core::int) → core::List<self::_#ListList#generate#tearOff::T%> generator, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#generate#tearOff::T%>>
+  return core::List::generate<core::List<self::_#ListList#generate#tearOff::T%>>(length, generator, growable: growable);
+static method _#ListList#unmodifiable#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements) → core::List<core::List<self::_#ListList#unmodifiable#tearOff::T%>>
+  return core::List::unmodifiable<core::List<self::_#ListList#unmodifiable#tearOff::T%>>(elements);
 
 constants  {
   #C1 = static-tearoff self::C::stat
@@ -108,4 +122,7 @@
   #C6 = instantiation self::Ext|estat <core::int>
   #C7 = TypeLiteralConstant(core::List<core::int>)
   #C8 = TypeLiteralConstant(core::List<core::List<core::int>>)
+  #C9 = null
+  #C10 = false
+  #C11 = true
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.expect
index ea4ceb1..d11b021 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.expect
@@ -90,6 +90,20 @@
   core::String typeName = (#C7).{core::Type::toString}(){() → core::String};
   core::String functionTypeName = (local<core::int>).{core::Object::runtimeType}{core::Type}.{core::Type::toString}(){() → core::String};
 }
+static method _#ListList#new#tearOff<T extends core::Object? = dynamic>([core::int? length = #C9]) → core::List<core::List<self::_#ListList#new#tearOff::T%>>
+  return core::List::•<core::List<self::_#ListList#new#tearOff::T%>>(length);
+static method _#ListList#filled#tearOff<T extends core::Object? = dynamic>(core::int length, core::List<self::_#ListList#filled#tearOff::T%> fill, {core::bool growable = #C10}) → core::List<core::List<self::_#ListList#filled#tearOff::T%>>
+  return core::List::filled<core::List<self::_#ListList#filled#tearOff::T%>>(length, fill, growable: growable);
+static method _#ListList#empty#tearOff<T extends core::Object? = dynamic>({core::bool growable = #C10}) → core::List<core::List<self::_#ListList#empty#tearOff::T%>>
+  return core::List::empty<core::List<self::_#ListList#empty#tearOff::T%>>(growable: growable);
+static method _#ListList#from#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#from#tearOff::T%>>
+  return core::List::from<core::List<self::_#ListList#from#tearOff::T%>>(elements, growable: growable);
+static method _#ListList#of#tearOff<T extends core::Object? = dynamic>(core::Iterable<core::List<self::_#ListList#of#tearOff::T%>> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#of#tearOff::T%>>
+  return core::List::of<core::List<self::_#ListList#of#tearOff::T%>>(elements, growable: growable);
+static method _#ListList#generate#tearOff<T extends core::Object? = dynamic>(core::int length, (core::int) → core::List<self::_#ListList#generate#tearOff::T%> generator, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#generate#tearOff::T%>>
+  return core::List::generate<core::List<self::_#ListList#generate#tearOff::T%>>(length, generator, growable: growable);
+static method _#ListList#unmodifiable#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements) → core::List<core::List<self::_#ListList#unmodifiable#tearOff::T%>>
+  return core::List::unmodifiable<core::List<self::_#ListList#unmodifiable#tearOff::T%>>(elements);
 
 constants  {
   #C1 = static-tearoff self::C::stat
@@ -100,4 +114,7 @@
   #C6 = instantiation self::Ext|estat <core::int*>
   #C7 = TypeLiteralConstant(core::List<core::int*>*)
   #C8 = TypeLiteralConstant(core::List<core::List<core::int*>*>*)
+  #C9 = null
+  #C10 = false
+  #C11 = true
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.outline.expect
index 6476dce..989a2cb 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.outline.expect
@@ -57,3 +57,17 @@
   return () → void => self::Ext|emethod(#this);
 static method main() → void
   ;
+static method _#ListList#new#tearOff<T extends core::Object? = dynamic>([core::int? length]) → core::List<core::List<self::_#ListList#new#tearOff::T%>>
+  return core::List::•<core::List<self::_#ListList#new#tearOff::T%>>(length);
+static method _#ListList#filled#tearOff<T extends core::Object? = dynamic>(core::int length, core::List<self::_#ListList#filled#tearOff::T%> fill, {core::bool growable}) → core::List<core::List<self::_#ListList#filled#tearOff::T%>>
+  return core::List::filled<core::List<self::_#ListList#filled#tearOff::T%>>(length, fill, growable: growable);
+static method _#ListList#empty#tearOff<T extends core::Object? = dynamic>({core::bool growable}) → core::List<core::List<self::_#ListList#empty#tearOff::T%>>
+  return core::List::empty<core::List<self::_#ListList#empty#tearOff::T%>>(growable: growable);
+static method _#ListList#from#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements, {core::bool growable}) → core::List<core::List<self::_#ListList#from#tearOff::T%>>
+  return core::List::from<core::List<self::_#ListList#from#tearOff::T%>>(elements, growable: growable);
+static method _#ListList#of#tearOff<T extends core::Object? = dynamic>(core::Iterable<core::List<self::_#ListList#of#tearOff::T%>> elements, {core::bool growable}) → core::List<core::List<self::_#ListList#of#tearOff::T%>>
+  return core::List::of<core::List<self::_#ListList#of#tearOff::T%>>(elements, growable: growable);
+static method _#ListList#generate#tearOff<T extends core::Object? = dynamic>(core::int length, (core::int) → core::List<self::_#ListList#generate#tearOff::T%> generator, {core::bool growable}) → core::List<core::List<self::_#ListList#generate#tearOff::T%>>
+  return core::List::generate<core::List<self::_#ListList#generate#tearOff::T%>>(length, generator, growable: growable);
+static method _#ListList#unmodifiable#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements) → core::List<core::List<self::_#ListList#unmodifiable#tearOff::T%>>
+  return core::List::unmodifiable<core::List<self::_#ListList#unmodifiable#tearOff::T%>>(elements);
diff --git a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.transformed.expect
index fc6c975..c8e2bba 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/explicit_instantiation.dart.weak.transformed.expect
@@ -98,6 +98,20 @@
   core::String typeName = (#C7).{core::Type::toString}(){() → core::String};
   core::String functionTypeName = (local<core::int>).{core::Object::runtimeType}{core::Type}.{core::Type::toString}(){() → core::String};
 }
+static method _#ListList#new#tearOff<T extends core::Object? = dynamic>([core::int? length = #C9]) → core::List<core::List<self::_#ListList#new#tearOff::T%>>
+  return core::_List::•<core::List<self::_#ListList#new#tearOff::T%>>(length);
+static method _#ListList#filled#tearOff<T extends core::Object? = dynamic>(core::int length, core::List<self::_#ListList#filled#tearOff::T%> fill, {core::bool growable = #C10}) → core::List<core::List<self::_#ListList#filled#tearOff::T%>>
+  return core::List::filled<core::List<self::_#ListList#filled#tearOff::T%>>(length, fill, growable: growable);
+static method _#ListList#empty#tearOff<T extends core::Object? = dynamic>({core::bool growable = #C10}) → core::List<core::List<self::_#ListList#empty#tearOff::T%>>
+  return core::List::empty<core::List<self::_#ListList#empty#tearOff::T%>>(growable: growable);
+static method _#ListList#from#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#from#tearOff::T%>>
+  return core::List::from<core::List<self::_#ListList#from#tearOff::T%>>(elements, growable: growable);
+static method _#ListList#of#tearOff<T extends core::Object? = dynamic>(core::Iterable<core::List<self::_#ListList#of#tearOff::T%>> elements, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#of#tearOff::T%>>
+  return core::List::of<core::List<self::_#ListList#of#tearOff::T%>>(elements, growable: growable);
+static method _#ListList#generate#tearOff<T extends core::Object? = dynamic>(core::int length, (core::int) → core::List<self::_#ListList#generate#tearOff::T%> generator, {core::bool growable = #C11}) → core::List<core::List<self::_#ListList#generate#tearOff::T%>>
+  return core::List::generate<core::List<self::_#ListList#generate#tearOff::T%>>(length, generator, growable: growable);
+static method _#ListList#unmodifiable#tearOff<T extends core::Object? = dynamic>(core::Iterable<dynamic> elements) → core::List<core::List<self::_#ListList#unmodifiable#tearOff::T%>>
+  return core::List::unmodifiable<core::List<self::_#ListList#unmodifiable#tearOff::T%>>(elements);
 
 constants  {
   #C1 = static-tearoff self::C::stat
@@ -108,4 +122,7 @@
   #C6 = instantiation self::Ext|estat <core::int*>
   #C7 = TypeLiteralConstant(core::List<core::int*>*)
   #C8 = TypeLiteralConstant(core::List<core::List<core::int*>*>*)
+  #C9 = null
+  #C10 = false
+  #C11 = true
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.expect
index ce055a4..ba4c564 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.expect
@@ -49,6 +49,12 @@
   if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
     throw "Expected ${expected}, actual ${actual}";
 }
+static method _#F#new#tearOff<X extends core::num>() → self::A<self::_#F#new#tearOff::X>
+  return new self::A::•<self::_#F#new#tearOff::X>();
+static method _#G#new#tearOff<unrelated Y extends core::Object? = dynamic>() → self::A<core::int>
+  return new self::A::•<core::int>();
+static method _#H#new#tearOff<X extends core::Object? = dynamic, unrelated Y extends core::Object? = dynamic>() → self::A<self::_#H#new#tearOff::X%>
+  return new self::A::•<self::_#H#new#tearOff::X%>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
diff --git a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.transformed.expect
index 0f0953f..966f2f6 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.strong.transformed.expect
@@ -49,6 +49,12 @@
   if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
     throw "Expected ${expected}, actual ${actual}";
 }
+static method _#F#new#tearOff<X extends core::num>() → self::A<self::_#F#new#tearOff::X>
+  return new self::A::•<self::_#F#new#tearOff::X>();
+static method _#G#new#tearOff<unrelated Y extends core::Object? = dynamic>() → self::A<core::int>
+  return new self::A::•<core::int>();
+static method _#H#new#tearOff<X extends core::Object? = dynamic, unrelated Y extends core::Object? = dynamic>() → self::A<self::_#H#new#tearOff::X%>
+  return new self::A::•<self::_#H#new#tearOff::X%>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -62,4 +68,4 @@
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:32:3 -> BoolConstant(true)
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:34:3 -> BoolConstant(true)
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:35:3 -> BoolConstant(true)
-Extra constant evaluation: evaluated: 33, effectively constant: 6
+Extra constant evaluation: evaluated: 36, effectively constant: 6
diff --git a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.expect
index 1121885..379376e 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.expect
@@ -49,6 +49,12 @@
   if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
     throw "Expected ${expected}, actual ${actual}";
 }
+static method _#F#new#tearOff<X extends core::num>() → self::A<self::_#F#new#tearOff::X>
+  return new self::A::•<self::_#F#new#tearOff::X>();
+static method _#G#new#tearOff<unrelated Y extends core::Object? = dynamic>() → self::A<core::int>
+  return new self::A::•<core::int>();
+static method _#H#new#tearOff<X extends core::Object? = dynamic, unrelated Y extends core::Object? = dynamic>() → self::A<self::_#H#new#tearOff::X%>
+  return new self::A::•<self::_#H#new#tearOff::X%>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
diff --git a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.outline.expect
index deb3803..6063fc6 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.outline.expect
@@ -12,19 +12,25 @@
 static final field core::bool inSoundMode;
 static const field () → self::A<core::int> f1a = self::A::•<core::int>;
 static const field () → self::A<core::int> f1b = self::A::•<core::int>;
-static const field () → self::A<core::int> f1c = <X extends core::num>.(self::A::•<X>)<core::int>;
+static const field () → self::A<core::int> f1c = self::_#F#new#tearOff<core::int>;
 static const field () → self::A<core::int> g1a = self::A::•<core::int>;
 static const field () → self::A<core::int> g1b = self::A::•<core::int>;
-static const field () → self::A<core::int> g1c = <unrelated Y extends core::Object? = dynamic>.(self::A::•<core::int>)<dynamic>;
+static const field () → self::A<core::int> g1c = self::_#G#new#tearOff<dynamic>;
 static const field () → self::A<core::int> h1a = self::A::•<core::int>;
 static const field () → self::A<core::int> h1b = self::A::•<core::int>;
-static const field () → self::A<core::int> h1c = <X extends core::Object? = dynamic, unrelated Y extends core::Object? = dynamic>.(self::A::•<X%>)<core::int, dynamic>;
+static const field () → self::A<core::int> h1c = self::_#H#new#tearOff<core::int, dynamic>;
 static method main() → dynamic
   ;
 static method test<T extends core::num>() → dynamic
   ;
 static method expect(dynamic expected, dynamic actual) → dynamic
   ;
+static method _#F#new#tearOff<X extends core::num>() → self::A<self::_#F#new#tearOff::X>
+  return new self::A::•<self::_#F#new#tearOff::X>();
+static method _#G#new#tearOff<unrelated Y extends core::Object? = dynamic>() → self::A<core::int>
+  return new self::A::•<core::int>();
+static method _#H#new#tearOff<X extends core::Object? = dynamic, unrelated Y extends core::Object? = dynamic>() → self::A<self::_#H#new#tearOff::X%>
+  return new self::A::•<self::_#H#new#tearOff::X%>();
 
 
 Extra constant evaluation status:
@@ -37,4 +43,4 @@
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:21:13 -> InstantiationConstant(A.<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:22:13 -> InstantiationConstant(A.<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:23:31 -> InstantiationConstant(A.<int*>)
-Extra constant evaluation: evaluated: 9, effectively constant: 9
+Extra constant evaluation: evaluated: 12, effectively constant: 9
diff --git a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.transformed.expect
index 74079d8..be2d1f5 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/inferred_non_proper_rename.dart.weak.transformed.expect
@@ -49,6 +49,12 @@
   if(!(expected =={core::Object::==}{(core::Object) → core::bool} actual))
     throw "Expected ${expected}, actual ${actual}";
 }
+static method _#F#new#tearOff<X extends core::num>() → self::A<self::_#F#new#tearOff::X>
+  return new self::A::•<self::_#F#new#tearOff::X>();
+static method _#G#new#tearOff<unrelated Y extends core::Object? = dynamic>() → self::A<core::int>
+  return new self::A::•<core::int>();
+static method _#H#new#tearOff<X extends core::Object? = dynamic, unrelated Y extends core::Object? = dynamic>() → self::A<self::_#H#new#tearOff::X%>
+  return new self::A::•<self::_#H#new#tearOff::X%>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -62,4 +68,4 @@
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:32:3 -> BoolConstant(true)
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:34:3 -> BoolConstant(true)
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:35:3 -> BoolConstant(true)
-Extra constant evaluation: evaluated: 33, effectively constant: 6
+Extra constant evaluation: evaluated: 36, effectively constant: 6
diff --git a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.expect
index 2949323..6f4cc26 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.expect
@@ -65,6 +65,10 @@
 static method test5() → dynamic
   return invalid-expression "This assertion failed.";
 static method main() → dynamic {}
+static method _#B4#new#tearOff<T extends core::int>() → self::A4<self::_#B4#new#tearOff::T>
+  return new self::A4::•<self::_#B4#new#tearOff::T>();
+static method _#B5#new#tearOff<unrelated T extends core::List<core::Object?>, unrelated S extends Null>() → self::A5<core::List<dynamic>, Never?>
+  return new self::A5::•<core::List<dynamic>, Never?>();
 
 constants  {
   #C1 = self::StaticIdentityTest {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.transformed.expect
index 2949323..6f4cc26 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.strong.transformed.expect
@@ -65,6 +65,10 @@
 static method test5() → dynamic
   return invalid-expression "This assertion failed.";
 static method main() → dynamic {}
+static method _#B4#new#tearOff<T extends core::int>() → self::A4<self::_#B4#new#tearOff::T>
+  return new self::A4::•<self::_#B4#new#tearOff::T>();
+static method _#B5#new#tearOff<unrelated T extends core::List<core::Object?>, unrelated S extends Null>() → self::A5<core::List<dynamic>, Never?>
+  return new self::A5::•<core::List<dynamic>, Never?>();
 
 constants  {
   #C1 = self::StaticIdentityTest {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.expect
index 2949323..6f4cc26 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.expect
@@ -65,6 +65,10 @@
 static method test5() → dynamic
   return invalid-expression "This assertion failed.";
 static method main() → dynamic {}
+static method _#B4#new#tearOff<T extends core::int>() → self::A4<self::_#B4#new#tearOff::T>
+  return new self::A4::•<self::_#B4#new#tearOff::T>();
+static method _#B5#new#tearOff<unrelated T extends core::List<core::Object?>, unrelated S extends Null>() → self::A5<core::List<dynamic>, Never?>
+  return new self::A5::•<core::List<dynamic>, Never?>();
 
 constants  {
   #C1 = self::StaticIdentityTest {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.outline.expect
index fd75da2..13089c3 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.outline.expect
@@ -44,3 +44,7 @@
   ;
 static method main() → dynamic
   ;
+static method _#B4#new#tearOff<T extends core::int>() → self::A4<self::_#B4#new#tearOff::T>
+  return new self::A4::•<self::_#B4#new#tearOff::T>();
+static method _#B5#new#tearOff<unrelated T extends core::List<core::Object?>, unrelated S extends Null>() → self::A5<core::List<dynamic>, Never?>
+  return new self::A5::•<core::List<dynamic>, Never?>();
diff --git a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.transformed.expect
index 2949323..6f4cc26 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/simple_proper_rename_identity.dart.weak.transformed.expect
@@ -65,6 +65,10 @@
 static method test5() → dynamic
   return invalid-expression "This assertion failed.";
 static method main() → dynamic {}
+static method _#B4#new#tearOff<T extends core::int>() → self::A4<self::_#B4#new#tearOff::T>
+  return new self::A4::•<self::_#B4#new#tearOff::T>();
+static method _#B5#new#tearOff<unrelated T extends core::List<core::Object?>, unrelated S extends Null>() → self::A5<core::List<dynamic>, Never?>
+  return new self::A5::•<core::List<dynamic>, Never?>();
 
 constants  {
   #C1 = self::StaticIdentityTest {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.expect
index e445535..ae2f0d4 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.expect
@@ -15,21 +15,11 @@
 // B<num> Function() test9() => DB1.new; // Error.
 //                              ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
-//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-// B<Y> Function<Y>() test17() => DB2.new; // Error.
-//                                ^
-//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y>() test17() => DB2.new; // Error.
 //                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
-//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
-//                                   ^
-//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
@@ -97,10 +87,7 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y>() test17() => DB2.new; // Error.
-                               ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
- - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-B<Y> Function<Y>() test17() => DB2.new; // Error.
-                               ^" in (#C12) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%> as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
+                               ^" in (#C12) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
 static method test18() → () → self::B<core::num>
   return #C9;
 static method test19() → () → self::B<core::num>
@@ -115,13 +102,24 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
-                                  ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
- - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
-                                  ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%> as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
+                                  ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
 static method test24() → () → self::B<core::String>
   return #C14;
 static method main() → dynamic {}
+static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
+  return new self::A::•();
+static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
+  return new self::B::•<self::_#DB2#new#tearOff::X>();
+static method _#DB2#foo#tearOff<X extends core::num>() → self::B<self::_#DB2#foo#tearOff::X>
+  return new self::B::foo<self::_#DB2#foo#tearOff::X>();
+static method _#DB2#bar#tearOff<X extends core::num>() → self::B<self::_#DB2#bar#tearOff::X>
+  return self::B::bar<self::_#DB2#bar#tearOff::X>();
+static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
+  return new self::B::•<self::_#DB3#new#tearOff::X>();
+static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#foo#tearOff::X>
+  return new self::B::foo<self::_#DB3#foo#tearOff::X>();
+static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#bar#tearOff::X>
+  return self::B::bar<self::_#DB3#bar#tearOff::X>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -135,7 +133,7 @@
   #C9 = instantiation self::B::• <core::num>
   #C10 = instantiation self::B::foo <core::num>
   #C11 = instantiation self::B::bar <core::num>
-  #C12 = typedef-tearoff <X extends core::num>.(#C3<X>)
-  #C13 = typedef-tearoff <X extends core::num, unrelated Y extends core::String>.(#C3<X>)
+  #C12 = static-tearoff self::_#DB2#new#tearOff
+  #C13 = static-tearoff self::_#DB3#new#tearOff
   #C14 = instantiation self::B::• <Never>
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.transformed.expect
index ddc1a03..ae2f0d4 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.strong.transformed.expect
@@ -15,21 +15,11 @@
 // B<num> Function() test9() => DB1.new; // Error.
 //                              ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
-//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-// B<Y> Function<Y>() test17() => DB2.new; // Error.
-//                                ^
-//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y>() test17() => DB2.new; // Error.
 //                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
-//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
-//                                   ^
-//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
@@ -97,9 +87,6 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y>() test17() => DB2.new; // Error.
-                               ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
- - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-B<Y> Function<Y>() test17() => DB2.new; // Error.
                                ^" in (#C12) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
 static method test18() → () → self::B<core::num>
   return #C9;
@@ -115,13 +102,24 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
-                                  ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
- - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
                                   ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
 static method test24() → () → self::B<core::String>
   return #C14;
 static method main() → dynamic {}
+static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
+  return new self::A::•();
+static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
+  return new self::B::•<self::_#DB2#new#tearOff::X>();
+static method _#DB2#foo#tearOff<X extends core::num>() → self::B<self::_#DB2#foo#tearOff::X>
+  return new self::B::foo<self::_#DB2#foo#tearOff::X>();
+static method _#DB2#bar#tearOff<X extends core::num>() → self::B<self::_#DB2#bar#tearOff::X>
+  return self::B::bar<self::_#DB2#bar#tearOff::X>();
+static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
+  return new self::B::•<self::_#DB3#new#tearOff::X>();
+static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#foo#tearOff::X>
+  return new self::B::foo<self::_#DB3#foo#tearOff::X>();
+static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#bar#tearOff::X>
+  return self::B::bar<self::_#DB3#bar#tearOff::X>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -135,7 +133,7 @@
   #C9 = instantiation self::B::• <core::num>
   #C10 = instantiation self::B::foo <core::num>
   #C11 = instantiation self::B::bar <core::num>
-  #C12 = typedef-tearoff <X extends core::num>.(#C3<X>)
-  #C13 = typedef-tearoff <X extends core::num, unrelated Y extends core::String>.(#C3<X>)
+  #C12 = static-tearoff self::_#DB2#new#tearOff
+  #C13 = static-tearoff self::_#DB3#new#tearOff
   #C14 = instantiation self::B::• <Never>
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.expect
index 835e035..a1d6e2f 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.expect
@@ -15,21 +15,11 @@
 // B<num> Function() test9() => DB1.new; // Error.
 //                              ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
-//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-// B<Y> Function<Y>() test17() => DB2.new; // Error.
-//                                ^
-//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y>() test17() => DB2.new; // Error.
 //                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
-//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
-//                                   ^
-//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
@@ -97,10 +87,7 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y>() test17() => DB2.new; // Error.
-                               ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
- - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-B<Y> Function<Y>() test17() => DB2.new; // Error.
-                               ^" in (#C12) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%> as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
+                               ^" in (#C12) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
 static method test18() → () → self::B<core::num>
   return #C9;
 static method test19() → () → self::B<core::num>
@@ -115,13 +102,24 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
-                                  ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
- - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
-                                  ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%> as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
+                                  ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
 static method test24() → () → self::B<core::String>
   return #C14;
 static method main() → dynamic {}
+static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
+  return new self::A::•();
+static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
+  return new self::B::•<self::_#DB2#new#tearOff::X>();
+static method _#DB2#foo#tearOff<X extends core::num>() → self::B<self::_#DB2#foo#tearOff::X>
+  return new self::B::foo<self::_#DB2#foo#tearOff::X>();
+static method _#DB2#bar#tearOff<X extends core::num>() → self::B<self::_#DB2#bar#tearOff::X>
+  return self::B::bar<self::_#DB2#bar#tearOff::X>();
+static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
+  return new self::B::•<self::_#DB3#new#tearOff::X>();
+static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#foo#tearOff::X>
+  return new self::B::foo<self::_#DB3#foo#tearOff::X>();
+static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#bar#tearOff::X>
+  return self::B::bar<self::_#DB3#bar#tearOff::X>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -135,7 +133,7 @@
   #C9 = instantiation self::B::• <core::num*>
   #C10 = instantiation self::B::foo <core::num*>
   #C11 = instantiation self::B::bar <core::num*>
-  #C12 = typedef-tearoff <X extends core::num>.(#C3<X>)
-  #C13 = typedef-tearoff <X extends core::num, unrelated Y extends core::String>.(#C3<X>)
+  #C12 = static-tearoff self::_#DB2#new#tearOff
+  #C13 = static-tearoff self::_#DB3#new#tearOff
   #C14 = instantiation self::B::• <Never*>
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.outline.expect
index fda6d4f..7a1ba29 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.outline.expect
@@ -69,3 +69,17 @@
   ;
 static method main() → dynamic
   ;
+static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
+  return new self::A::•();
+static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
+  return new self::B::•<self::_#DB2#new#tearOff::X>();
+static method _#DB2#foo#tearOff<X extends core::num>() → self::B<self::_#DB2#foo#tearOff::X>
+  return new self::B::foo<self::_#DB2#foo#tearOff::X>();
+static method _#DB2#bar#tearOff<X extends core::num>() → self::B<self::_#DB2#bar#tearOff::X>
+  return self::B::bar<self::_#DB2#bar#tearOff::X>();
+static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
+  return new self::B::•<self::_#DB3#new#tearOff::X>();
+static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#foo#tearOff::X>
+  return new self::B::foo<self::_#DB3#foo#tearOff::X>();
+static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#bar#tearOff::X>
+  return self::B::bar<self::_#DB3#bar#tearOff::X>();
diff --git a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.transformed.expect
index f6769ba..a1d6e2f 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart.weak.transformed.expect
@@ -15,21 +15,11 @@
 // B<num> Function() test9() => DB1.new; // Error.
 //                              ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
-//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-// B<Y> Function<Y>() test17() => DB2.new; // Error.
-//                                ^
-//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y>() test17() => DB2.new; // Error.
 //                                ^
 //
-// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
-//  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
-//                                   ^
-//
 // pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
 //  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 // B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
@@ -97,9 +87,6 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y>() test17() => DB2.new; // Error.
-                               ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
- - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-B<Y> Function<Y>() test17() => DB2.new; // Error.
                                ^" in (#C12) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
 static method test18() → () → self::B<core::num>
   return #C9;
@@ -115,13 +102,24 @@
   return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
  - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
 B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
-                                  ^" in invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
- - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
-B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
                                   ^" in (#C13) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
 static method test24() → () → self::B<core::String>
   return #C14;
 static method main() → dynamic {}
+static method _#DA2#new#tearOff<unrelated X extends core::num>() → self::A
+  return new self::A::•();
+static method _#DB2#new#tearOff<X extends core::num>() → self::B<self::_#DB2#new#tearOff::X>
+  return new self::B::•<self::_#DB2#new#tearOff::X>();
+static method _#DB2#foo#tearOff<X extends core::num>() → self::B<self::_#DB2#foo#tearOff::X>
+  return new self::B::foo<self::_#DB2#foo#tearOff::X>();
+static method _#DB2#bar#tearOff<X extends core::num>() → self::B<self::_#DB2#bar#tearOff::X>
+  return self::B::bar<self::_#DB2#bar#tearOff::X>();
+static method _#DB3#new#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#new#tearOff::X>
+  return new self::B::•<self::_#DB3#new#tearOff::X>();
+static method _#DB3#foo#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#foo#tearOff::X>
+  return new self::B::foo<self::_#DB3#foo#tearOff::X>();
+static method _#DB3#bar#tearOff<X extends core::num, unrelated Y extends core::String>() → self::B<self::_#DB3#bar#tearOff::X>
+  return self::B::bar<self::_#DB3#bar#tearOff::X>();
 
 constants  {
   #C1 = constructor-tearoff self::A::•
@@ -135,7 +133,7 @@
   #C9 = instantiation self::B::• <core::num*>
   #C10 = instantiation self::B::foo <core::num*>
   #C11 = instantiation self::B::bar <core::num*>
-  #C12 = typedef-tearoff <X extends core::num>.(#C3<X>)
-  #C13 = typedef-tearoff <X extends core::num, unrelated Y extends core::String>.(#C3<X>)
+  #C12 = static-tearoff self::_#DB2#new#tearOff
+  #C13 = static-tearoff self::_#DB3#new#tearOff
   #C14 = instantiation self::B::• <Never*>
 }
diff --git a/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect
index 525fab5..4e5f43d 100644
--- a/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/mock_http_headers.dart.weak.outline.expect
@@ -170,8 +170,8 @@
 Evaluated: SymbolLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> SymbolConstant(#noFolding)
 Evaluated: ListLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> ListConstant(const <Type*>[])
 Evaluated: MapLiteral @ org-dartlang-testcase:///mock_http_headers.dart:13:7 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:774:8 -> SymbolConstant(#clear)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:774:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:774:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:774:8 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:782:8 -> SymbolConstant(#clear)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:782:8 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:782:8 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:782:8 -> InstanceConstant(const _ImmutableMap<Symbol*, dynamic>{_ImmutableMap._kvPairs: const <dynamic>[]})
 Extra constant evaluation: evaluated: 268, effectively constant: 91
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.strong.expect
index 68d1353..ebbaed4 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.strong.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.strong.expect
@@ -214,3 +214,5 @@
 static method bar3b<X extends self::A<self::A<self::A<core::int>>>>() → dynamic
   return throw 42;
 static method main() → dynamic {}
+static method _#B#new#tearOff<X extends self::A<self::_#B#new#tearOff::X> = self::A<dynamic>>() → self::A<self::_#B#new#tearOff::X>
+  return new self::A::•<self::_#B#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.strong.transformed.expect
index 68d1353..ebbaed4 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.strong.transformed.expect
@@ -214,3 +214,5 @@
 static method bar3b<X extends self::A<self::A<self::A<core::int>>>>() → dynamic
   return throw 42;
 static method main() → dynamic {}
+static method _#B#new#tearOff<X extends self::A<self::_#B#new#tearOff::X> = self::A<dynamic>>() → self::A<self::_#B#new#tearOff::X>
+  return new self::A::•<self::_#B#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.expect
index 68d1353..ebbaed4 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.expect
@@ -214,3 +214,5 @@
 static method bar3b<X extends self::A<self::A<self::A<core::int>>>>() → dynamic
   return throw 42;
 static method main() → dynamic {}
+static method _#B#new#tearOff<X extends self::A<self::_#B#new#tearOff::X> = self::A<dynamic>>() → self::A<self::_#B#new#tearOff::X>
+  return new self::A::•<self::_#B#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.outline.expect
index 224c9fc..bde9db2 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.outline.expect
@@ -192,3 +192,5 @@
   ;
 static method main() → dynamic
   ;
+static method _#B#new#tearOff<X extends self::A<self::_#B#new#tearOff::X> = self::A<dynamic>>() → self::A<self::_#B#new#tearOff::X>
+  return new self::A::•<self::_#B#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.transformed.expect
index 68d1353..ebbaed4 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks.dart.weak.transformed.expect
@@ -214,3 +214,5 @@
 static method bar3b<X extends self::A<self::A<self::A<core::int>>>>() → dynamic
   return throw 42;
 static method main() → dynamic {}
+static method _#B#new#tearOff<X extends self::A<self::_#B#new#tearOff::X> = self::A<dynamic>>() → self::A<self::_#B#new#tearOff::X>
+  return new self::A::•<self::_#B#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.strong.expect
index 221969e..7e82df9 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.strong.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.strong.expect
@@ -36,3 +36,21 @@
   core::String a;
 }
 static method main() → dynamic {}
+static method _#A#fromCharCodes#tearOff<unrelated X extends core::int>(core::Iterable<core::int> charCodes, [core::int start = #C1, core::int? end = #C2]) → core::String
+  return core::String::fromCharCodes(charCodes, start, end);
+static method _#A#fromCharCode#tearOff<unrelated X extends core::int>(core::int charCode) → core::String
+  return core::String::fromCharCode(charCode);
+static method _#A#fromEnvironment#tearOff<unrelated X extends core::int>(core::String name, {core::String defaultValue = #C3}) → core::String
+  return core::String::fromEnvironment(name, defaultValue: defaultValue);
+static method _#B#fromCharCodes#tearOff<unrelated X extends core::int>(core::Iterable<core::int> charCodes, [core::int start = #C1, core::int? end = #C2]) → core::String
+  return core::String::fromCharCodes(charCodes, start, end);
+static method _#B#fromCharCode#tearOff<unrelated X extends core::int>(core::int charCode) → core::String
+  return core::String::fromCharCode(charCode);
+static method _#B#fromEnvironment#tearOff<unrelated X extends core::int>(core::String name, {core::String defaultValue = #C3}) → core::String
+  return core::String::fromEnvironment(name, defaultValue: defaultValue);
+
+constants  {
+  #C1 = 0
+  #C2 = null
+  #C3 = ""
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.strong.transformed.expect
index 221969e..7e82df9 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.strong.transformed.expect
@@ -36,3 +36,21 @@
   core::String a;
 }
 static method main() → dynamic {}
+static method _#A#fromCharCodes#tearOff<unrelated X extends core::int>(core::Iterable<core::int> charCodes, [core::int start = #C1, core::int? end = #C2]) → core::String
+  return core::String::fromCharCodes(charCodes, start, end);
+static method _#A#fromCharCode#tearOff<unrelated X extends core::int>(core::int charCode) → core::String
+  return core::String::fromCharCode(charCode);
+static method _#A#fromEnvironment#tearOff<unrelated X extends core::int>(core::String name, {core::String defaultValue = #C3}) → core::String
+  return core::String::fromEnvironment(name, defaultValue: defaultValue);
+static method _#B#fromCharCodes#tearOff<unrelated X extends core::int>(core::Iterable<core::int> charCodes, [core::int start = #C1, core::int? end = #C2]) → core::String
+  return core::String::fromCharCodes(charCodes, start, end);
+static method _#B#fromCharCode#tearOff<unrelated X extends core::int>(core::int charCode) → core::String
+  return core::String::fromCharCode(charCode);
+static method _#B#fromEnvironment#tearOff<unrelated X extends core::int>(core::String name, {core::String defaultValue = #C3}) → core::String
+  return core::String::fromEnvironment(name, defaultValue: defaultValue);
+
+constants  {
+  #C1 = 0
+  #C2 = null
+  #C3 = ""
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.expect
index 221969e..7e82df9 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.expect
@@ -36,3 +36,21 @@
   core::String a;
 }
 static method main() → dynamic {}
+static method _#A#fromCharCodes#tearOff<unrelated X extends core::int>(core::Iterable<core::int> charCodes, [core::int start = #C1, core::int? end = #C2]) → core::String
+  return core::String::fromCharCodes(charCodes, start, end);
+static method _#A#fromCharCode#tearOff<unrelated X extends core::int>(core::int charCode) → core::String
+  return core::String::fromCharCode(charCode);
+static method _#A#fromEnvironment#tearOff<unrelated X extends core::int>(core::String name, {core::String defaultValue = #C3}) → core::String
+  return core::String::fromEnvironment(name, defaultValue: defaultValue);
+static method _#B#fromCharCodes#tearOff<unrelated X extends core::int>(core::Iterable<core::int> charCodes, [core::int start = #C1, core::int? end = #C2]) → core::String
+  return core::String::fromCharCodes(charCodes, start, end);
+static method _#B#fromCharCode#tearOff<unrelated X extends core::int>(core::int charCode) → core::String
+  return core::String::fromCharCode(charCode);
+static method _#B#fromEnvironment#tearOff<unrelated X extends core::int>(core::String name, {core::String defaultValue = #C3}) → core::String
+  return core::String::fromEnvironment(name, defaultValue: defaultValue);
+
+constants  {
+  #C1 = 0
+  #C2 = null
+  #C3 = ""
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.outline.expect
index 9b82c3d..3fd24b5 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.outline.expect
@@ -28,3 +28,15 @@
   ;
 static method main() → dynamic
   ;
+static method _#A#fromCharCodes#tearOff<unrelated X extends core::int>(core::Iterable<core::int> charCodes, [core::int start, core::int? end]) → core::String
+  return core::String::fromCharCodes(charCodes, start, end);
+static method _#A#fromCharCode#tearOff<unrelated X extends core::int>(core::int charCode) → core::String
+  return core::String::fromCharCode(charCode);
+static method _#A#fromEnvironment#tearOff<unrelated X extends core::int>(core::String name, {core::String defaultValue}) → core::String
+  return core::String::fromEnvironment(name, defaultValue: defaultValue);
+static method _#B#fromCharCodes#tearOff<unrelated X extends core::int>(core::Iterable<core::int> charCodes, [core::int start, core::int? end]) → core::String
+  return core::String::fromCharCodes(charCodes, start, end);
+static method _#B#fromCharCode#tearOff<unrelated X extends core::int>(core::int charCode) → core::String
+  return core::String::fromCharCode(charCode);
+static method _#B#fromEnvironment#tearOff<unrelated X extends core::int>(core::String name, {core::String defaultValue}) → core::String
+  return core::String::fromEnvironment(name, defaultValue: defaultValue);
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.transformed.expect
index 221969e..7e82df9 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_in_typedef.dart.weak.transformed.expect
@@ -36,3 +36,21 @@
   core::String a;
 }
 static method main() → dynamic {}
+static method _#A#fromCharCodes#tearOff<unrelated X extends core::int>(core::Iterable<core::int> charCodes, [core::int start = #C1, core::int? end = #C2]) → core::String
+  return core::String::fromCharCodes(charCodes, start, end);
+static method _#A#fromCharCode#tearOff<unrelated X extends core::int>(core::int charCode) → core::String
+  return core::String::fromCharCode(charCode);
+static method _#A#fromEnvironment#tearOff<unrelated X extends core::int>(core::String name, {core::String defaultValue = #C3}) → core::String
+  return core::String::fromEnvironment(name, defaultValue: defaultValue);
+static method _#B#fromCharCodes#tearOff<unrelated X extends core::int>(core::Iterable<core::int> charCodes, [core::int start = #C1, core::int? end = #C2]) → core::String
+  return core::String::fromCharCodes(charCodes, start, end);
+static method _#B#fromCharCode#tearOff<unrelated X extends core::int>(core::int charCode) → core::String
+  return core::String::fromCharCode(charCode);
+static method _#B#fromEnvironment#tearOff<unrelated X extends core::int>(core::String name, {core::String defaultValue = #C3}) → core::String
+  return core::String::fromEnvironment(name, defaultValue: defaultValue);
+
+constants  {
+  #C1 = 0
+  #C2 = null
+  #C3 = ""
+}
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.strong.expect
index 2da2661..cf0d7b6 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.strong.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.strong.expect
@@ -31,3 +31,5 @@
     : super core::Object::•()
     ;
 }
+static method _#B#new#tearOff<unrelated X extends core::String>() → self2::A
+  return new self2::A::•();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.strong.transformed.expect
index 2da2661..cf0d7b6 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.strong.transformed.expect
@@ -31,3 +31,5 @@
     : super core::Object::•()
     ;
 }
+static method _#B#new#tearOff<unrelated X extends core::String>() → self2::A
+  return new self2::A::•();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.expect
index 2da2661..cf0d7b6 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.expect
@@ -31,3 +31,5 @@
     : super core::Object::•()
     ;
 }
+static method _#B#new#tearOff<unrelated X extends core::String>() → self2::A
+  return new self2::A::•();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.outline.expect
index 9cbea69..250c92f 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.outline.expect
@@ -30,3 +30,5 @@
   synthetic constructor •() → self2::C<self2::C::Y>
     ;
 }
+static method _#B#new#tearOff<unrelated X extends core::String>() → self2::A
+  return new self2::A::•();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.transformed.expect
index 2da2661..cf0d7b6 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/aliased_checks_no_bodies_main.dart.weak.transformed.expect
@@ -31,3 +31,5 @@
     : super core::Object::•()
     ;
 }
+static method _#B#new#tearOff<unrelated X extends core::String>() → self2::A
+  return new self2::A::•();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.expect
index e43a323..ada86f5 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.expect
@@ -21,3 +21,5 @@
     ;
 }
 static method main() → void {}
+static method _#AAlias#new#tearOff<unrelated X extends core::Object? = dynamic>() → self::A<self::A<dynamic>>
+  return new self::A::•<self::A<dynamic>>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.transformed.expect
index e43a323..ada86f5 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.strong.transformed.expect
@@ -21,3 +21,5 @@
     ;
 }
 static method main() → void {}
+static method _#AAlias#new#tearOff<unrelated X extends core::Object? = dynamic>() → self::A<self::A<dynamic>>
+  return new self::A::•<self::A<dynamic>>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.expect
index e43a323..ada86f5 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.expect
@@ -21,3 +21,5 @@
     ;
 }
 static method main() → void {}
+static method _#AAlias#new#tearOff<unrelated X extends core::Object? = dynamic>() → self::A<self::A<dynamic>>
+  return new self::A::•<self::A<dynamic>>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.outline.expect
index 19040d1..c6e3e9c 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.outline.expect
@@ -21,3 +21,5 @@
 }
 static method main() → void
   ;
+static method _#AAlias#new#tearOff<unrelated X extends core::Object? = dynamic>() → self::A<self::A<dynamic>>
+  return new self::A::•<self::A<dynamic>>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.transformed.expect
index e43a323..ada86f5 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45491.dart.weak.transformed.expect
@@ -21,3 +21,5 @@
     ;
 }
 static method main() → void {}
+static method _#AAlias#new#tearOff<unrelated X extends core::Object? = dynamic>() → self::A<self::A<dynamic>>
+  return new self::A::•<self::A<dynamic>>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.strong.expect
index 20cf2a0a..0d5fcd0 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.strong.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.strong.expect
@@ -29,3 +29,5 @@
   self::C<(self::C<dynamic>) → self::C<dynamic>> a = throw 42;
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends (self::C<self::_#A#new#tearOff::X>) → self::C<self::_#A#new#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.strong.transformed.expect
index 20cf2a0a..0d5fcd0 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.strong.transformed.expect
@@ -29,3 +29,5 @@
   self::C<(self::C<dynamic>) → self::C<dynamic>> a = throw 42;
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends (self::C<self::_#A#new#tearOff::X>) → self::C<self::_#A#new#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.expect
index 20cf2a0a..0d5fcd0 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.expect
@@ -29,3 +29,5 @@
   self::C<(self::C<dynamic>) → self::C<dynamic>> a = throw 42;
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends (self::C<self::_#A#new#tearOff::X>) → self::C<self::_#A#new#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.outline.expect
index 2c7e28a..88c365f 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.outline.expect
@@ -12,3 +12,5 @@
   ;
 static method main() → dynamic
   ;
+static method _#A#new#tearOff<X extends (self::C<self::_#A#new#tearOff::X>) → self::C<self::_#A#new#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.transformed.expect
index 20cf2a0a..0d5fcd0 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519.dart.weak.transformed.expect
@@ -29,3 +29,5 @@
   self::C<(self::C<dynamic>) → self::C<dynamic>> a = throw 42;
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends (self::C<self::_#A#new#tearOff::X>) → self::C<self::_#A#new#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.expect
index 45b7e1ee7..1d4c9d2 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.expect
@@ -96,3 +96,15 @@
   new self::D::•<(self::D<Never>) → self::D<core::Object?>>();
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends (self::C<self::_#A#new#tearOff::X>) → self::C<self::_#A#new#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return self::C::•<self::_#A#new#tearOff::X>();
+static method _#A#foo#tearOff<X extends (self::C<self::_#A#foo#tearOff::X>) → self::C<self::_#A#foo#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#foo#tearOff::X>
+  return new self::C::foo<self::_#A#foo#tearOff::X>();
+static method _#A#bar#tearOff<X extends (self::C<self::_#A#bar#tearOff::X>) → self::C<self::_#A#bar#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#bar#tearOff::X>
+  return self::C::bar<self::_#A#bar#tearOff::X>();
+static method _#B#new#tearOff<X extends (self::D<self::_#B#new#tearOff::X>) → self::D<self::_#B#new#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#new#tearOff::X>
+  return new self::D::•<self::_#B#new#tearOff::X>();
+static method _#B#foo#tearOff<X extends (self::D<self::_#B#foo#tearOff::X>) → self::D<self::_#B#foo#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#foo#tearOff::X>
+  return self::D::foo<self::_#B#foo#tearOff::X>();
+static method _#B#bar#tearOff<X extends (self::D<self::_#B#bar#tearOff::X>) → self::D<self::_#B#bar#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#bar#tearOff::X>
+  return self::D::bar<self::_#B#bar#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.transformed.expect
index 45b7e1ee7..1d4c9d2 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.strong.transformed.expect
@@ -96,3 +96,15 @@
   new self::D::•<(self::D<Never>) → self::D<core::Object?>>();
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends (self::C<self::_#A#new#tearOff::X>) → self::C<self::_#A#new#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return self::C::•<self::_#A#new#tearOff::X>();
+static method _#A#foo#tearOff<X extends (self::C<self::_#A#foo#tearOff::X>) → self::C<self::_#A#foo#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#foo#tearOff::X>
+  return new self::C::foo<self::_#A#foo#tearOff::X>();
+static method _#A#bar#tearOff<X extends (self::C<self::_#A#bar#tearOff::X>) → self::C<self::_#A#bar#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#bar#tearOff::X>
+  return self::C::bar<self::_#A#bar#tearOff::X>();
+static method _#B#new#tearOff<X extends (self::D<self::_#B#new#tearOff::X>) → self::D<self::_#B#new#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#new#tearOff::X>
+  return new self::D::•<self::_#B#new#tearOff::X>();
+static method _#B#foo#tearOff<X extends (self::D<self::_#B#foo#tearOff::X>) → self::D<self::_#B#foo#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#foo#tearOff::X>
+  return self::D::foo<self::_#B#foo#tearOff::X>();
+static method _#B#bar#tearOff<X extends (self::D<self::_#B#bar#tearOff::X>) → self::D<self::_#B#bar#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#bar#tearOff::X>
+  return self::D::bar<self::_#B#bar#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.expect
index 45b7e1ee7..1d4c9d2 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.expect
@@ -96,3 +96,15 @@
   new self::D::•<(self::D<Never>) → self::D<core::Object?>>();
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends (self::C<self::_#A#new#tearOff::X>) → self::C<self::_#A#new#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return self::C::•<self::_#A#new#tearOff::X>();
+static method _#A#foo#tearOff<X extends (self::C<self::_#A#foo#tearOff::X>) → self::C<self::_#A#foo#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#foo#tearOff::X>
+  return new self::C::foo<self::_#A#foo#tearOff::X>();
+static method _#A#bar#tearOff<X extends (self::C<self::_#A#bar#tearOff::X>) → self::C<self::_#A#bar#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#bar#tearOff::X>
+  return self::C::bar<self::_#A#bar#tearOff::X>();
+static method _#B#new#tearOff<X extends (self::D<self::_#B#new#tearOff::X>) → self::D<self::_#B#new#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#new#tearOff::X>
+  return new self::D::•<self::_#B#new#tearOff::X>();
+static method _#B#foo#tearOff<X extends (self::D<self::_#B#foo#tearOff::X>) → self::D<self::_#B#foo#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#foo#tearOff::X>
+  return self::D::foo<self::_#B#foo#tearOff::X>();
+static method _#B#bar#tearOff<X extends (self::D<self::_#B#bar#tearOff::X>) → self::D<self::_#B#bar#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#bar#tearOff::X>
+  return self::D::bar<self::_#B#bar#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.outline.expect
index b89222a..218a88b 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.outline.expect
@@ -27,3 +27,15 @@
   ;
 static method main() → dynamic
   ;
+static method _#A#new#tearOff<X extends (self::C<self::_#A#new#tearOff::X>) → self::C<self::_#A#new#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return self::C::•<self::_#A#new#tearOff::X>();
+static method _#A#foo#tearOff<X extends (self::C<self::_#A#foo#tearOff::X>) → self::C<self::_#A#foo#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#foo#tearOff::X>
+  return new self::C::foo<self::_#A#foo#tearOff::X>();
+static method _#A#bar#tearOff<X extends (self::C<self::_#A#bar#tearOff::X>) → self::C<self::_#A#bar#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#bar#tearOff::X>
+  return self::C::bar<self::_#A#bar#tearOff::X>();
+static method _#B#new#tearOff<X extends (self::D<self::_#B#new#tearOff::X>) → self::D<self::_#B#new#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#new#tearOff::X>
+  return new self::D::•<self::_#B#new#tearOff::X>();
+static method _#B#foo#tearOff<X extends (self::D<self::_#B#foo#tearOff::X>) → self::D<self::_#B#foo#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#foo#tearOff::X>
+  return self::D::foo<self::_#B#foo#tearOff::X>();
+static method _#B#bar#tearOff<X extends (self::D<self::_#B#bar#tearOff::X>) → self::D<self::_#B#bar#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#bar#tearOff::X>
+  return self::D::bar<self::_#B#bar#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.transformed.expect
index 45b7e1ee7..1d4c9d2 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45519_2.dart.weak.transformed.expect
@@ -96,3 +96,15 @@
   new self::D::•<(self::D<Never>) → self::D<core::Object?>>();
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends (self::C<self::_#A#new#tearOff::X>) → self::C<self::_#A#new#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return self::C::•<self::_#A#new#tearOff::X>();
+static method _#A#foo#tearOff<X extends (self::C<self::_#A#foo#tearOff::X>) → self::C<self::_#A#foo#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#foo#tearOff::X>
+  return new self::C::foo<self::_#A#foo#tearOff::X>();
+static method _#A#bar#tearOff<X extends (self::C<self::_#A#bar#tearOff::X>) → self::C<self::_#A#bar#tearOff::X> = (self::C<dynamic>) → self::C<dynamic>>() → self::C<self::_#A#bar#tearOff::X>
+  return self::C::bar<self::_#A#bar#tearOff::X>();
+static method _#B#new#tearOff<X extends (self::D<self::_#B#new#tearOff::X>) → self::D<self::_#B#new#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#new#tearOff::X>
+  return new self::D::•<self::_#B#new#tearOff::X>();
+static method _#B#foo#tearOff<X extends (self::D<self::_#B#foo#tearOff::X>) → self::D<self::_#B#foo#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#foo#tearOff::X>
+  return self::D::foo<self::_#B#foo#tearOff::X>();
+static method _#B#bar#tearOff<X extends (self::D<self::_#B#bar#tearOff::X>) → self::D<self::_#B#bar#tearOff::X> = (self::D<dynamic>) → self::D<dynamic>>() → self::D<self::_#B#bar#tearOff::X>
+  return self::D::bar<self::_#B#bar#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.strong.expect
index 502ae56..0ed8715 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.strong.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.strong.expect
@@ -38,3 +38,7 @@
   self::C::foo<self::C<core::Object?>>();
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends self::C<self::_#A#new#tearOff::X> = self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
+static method _#A#foo#tearOff<X extends self::C<self::_#A#foo#tearOff::X> = self::C<dynamic>>() → self::C<self::_#A#foo#tearOff::X>
+  return self::C::foo<self::_#A#foo#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.strong.transformed.expect
index 502ae56..0ed8715 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.strong.transformed.expect
@@ -38,3 +38,7 @@
   self::C::foo<self::C<core::Object?>>();
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends self::C<self::_#A#new#tearOff::X> = self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
+static method _#A#foo#tearOff<X extends self::C<self::_#A#foo#tearOff::X> = self::C<dynamic>>() → self::C<self::_#A#foo#tearOff::X>
+  return self::C::foo<self::_#A#foo#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.weak.expect
index 502ae56..0ed8715 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.weak.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.weak.expect
@@ -38,3 +38,7 @@
   self::C::foo<self::C<core::Object?>>();
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends self::C<self::_#A#new#tearOff::X> = self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
+static method _#A#foo#tearOff<X extends self::C<self::_#A#foo#tearOff::X> = self::C<dynamic>>() → self::C<self::_#A#foo#tearOff::X>
+  return self::C::foo<self::_#A#foo#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.weak.outline.expect
index d911298..a91ccee 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.weak.outline.expect
@@ -13,3 +13,7 @@
   ;
 static method main() → dynamic
   ;
+static method _#A#new#tearOff<X extends self::C<self::_#A#new#tearOff::X> = self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
+static method _#A#foo#tearOff<X extends self::C<self::_#A#foo#tearOff::X> = self::C<dynamic>>() → self::C<self::_#A#foo#tearOff::X>
+  return self::C::foo<self::_#A#foo#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.weak.transformed.expect
index 502ae56..0ed8715 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/issue45658.dart.weak.transformed.expect
@@ -38,3 +38,7 @@
   self::C::foo<self::C<core::Object?>>();
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends self::C<self::_#A#new#tearOff::X> = self::C<dynamic>>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
+static method _#A#foo#tearOff<X extends self::C<self::_#A#foo#tearOff::X> = self::C<dynamic>>() → self::C<self::_#A#foo#tearOff::X>
+  return self::C::foo<self::_#A#foo#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.strong.expect
index d805d8c..1dd5191 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.strong.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.strong.expect
@@ -23,3 +23,5 @@
   new self::C::•<dynamic>();
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends core::num, unrelated Y extends core::Object? = dynamic>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.strong.transformed.expect
index d805d8c..1dd5191 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.strong.transformed.expect
@@ -23,3 +23,5 @@
   new self::C::•<dynamic>();
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends core::num, unrelated Y extends core::Object? = dynamic>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.expect
index d805d8c..1dd5191 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.expect
@@ -23,3 +23,5 @@
   new self::C::•<dynamic>();
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends core::num, unrelated Y extends core::Object? = dynamic>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.outline.expect
index 0b4358a..f5a9e7e 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.outline.expect
@@ -11,3 +11,5 @@
   ;
 static method main() → dynamic
   ;
+static method _#A#new#tearOff<X extends core::num, unrelated Y extends core::Object? = dynamic>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.transformed.expect
index d805d8c..1dd5191 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls.dart.weak.transformed.expect
@@ -23,3 +23,5 @@
   new self::C::•<dynamic>();
 }
 static method main() → dynamic {}
+static method _#A#new#tearOff<X extends core::num, unrelated Y extends core::Object? = dynamic>() → self::C<self::_#A#new#tearOff::X>
+  return new self::C::•<self::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.strong.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.strong.expect
index 98796c8..f7eab09 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.strong.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.strong.expect
@@ -30,3 +30,5 @@
 static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ foo() → dynamic {
   new self2::C::•<dynamic>();
 }
+static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ _#A#new#tearOff<X extends core::num, unrelated Y extends core::Object? = dynamic>() → self2::C<self2::_#A#new#tearOff::X>
+  return new self2::C::•<self2::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.strong.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.strong.transformed.expect
index 98796c8..f7eab09 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.strong.transformed.expect
@@ -30,3 +30,5 @@
 static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ foo() → dynamic {
   new self2::C::•<dynamic>();
 }
+static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ _#A#new#tearOff<X extends core::num, unrelated Y extends core::Object? = dynamic>() → self2::C<self2::_#A#new#tearOff::X>
+  return new self2::C::•<self2::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.expect
index 98796c8..f7eab09 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.expect
@@ -30,3 +30,5 @@
 static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ foo() → dynamic {
   new self2::C::•<dynamic>();
 }
+static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ _#A#new#tearOff<X extends core::num, unrelated Y extends core::Object? = dynamic>() → self2::C<self2::_#A#new#tearOff::X>
+  return new self2::C::•<self2::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.outline.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.outline.expect
index ca7c9c2..8a85f74 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.outline.expect
@@ -18,3 +18,5 @@
 }
 static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ foo() → dynamic
   ;
+static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ _#A#new#tearOff<X extends core::num, unrelated Y extends core::Object? = dynamic>() → self2::C<self2::_#A#new#tearOff::X>
+  return new self2::C::•<self2::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.transformed.expect b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.transformed.expect
index 98796c8..f7eab09 100644
--- a/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nonfunction_type_aliases/unaliased_bounds_checks_in_constructor_calls_with_parts_main.dart.weak.transformed.expect
@@ -30,3 +30,5 @@
 static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ foo() → dynamic {
   new self2::C::•<dynamic>();
 }
+static method /* from org-dartlang-testcase:///unaliased_bounds_checks_in_constructor_calls_with_parts_part_lib.dart */ _#A#new#tearOff<X extends core::num, unrelated Y extends core::Object? = dynamic>() → self2::C<self2::_#A#new#tearOff::X>
+  return new self2::C::•<self2::_#A#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 5cd897f..47b80dd 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -9,7 +9,6 @@
 dart2js/late_statics: SemiFuzzFailure # dartbug.com/45854
 
 constructor_tearoffs/call_instantiation: TypeCheckError
-constructor_tearoffs/const_tear_off: RuntimeError
 constructor_tearoffs/lowering/invalid_redirect: VerificationError
 extension_types/extension_on_nullable: ExpectationFileMismatchSerialized # Expected.
 extension_types/issue45775: ExpectationFileMismatchSerialized # Expected.
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index dc2b0b7..dc74759 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -7,7 +7,6 @@
 # Kernel files are produced by compiling Dart code via Fasta.
 
 constructor_tearoffs/call_instantiation: TypeCheckError
-constructor_tearoffs/const_tear_off: RuntimeError
 constructor_tearoffs/lowering/invalid_redirect: VerificationError
 extension_types/extension_on_nullable: ExpectationFileMismatchSerialized # Expected.
 extension_types/issue45775: ExpectationFileMismatchSerialized # Expected.
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index 0281cb6..7263971 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -12,7 +12,6 @@
 dart2js/late_statics: SemiFuzzFailure # dartbug.com/45854
 
 constructor_tearoffs/call_instantiation: TypeCheckError
-constructor_tearoffs/const_tear_off: RuntimeError
 constructor_tearoffs/lowering/invalid_redirect: VerificationError
 extension_types/extension_on_nullable: ExpectationFileMismatchSerialized # Expected.
 extension_types/issue45775: ExpectationFileMismatchSerialized # Expected.
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index 01def63..f6d1c44 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -65,6 +65,7 @@
 
   @override
   int get enabledConstructorTearOffLowerings =>
+      ConstructorTearOffLowering.typedefs |
       flags.forceConstructorTearOffLoweringForTesting;
 
   @override
diff --git a/runtime/tests/vm/dart/isolates/test_utils.dart b/runtime/tests/vm/dart/isolates/test_utils.dart
index 4e1d929..7c5da81 100644
--- a/runtime/tests/vm/dart/isolates/test_utils.dart
+++ b/runtime/tests/vm/dart/isolates/test_utils.dart
@@ -8,6 +8,9 @@
 
 import 'internal.dart';
 
+export '../../../../../benchmarks/IsolateFibonacci/dart/IsolateFibonacci.dart'
+  show fibonacciRecursive;
+
 final bool isDebugMode = Platform.script.path.contains('Debug');
 final bool isSimulator = Platform.script.path.contains('SIM');
 final bool isArtificialReloadMode = Platform.executableArguments.any((arg) => [
@@ -44,26 +47,6 @@
   }
 }
 
-// Implements recursive summation via tail calls:
-//   fib(n) => n <= 1 ? 1
-//                    : fib(n-1) + fib(n-2);
-Future fibonacciRecursive(List args) async {
-  final SendPort port = args[0];
-  final n = args[1];
-  if (n <= 1) {
-    port.send(1);
-    return;
-  }
-  final left = ReceivePort();
-  final right = ReceivePort();
-  await Future.wait([
-    Isolate.spawn(fibonacciRecursive, [left.sendPort, n - 1]),
-    Isolate.spawn(fibonacciRecursive, [right.sendPort, n - 2]),
-  ]);
-  final results = await Future.wait([left.first, right.first]);
-  port.send(results[0] + results[1]);
-}
-
 enum Command { kRun, kRunAndClose, kClose }
 
 abstract class RingElement {
diff --git a/runtime/tests/vm/dart_2/isolates/test_utils.dart b/runtime/tests/vm/dart_2/isolates/test_utils.dart
index c8aa4ef..0c93f3d 100644
--- a/runtime/tests/vm/dart_2/isolates/test_utils.dart
+++ b/runtime/tests/vm/dart_2/isolates/test_utils.dart
@@ -10,6 +10,9 @@
 
 import 'internal.dart';
 
+export '../../../../../benchmarks/IsolateFibonacci/dart2/IsolateFibonacci.dart'
+  show fibonacciRecursive;
+
 final bool isDebugMode = Platform.script.path.contains('Debug');
 final bool isSimulator = Platform.script.path.contains('SIM');
 final bool isArtificialReloadMode = Platform.executableArguments.any((arg) => [
@@ -46,26 +49,6 @@
   }
 }
 
-// Implements recursive summation via tail calls:
-//   fib(n) => n <= 1 ? 1
-//                    : fib(n-1) + fib(n-2);
-Future fibonacciRecursive(List args) async {
-  final SendPort port = args[0];
-  final n = args[1];
-  if (n <= 1) {
-    port.send(1);
-    return;
-  }
-  final left = ReceivePort();
-  final right = ReceivePort();
-  await Future.wait([
-    Isolate.spawn(fibonacciRecursive, [left.sendPort, n - 1]),
-    Isolate.spawn(fibonacciRecursive, [right.sendPort, n - 2]),
-  ]);
-  final results = await Future.wait([left.first, right.first]);
-  port.send(results[0] + results[1]);
-}
-
 enum Command { kRun, kRunAndClose, kClose }
 
 abstract class RingElement {
diff --git a/sdk/lib/_http/http.dart b/sdk/lib/_http/http.dart
index abc401e..d303412 100644
--- a/sdk/lib/_http/http.dart
+++ b/sdk/lib/_http/http.dart
@@ -391,16 +391,24 @@
   static const acceptEncodingHeader = "accept-encoding";
   static const acceptLanguageHeader = "accept-language";
   static const acceptRangesHeader = "accept-ranges";
+  @Since("2.14")
   static const accessControlAllowCredentialsHeader =
       'access-control-allow-credentials';
+  @Since("2.14")
   static const accessControlAllowHeadersHeader = 'access-control-allow-headers';
+  @Since("2.14")
   static const accessControlAllowMethodsHeader = 'access-control-allow-methods';
+  @Since("2.14")
   static const accessControlAllowOriginHeader = 'access-control-allow-origin';
+  @Since("2.14")
   static const accessControlExposeHeadersHeader =
       'access-control-expose-headers';
+  @Since("2.14")
   static const accessControlMaxAgeHeader = 'access-control-max-age';
+  @Since("2.14")
   static const accessControlRequestHeadersHeader =
       'access-control-request-headers';
+  @Since("2.14")
   static const accessControlRequestMethodHeader =
       'access-control-request-method';
   static const ageHeader = "age";
@@ -2315,7 +2323,9 @@
   const HttpException(this.message, {this.uri});
 
   String toString() {
-    var b = new StringBuffer()..write('HttpException: ')..write(message);
+    var b = new StringBuffer()
+      ..write('HttpException: ')
+      ..write(message);
     var uri = this.uri;
     if (uri != null) {
       b.write(', uri = $uri');
diff --git a/tests/language/constructor/reference_test.dart b/tests/language/constructor/reference_test.dart
index d781ab1..0630a86 100644
--- a/tests/language/constructor/reference_test.dart
+++ b/tests/language/constructor/reference_test.dart
@@ -87,8 +87,11 @@
   Foo.bar();
   Foo.bar.baz();
   //  ^^^
-  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
   // [cfe] Getter not found: 'bar'.
+//^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONSTRUCTOR_TEAROFFS_NOT_ENABLED
+  //      ^^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_METHOD
   Foo<int>();
   Foo<int>.bar();
   Foo<int>.bar.baz();
@@ -111,6 +114,9 @@
   // [cfe] Method not found: 'Foo.bar.baz'.
   Foo.bar.baz<int>();
   //  ^^^
-  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
   // [cfe] Getter not found: 'bar'.
+//^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONSTRUCTOR_TEAROFFS_NOT_ENABLED
+  //      ^^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_METHOD
 }
diff --git a/tests/language_2/constructor/reference_test.dart b/tests/language_2/constructor/reference_test.dart
index ee1aa67..6e3dac9 100644
--- a/tests/language_2/constructor/reference_test.dart
+++ b/tests/language_2/constructor/reference_test.dart
@@ -89,8 +89,11 @@
   Foo.bar();
   Foo.bar.baz();
   //  ^^^
-  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
   // [cfe] Getter not found: 'bar'.
+//^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONSTRUCTOR_TEAROFFS_NOT_ENABLED
+  //      ^^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_METHOD
   Foo<int>();
   Foo<int>.bar();
   Foo<int>.bar.baz();
@@ -113,6 +116,9 @@
   // [cfe] Method not found: 'Foo.bar.baz'.
   Foo.bar.baz<int>();
   //  ^^^
-  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_GETTER
   // [cfe] Getter not found: 'bar'.
+//^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONSTRUCTOR_TEAROFFS_NOT_ENABLED
+  //      ^^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_METHOD
 }
diff --git a/tools/VERSION b/tools/VERSION
index 89007c1..13fcb01 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 389
+PRERELEASE 390
 PRERELEASE_PATCH 0
\ No newline at end of file