Version 2.14.0-385.0.dev

Merge commit '81da4e07fdcf3788690504106c214d9a356bd96c' into 'dev'
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 28509f0..fa2fae2 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -501,7 +501,7 @@
     }
   }
 
-  List<String> _getPossibelBazelBinPaths(_BazelWatchedFiles watched) => [
+  List<String> _getPossibleBazelBinPaths(_BazelWatchedFiles watched) => [
         pathContext.join(watched.workspace, 'bazel-bin'),
         pathContext.join(watched.workspace, 'blaze-bin'),
       ];
@@ -530,7 +530,7 @@
     // we do, we'll simply recreate all contexts to make sure that we follow the
     // correct paths.
     var bazelSymlinkPaths = bazelWatchedPathsPerFolder.values
-        .expand((watched) => _getPossibelBazelBinPaths(watched))
+        .expand((watched) => _getPossibleBazelBinPaths(watched))
         .toSet();
     if (allEvents.any((event) => bazelSymlinkPaths.contains(event.path))) {
       refresh();
@@ -572,15 +572,16 @@
 
     _instrumentationService.logWatchEvent('<unknown>', path, type.toString());
 
-    final isPubpsec = file_paths.isPubspecYaml(pathContext, path);
+    final isPubspec = file_paths.isPubspecYaml(pathContext, path);
     if (file_paths.isAnalysisOptionsYaml(pathContext, path) ||
+        file_paths.isBazelBuild(pathContext, path) ||
         file_paths.isDotPackages(pathContext, path) ||
         file_paths.isPackageConfigJson(pathContext, path) ||
-        isPubpsec ||
+        isPubspec ||
         false) {
       _createAnalysisContexts();
 
-      if (isPubpsec) {
+      if (isPubspec) {
         if (type == ChangeType.REMOVE) {
           callbacks.pubspecRemoved(path);
         } else {
@@ -684,7 +685,7 @@
   void _startWatchingBazelBinPaths(_BazelWatchedFiles watched) {
     var watcherService = bazelWatcherService;
     if (watcherService == null) return;
-    var paths = _getPossibelBazelBinPaths(watched);
+    var paths = _getPossibleBazelBinPaths(watched);
     watcherService.startWatching(
         watched.workspace, BazelSearchInfo(paths[0], paths));
   }
@@ -693,7 +694,7 @@
   void _stopWatchingBazelBinPaths(_BazelWatchedFiles watched) {
     var watcherService = bazelWatcherService;
     if (watcherService == null) return;
-    var paths = _getPossibelBazelBinPaths(watched);
+    var paths = _getPossibleBazelBinPaths(watched);
     watcherService.stopWatching(watched.workspace, paths[0]);
   }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/organize_imports.dart b/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
index 6a56773..aceacd3 100644
--- a/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
+++ b/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
@@ -233,7 +233,8 @@
   ///
   /// Leading comments for the first directive in a file are considered library
   /// comments and not returned unless they contain blank lines, in which case
-  /// only the last part of the comment will be returned.
+  /// only the last part of the comment will be returned (unless it is a
+  /// language directive comment, in which case it will also be skipped).
   static Token? getLeadingComment(
       CompilationUnit unit, UriBasedDirective directive, LineInfo lineInfo) {
     if (directive.beginToken.precedingComments == null) {
@@ -254,6 +255,11 @@
       nextComment = comment.next;
     }
 
+    // Language version tokens should never be attached so skip over.
+    if (firstComment is LanguageVersionToken) {
+      firstComment = firstComment.next;
+    }
+
     // Check if the comment is the first comment in the document
     if (firstComment != unit.beginToken.precedingComments) {
       var previousDirectiveLine =
diff --git a/pkg/analysis_server/test/analysis/get_navigation_test.dart b/pkg/analysis_server/test/analysis/get_navigation_test.dart
index 4c24110..de8f51e 100644
--- a/pkg/analysis_server/test/analysis/get_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/get_navigation_test.dart
@@ -66,6 +66,42 @@
     assertHasRegion('String]');
   }
 
+  Future<void> test_constructorInvocation() async {
+    // Check that a constructor invocation navigates to the constructor and not
+    // the class.
+    // https://github.com/dart-lang/sdk/issues/46725
+    addTestFile('''
+class Foo {
+  // ...
+  // ...
+  Foo() {
+    print('');
+  }
+  // ...
+}
+
+final a = Foo();
+final b = new Foo();
+''');
+    await waitForTasksFinished();
+
+    // Without `new`
+    await _getNavigation(testFile, testCode.indexOf('Foo();'), 0);
+    expect(regions, hasLength(1));
+    expect(regions.first.targets, hasLength(1));
+    var target = targets[regions.first.targets.first];
+    expect(target.kind, ElementKind.CONSTRUCTOR);
+    expect(target.offset, testCode.indexOf('Foo() {'));
+
+    // With `new`
+    await _getNavigation(testFile, testCode.indexOf('new Foo();') + 4, 0);
+    expect(regions, hasLength(1));
+    expect(regions.first.targets, hasLength(1));
+    target = targets[regions.first.targets.first];
+    expect(target.kind, ElementKind.CONSTRUCTOR);
+    expect(target.offset, testCode.indexOf('Foo() {'));
+  }
+
   Future<void> test_fieldType() async {
     // This test mirrors test_navigation() from
     // test/integration/analysis/get_navigation_test.dart
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index af1689b..0eee133 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -26,13 +26,57 @@
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(AnalysisDomainTest);
+    defineReflectiveTests(AnalysisDomainBazelTest);
+    defineReflectiveTests(AnalysisDomainPubTest);
     defineReflectiveTests(AnalysisDomainHandlerTest);
     defineReflectiveTests(SetSubscriptionsTest);
   });
 }
 
 @reflectiveTest
+class AnalysisDomainBazelTest extends _AnalysisDomainTest {
+  String get myPackageLibPath => '$myPackageRootPath/lib';
+
+  String get myPackageRootPath => '$workspaceRootPath/dart/my';
+
+  String get myPackageTestFilePath => '$myPackageLibPath/test.dart';
+
+  String get workspaceRootPath => '/workspace';
+
+  @override
+  void setUp() {
+    super.setUp();
+    newFile('$workspaceRootPath/WORKSPACE');
+  }
+
+  Future<void> test_fileSystem_changeFile_buildFile() async {
+    // This BUILD file does not enable null safety.
+    newBazelBuildFile(myPackageRootPath, '');
+
+    newFile(myPackageTestFilePath, content: '''
+void f(int? a) {}
+''');
+
+    setRoots(included: [myPackageRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // Cannot use `int?` without enabling null safety.
+    assertHasErrors(myPackageTestFilePath);
+
+    // Enable null safety.
+    newBazelBuildFile(myPackageRootPath, '''
+dart_package(null_safety = True)
+''');
+
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // We have null safety enabled, so no errors.
+    assertNoErrors(myPackageTestFilePath);
+  }
+}
+
+@reflectiveTest
 class AnalysisDomainHandlerTest extends AbstractAnalysisTest {
   Future<void> outOfRangeTest(SourceEdit edit) async {
     var helper = AnalysisTestHelper();
@@ -302,12 +346,7 @@
 }
 
 @reflectiveTest
-class AnalysisDomainTest extends AbstractAnalysisTest {
-  final Map<String, List<AnalysisError>> filesErrors = {};
-
-  /// The files for which `analysis.flushResults` was received.
-  final List<String> flushResults = [];
-
+class AnalysisDomainPubTest extends _AnalysisDomainTest {
   String get testFilePath => '$testPackageLibPath/test.dart';
 
   String get testPackageLibPath => '$testPackageRootPath/lib';
@@ -316,38 +355,6 @@
 
   String get workspaceRootPath => '/home';
 
-  void assertHasErrors(String path) {
-    path = convertPath(path);
-    expect(filesErrors[path], isNotEmpty, reason: path);
-  }
-
-  void assertNoErrors(String path) {
-    path = convertPath(path);
-    expect(filesErrors[path], isEmpty, reason: path);
-  }
-
-  void assertNoErrorsNotification(String path) {
-    path = convertPath(path);
-    expect(filesErrors[path], isNull, reason: path);
-  }
-
-  void forgetReceivedErrors() {
-    filesErrors.clear();
-  }
-
-  @override
-  void processNotification(Notification notification) {
-    if (notification.event == ANALYSIS_NOTIFICATION_FLUSH_RESULTS) {
-      var decoded = AnalysisFlushResultsParams.fromNotification(notification);
-      flushResults.addAll(decoded.files);
-      decoded.files.forEach(filesErrors.remove);
-    }
-    if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) {
-      var decoded = AnalysisErrorsParams.fromNotification(notification);
-      filesErrors[decoded.file] = decoded.errors;
-    }
-  }
-
   Future<void> test_fileSystem_addFile_analysisOptions() async {
     var a_path = '$testPackageLibPath/a.dart';
     var b_path = '$testPackageLibPath/b.dart';
@@ -1408,44 +1415,6 @@
     // errors are not reported for packages
     assertNoErrorsNotification(a_path);
   }
-
-  void writePackageConfig(String path, PackageConfigFileBuilder config) {
-    newFile(path, content: config.toContent(toUriStr: toUriStr));
-  }
-
-  void _assertAnalyzedFiles({
-    required List<String> hasErrors,
-    List<String> noErrors = const [],
-    required List<String> notAnalyzed,
-  }) {
-    for (var path in hasErrors) {
-      assertHasErrors(path);
-    }
-
-    for (var path in noErrors) {
-      assertNoErrors(path);
-    }
-
-    for (var path in notAnalyzed) {
-      assertNoErrorsNotification(path);
-    }
-
-    filesErrors.clear();
-  }
-
-  void _assertFlushedResults(List<String> paths) {
-    var convertedPaths = paths.map(convertPath).toList();
-    expect(flushResults, unorderedEquals(convertedPaths));
-    flushResults.clear();
-  }
-
-  /// Create files with a content that has a compile time error.
-  /// So, when analyzed, these files will satisfy [assertHasErrors].
-  void _createFilesWithErrors(List<String> paths) {
-    for (var path in paths) {
-      newFile(path, content: 'error');
-    }
-  }
 }
 
 /// A helper to test 'analysis.*' requests.
@@ -1776,3 +1745,80 @@
     expect(files, [testFile]);
   }
 }
+
+class _AnalysisDomainTest extends AbstractAnalysisTest {
+  final Map<String, List<AnalysisError>> filesErrors = {};
+
+  /// The files for which `analysis.flushResults` was received.
+  final List<String> flushResults = [];
+
+  void assertHasErrors(String path) {
+    path = convertPath(path);
+    expect(filesErrors[path], isNotEmpty, reason: path);
+  }
+
+  void assertNoErrors(String path) {
+    path = convertPath(path);
+    expect(filesErrors[path], isEmpty, reason: path);
+  }
+
+  void assertNoErrorsNotification(String path) {
+    path = convertPath(path);
+    expect(filesErrors[path], isNull, reason: path);
+  }
+
+  void forgetReceivedErrors() {
+    filesErrors.clear();
+  }
+
+  @override
+  void processNotification(Notification notification) {
+    if (notification.event == ANALYSIS_NOTIFICATION_FLUSH_RESULTS) {
+      var decoded = AnalysisFlushResultsParams.fromNotification(notification);
+      flushResults.addAll(decoded.files);
+      decoded.files.forEach(filesErrors.remove);
+    }
+    if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) {
+      var decoded = AnalysisErrorsParams.fromNotification(notification);
+      filesErrors[decoded.file] = decoded.errors;
+    }
+  }
+
+  void writePackageConfig(String path, PackageConfigFileBuilder config) {
+    newFile(path, content: config.toContent(toUriStr: toUriStr));
+  }
+
+  void _assertAnalyzedFiles({
+    required List<String> hasErrors,
+    List<String> noErrors = const [],
+    required List<String> notAnalyzed,
+  }) {
+    for (var path in hasErrors) {
+      assertHasErrors(path);
+    }
+
+    for (var path in noErrors) {
+      assertNoErrors(path);
+    }
+
+    for (var path in notAnalyzed) {
+      assertNoErrorsNotification(path);
+    }
+
+    filesErrors.clear();
+  }
+
+  void _assertFlushedResults(List<String> paths) {
+    var convertedPaths = paths.map(convertPath).toList();
+    expect(flushResults, unorderedEquals(convertedPaths));
+    flushResults.clear();
+  }
+
+  /// Create files with a content that has a compile time error.
+  /// So, when analyzed, these files will satisfy [assertHasErrors].
+  void _createFilesWithErrors(List<String> paths) {
+    for (var path in paths) {
+      newFile(path, content: 'error');
+    }
+  }
+}
diff --git a/pkg/analysis_server/test/services/correction/organize_directives_test.dart b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
index 7696ad5..b99492a 100644
--- a/pkg/analysis_server/test/services/correction/organize_directives_test.dart
+++ b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
@@ -78,6 +78,76 @@
     _assertOrganize(code);
   }
 
+  Future<void> test_languageVersion_afterLibraryComment() async {
+    await _computeUnitAndErrors(r'''
+// Copyright
+
+// @dart=2.10
+
+import 'dart:io';
+import 'dart:async';
+
+File f;
+Future a;
+''');
+    // validate change
+    _assertOrganize(r'''
+// Copyright
+
+// @dart=2.10
+
+import 'dart:async';
+import 'dart:io';
+
+File f;
+Future a;
+''');
+  }
+
+  Future<void> test_languageVersion_asFirstComment() async {
+    await _computeUnitAndErrors(r'''
+// @dart=2.10
+import 'dart:io';
+import 'dart:async';
+
+File f;
+Future a;
+''');
+    // validate change
+    _assertOrganize(r'''
+// @dart=2.10
+import 'dart:async';
+import 'dart:io';
+
+File f;
+Future a;
+''');
+  }
+
+  Future<void> test_languageVersion_beforeImportWithoutNewline() async {
+    await _computeUnitAndErrors(r'''
+// Copyright
+
+// @dart=2.10
+import 'dart:io';
+import 'dart:async';
+
+File f;
+Future a;
+''');
+    // validate change
+    _assertOrganize(r'''
+// Copyright
+
+// @dart=2.10
+import 'dart:async';
+import 'dart:io';
+
+File f;
+Future a;
+''');
+  }
+
   Future<void> test_remove_duplicateImports() async {
     await _computeUnitAndErrors(r'''
 import 'dart:async';
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
index c161993..e0a5372 100644
--- a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
@@ -27,6 +27,12 @@
     unit.accept(visitor);
   } else {
     var node = _getNodeForRange(unit, offset, length);
+    // Take the outer-most node that shares this offset/length so that we get
+    // things like ConstructorName instead of SimpleIdentifier.
+    // https://github.com/dart-lang/sdk/issues/46725
+    if (node != null) {
+      node = _getOutermostNode(node);
+    }
     node?.accept(visitor);
   }
   return collector;
@@ -42,6 +48,19 @@
   return node;
 }
 
+/// Gets the outer-most node with the same offset/length as node.
+AstNode _getOutermostNode(AstNode node) {
+  AstNode? current = node;
+  while (current != null &&
+      current.parent != null &&
+      current != current.parent &&
+      current.offset == current.parent!.offset &&
+      current.length == current.parent!.length) {
+    current = current.parent;
+  }
+  return current ?? node;
+}
+
 /// A Dart specific wrapper around [NavigationCollector].
 class _DartNavigationCollector {
   final NavigationCollector collector;
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 3a6544e..432f847 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1214,67 +1214,44 @@
     Procedure initialTarget = target;
     Expression replacementNode;
 
-    RedirectionTarget? redirectionTarget =
+    RedirectionTarget redirectionTarget =
         getRedirectionTarget(initialTarget, this);
-    Member? resolvedTarget = redirectionTarget?.target;
-    if (redirectionTarget != null &&
-        redirectionTarget.typeArguments.any((type) => type is UnknownType)) {
+    Member resolvedTarget = redirectionTarget.target;
+    if (redirectionTarget.typeArguments.any((type) => type is UnknownType)) {
       return null;
     }
 
-    if (resolvedTarget == null) {
-      String name = constructorNameForDiagnostics(initialTarget.name.text,
-          className: initialTarget.enclosingClass!.name);
-      // TODO(dmitryas): Report this error earlier.
-      replacementNode = buildProblem(
-          fasta.templateCyclicRedirectingFactoryConstructors
-              .withArguments(name),
-          initialTarget.fileOffset,
-          name.length);
-    } else if (resolvedTarget is Constructor &&
-        resolvedTarget.enclosingClass.isAbstract) {
-      replacementNode = evaluateArgumentsBefore(
-          forest.createArguments(noLocation, arguments.positional,
-              types: arguments.types, named: arguments.named),
-          buildAbstractClassInstantiationError(
-              fasta.templateAbstractRedirectedClassInstantiation
-                  .withArguments(resolvedTarget.enclosingClass.name),
-              resolvedTarget.enclosingClass.name,
-              initialTarget.fileOffset));
+    RedirectingFactoryBody? redirectingFactoryBody =
+        getRedirectingFactoryBody(resolvedTarget);
+    if (redirectingFactoryBody != null) {
+      // If the redirection target is itself a redirecting factory, it means
+      // that it is unresolved.
+      assert(redirectingFactoryBody.isError);
+      String errorMessage = redirectingFactoryBody.errorMessage!;
+      replacementNode = new InvalidExpression(errorMessage)
+        ..fileOffset = fileOffset;
     } else {
-      RedirectingFactoryBody? redirectingFactoryBody =
-          getRedirectingFactoryBody(resolvedTarget);
-      if (redirectingFactoryBody != null) {
-        // If the redirection target is itself a redirecting factory, it means
-        // that it is unresolved.
-        assert(redirectingFactoryBody.isError);
-        String errorMessage = redirectingFactoryBody.errorMessage!;
-        replacementNode = new InvalidExpression(errorMessage)
-          ..fileOffset = fileOffset;
-      } else {
-        Substitution substitution = Substitution.fromPairs(
-            initialTarget.function.typeParameters, arguments.types);
-        for (int i = 0; i < redirectionTarget!.typeArguments.length; i++) {
-          DartType typeArgument =
-              substitution.substituteType(redirectionTarget.typeArguments[i]);
-          if (i < arguments.types.length) {
-            arguments.types[i] = typeArgument;
-          } else {
-            arguments.types.add(typeArgument);
-          }
+      Substitution substitution = Substitution.fromPairs(
+          initialTarget.function.typeParameters, arguments.types);
+      for (int i = 0; i < redirectionTarget.typeArguments.length; i++) {
+        DartType typeArgument =
+            substitution.substituteType(redirectionTarget.typeArguments[i]);
+        if (i < arguments.types.length) {
+          arguments.types[i] = typeArgument;
+        } else {
+          arguments.types.add(typeArgument);
         }
-        arguments.types.length = redirectionTarget.typeArguments.length;
-
-        replacementNode = buildStaticInvocation(
-            resolvedTarget,
-            forest.createArguments(noLocation, arguments.positional,
-                types: arguments.types,
-                named: arguments.named,
-                hasExplicitTypeArguments: hasExplicitTypeArguments(arguments)),
-            constness:
-                isConst ? Constness.explicitConst : Constness.explicitNew,
-            charOffset: fileOffset);
       }
+      arguments.types.length = redirectionTarget.typeArguments.length;
+
+      replacementNode = buildStaticInvocation(
+          resolvedTarget,
+          forest.createArguments(noLocation, arguments.positional,
+              types: arguments.types,
+              named: arguments.named,
+              hasExplicitTypeArguments: hasExplicitTypeArguments(arguments)),
+          constness: isConst ? Constness.explicitConst : Constness.explicitNew,
+          charOffset: fileOffset);
     }
     return replacementNode;
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index 840ea47..23286b5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -3324,7 +3324,7 @@
         // ignore: unnecessary_null_comparison
         assert(types != null);
 
-        List<DartType> typeArguments = convertTypes(types);
+        List<DartType> typeArguments = types;
         if (constant is TypedefTearOffConstant) {
           Substitution substitution =
               Substitution.fromPairs(constant.parameters, typeArguments);
@@ -3345,7 +3345,8 @@
                 .toList();
           }
         }
-        return canonicalize(new InstantiationConstant(constant, typeArguments));
+        return canonicalize(
+            new InstantiationConstant(constant, convertTypes(typeArguments)));
       } else {
         // Probably unreachable.
         return createInvalidExpressionConstant(
diff --git a/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart b/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
index 9debfe6..3697827 100644
--- a/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/redirecting_factory_body.dart
@@ -176,31 +176,27 @@
   RedirectionTarget(this.target, this.typeArguments);
 }
 
-RedirectionTarget? getRedirectionTarget(Procedure member, EnsureLoaded helper) {
+RedirectionTarget getRedirectionTarget(Procedure factory, EnsureLoaded helper) {
   List<DartType> typeArguments = new List<DartType>.generate(
-      member.function.typeParameters.length, (int i) {
+      factory.function.typeParameters.length, (int i) {
     return new TypeParameterType.withDefaultNullabilityForLibrary(
-        member.function.typeParameters[i], member.enclosingLibrary);
+        factory.function.typeParameters[i], factory.enclosingLibrary);
   }, growable: true);
 
-  // We use the [tortoise and hare algorithm]
-  // (https://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare) to
-  // handle cycles.
-  Member tortoise = member;
-  RedirectingFactoryBody? tortoiseBody = getRedirectingFactoryBody(tortoise);
-  Member? hare = tortoiseBody?.target;
-  helper.ensureLoaded(hare);
-  RedirectingFactoryBody? hareBody = getRedirectingFactoryBody(hare);
-  while (tortoise != hare) {
-    if (tortoiseBody == null || tortoiseBody.isError) {
-      return new RedirectionTarget(tortoise, typeArguments);
+  // Cyclic factories are detected earlier, so we're guaranteed to
+  // reach either a non-redirecting factory or an error eventually.
+  Member target = factory;
+  for (;;) {
+    RedirectingFactoryBody? body = getRedirectingFactoryBody(target);
+    if (body == null || body.isError) {
+      return new RedirectionTarget(target, typeArguments);
     }
-    Member nextTortoise = tortoiseBody.target!;
-    helper.ensureLoaded(nextTortoise);
-    List<DartType>? nextTypeArguments = tortoiseBody.typeArguments;
+    Member nextMember = body.target!;
+    helper.ensureLoaded(nextMember);
+    List<DartType>? nextTypeArguments = body.typeArguments;
     if (nextTypeArguments != null) {
       Substitution sub = Substitution.fromPairs(
-          tortoise.function!.typeParameters, typeArguments);
+          target.function!.typeParameters, typeArguments);
       typeArguments =
           new List<DartType>.generate(nextTypeArguments.length, (int i) {
         return sub.substituteType(nextTypeArguments[i]);
@@ -208,13 +204,6 @@
     } else {
       typeArguments = <DartType>[];
     }
-
-    tortoise = nextTortoise;
-    tortoiseBody = getRedirectingFactoryBody(tortoise);
-    helper.ensureLoaded(hareBody?.target);
-    hare = getRedirectingFactoryBody(hareBody?.target)?.target;
-    helper.ensureLoaded(hare);
-    hareBody = getRedirectingFactoryBody(hare);
+    target = nextMember;
   }
-  return null;
 }
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
index 60e717f..67ffb10 100644
--- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -278,7 +278,9 @@
   void buildTypedefTearOffs(
       SourceLibraryBuilder library, void Function(Procedure) f) {
     TypeDeclarationBuilder? declaration = unaliasDeclaration(null);
+    DartType? targetType = typedef.type;
     if (declaration is ClassBuilder &&
+        targetType is InterfaceType &&
         typedef.typeParameters.isNotEmpty &&
         !isProperRenameForClass(library.loader.typeEnvironment, typedef)) {
       tearOffs = {};
@@ -296,7 +298,7 @@
               createTypedefTearOffProcedure(
                   name, constructorName, library, fileUri, charOffset);
           _tearOffDependencies![tearOff] = target;
-          InterfaceType targetType = typedef.type as InterfaceType;
+
           buildTypedefTearOffProcedure(tearOff, target, declaration.cls,
               typedef.typeParameters, targetType.typeArguments, library);
           f(tearOff);
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 7f08054..1121885 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
@@ -16,7 +16,7 @@
 static const field () → self::A<core::int> f1c = #C2;
 static const field () → self::A<core::int> g1a = #C2;
 static const field () → self::A<core::int> g1b = #C2;
-static const field () → self::A<core::int> g1c = #C3;
+static const field () → self::A<core::int> g1c = #C2;
 static const field () → self::A<core::int> h1a = #C2;
 static const field () → self::A<core::int> h1b = #C2;
 static const field () → self::A<core::int> h1c = #C2;
@@ -25,7 +25,7 @@
   core::identical(#C2, #C2);
   core::identical(#C2, #C2);
   core::identical(#C2, #C2);
-  core::identical(#C2, #C3);
+  core::identical(#C2, #C2);
   core::identical(#C2, #C2);
   core::identical(#C2, #C2);
 }
@@ -35,7 +35,7 @@
   () → self::A<self::test::T> f2c = #C1<self::test::T>;
   () → self::A<core::int> g2a = #C2;
   () → self::A<core::int> g2b = #C2;
-  () → self::A<core::int> g2c = #C3;
+  () → self::A<core::int> g2c = #C2;
   () → self::A<self::test::T> h2a = #C1<self::test::T>;
   () → self::A<self::test::T> h2b = #C1<self::test::T>;
   () → self::A<self::test::T> h2c = #C1<self::test::T>;
@@ -53,5 +53,4 @@
 constants  {
   #C1 = constructor-tearoff self::A::•
   #C2 = instantiation self::A::• <core::int*>
-  #C3 = instantiation self::A::• <core::int>
 }
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 54daed1..deb3803 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
@@ -33,7 +33,7 @@
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:15:31 -> InstantiationConstant(A.<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:17:13 -> InstantiationConstant(A.<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:18:13 -> InstantiationConstant(A.<int*>)
-Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:19:31 -> InstantiationConstant(A.<int>)
+Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:19:31 -> InstantiationConstant(A.<int*>)
 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*>)
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 4b8f00e..74079d8 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
@@ -16,7 +16,7 @@
 static const field () → self::A<core::int> f1c = #C2;
 static const field () → self::A<core::int> g1a = #C2;
 static const field () → self::A<core::int> g1b = #C2;
-static const field () → self::A<core::int> g1c = #C3;
+static const field () → self::A<core::int> g1c = #C2;
 static const field () → self::A<core::int> h1a = #C2;
 static const field () → self::A<core::int> h1b = #C2;
 static const field () → self::A<core::int> h1c = #C2;
@@ -25,7 +25,7 @@
   core::identical(#C2, #C2);
   core::identical(#C2, #C2);
   core::identical(#C2, #C2);
-  core::identical(#C2, #C3);
+  core::identical(#C2, #C2);
   core::identical(#C2, #C2);
   core::identical(#C2, #C2);
 }
@@ -35,7 +35,7 @@
   () → self::A<self::test::T> f2c = #C1<self::test::T>;
   () → self::A<core::int> g2a = #C2;
   () → self::A<core::int> g2b = #C2;
-  () → self::A<core::int> g2c = #C3;
+  () → self::A<core::int> g2c = #C2;
   () → self::A<self::test::T> h2a = #C1<self::test::T>;
   () → self::A<self::test::T> h2b = #C1<self::test::T>;
   () → self::A<self::test::T> h2c = #C1<self::test::T>;
@@ -53,14 +53,13 @@
 constants  {
   #C1 = constructor-tearoff self::A::•
   #C2 = instantiation self::A::• <core::int*>
-  #C3 = instantiation self::A::• <core::int>
 }
 
 Extra constant evaluation status:
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:28:3 -> BoolConstant(true)
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:29:3 -> BoolConstant(true)
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:31:3 -> BoolConstant(true)
-Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:32:3 -> BoolConstant(false)
+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
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_non_proper_rename.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_non_proper_rename.dart.weak.expect
index b2261ef..942bbe6 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_non_proper_rename.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_non_proper_rename.dart.weak.expect
@@ -24,45 +24,45 @@
 static final field core::bool inSoundMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
 static const field () → self::A<core::int> f1a = #C2;
 static const field () → self::A<core::int> f1b = #C2;
-static const field () → self::A<core::int> f1c = #C3;
-static const field () → self::A<core::int> f1d = #C5;
-static const field () → self::A<core::int> f1e = #C5;
-static const field () → self::A<core::int> f1f = #C6;
-static const field () → self::A<core::int> f1g = #C8;
-static const field () → self::A<core::int> f1h = #C8;
-static const field () → self::A<core::int> f1i = #C9;
+static const field () → self::A<core::int> f1c = #C2;
+static const field () → self::A<core::int> f1d = #C4;
+static const field () → self::A<core::int> f1e = #C4;
+static const field () → self::A<core::int> f1f = #C4;
+static const field () → self::A<core::int> f1g = #C6;
+static const field () → self::A<core::int> f1h = #C6;
+static const field () → self::A<core::int> f1i = #C6;
 static const field () → self::A<core::int> g1a = #C2;
 static const field () → self::A<core::int> g1b = #C2;
-static const field () → self::A<core::int> g1c = #C3;
+static const field () → self::A<core::int> g1c = #C2;
 static const field () → self::A<core::int> h1a = #C2;
 static const field () → self::A<core::int> h1b = #C2;
-static const field () → self::A<core::int> h1c = #C3;
+static const field () → self::A<core::int> h1c = #C2;
 static method main() → dynamic {
   self::test<core::int>();
   core::identical(#C2, #C2);
-  core::identical(#C2, #C3);
-  core::identical(#C5, #C5);
-  core::identical(#C5, #C6);
-  core::identical(#C8, #C8);
-  core::identical(#C8, #C9);
   core::identical(#C2, #C2);
-  core::identical(#C2, #C3);
+  core::identical(#C4, #C4);
+  core::identical(#C4, #C4);
+  core::identical(#C6, #C6);
+  core::identical(#C6, #C6);
   core::identical(#C2, #C2);
-  core::identical(#C2, #C3);
+  core::identical(#C2, #C2);
+  core::identical(#C2, #C2);
+  core::identical(#C2, #C2);
 }
 static method test<T extends core::num>() → dynamic {
   () → self::A<self::test::T> f2a = #C1<self::test::T>;
   () → self::A<self::test::T> f2b = #C1<self::test::T>;
   () → self::A<self::test::T> f2c = #C1<self::test::T>;
-  () → self::A<self::test::T> f2d = #C4<self::test::T>;
-  () → self::A<self::test::T> f2e = #C4<self::test::T>;
-  () → self::A<self::test::T> f2f = #C4<self::test::T>;
-  () → self::A<self::test::T> f2g = #C7<self::test::T>;
-  () → self::A<self::test::T> f2h = #C7<self::test::T>;
-  () → self::A<self::test::T> f2i = #C7<self::test::T>;
+  () → self::A<self::test::T> f2d = #C3<self::test::T>;
+  () → self::A<self::test::T> f2e = #C3<self::test::T>;
+  () → self::A<self::test::T> f2f = #C3<self::test::T>;
+  () → self::A<self::test::T> f2g = #C5<self::test::T>;
+  () → self::A<self::test::T> f2h = #C5<self::test::T>;
+  () → self::A<self::test::T> f2i = #C5<self::test::T>;
   () → self::A<core::int> g2a = #C2;
   () → self::A<core::int> g2b = #C2;
-  () → self::A<core::int> g2c = #C3;
+  () → self::A<core::int> g2c = #C2;
   () → self::A<self::test::T> h2a = #C1<self::test::T>;
   () → self::A<self::test::T> h2b = #C1<self::test::T>;
   () → self::A<self::test::T> h2c = #C1<self::test::T>;
@@ -98,11 +98,8 @@
 constants  {
   #C1 = static-tearoff self::A::_#new#tearOff
   #C2 = instantiation self::A::_#new#tearOff <core::int*>
-  #C3 = instantiation self::A::_#new#tearOff <core::int>
-  #C4 = static-tearoff self::A::_#fact#tearOff
-  #C5 = instantiation self::A::_#fact#tearOff <core::int*>
-  #C6 = instantiation self::A::_#fact#tearOff <core::int>
-  #C7 = static-tearoff self::A::_#redirect#tearOff
-  #C8 = instantiation self::A::_#redirect#tearOff <core::int*>
-  #C9 = instantiation self::A::_#redirect#tearOff <core::int>
+  #C3 = static-tearoff self::A::_#fact#tearOff
+  #C4 = instantiation self::A::_#fact#tearOff <core::int*>
+  #C5 = static-tearoff self::A::_#redirect#tearOff
+  #C6 = instantiation self::A::_#redirect#tearOff <core::int*>
 }
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_non_proper_rename.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_non_proper_rename.dart.weak.outline.expect
index 05aae66..feba408 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_non_proper_rename.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_non_proper_rename.dart.weak.outline.expect
@@ -65,17 +65,17 @@
 Extra constant evaluation status:
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:17:13 -> InstantiationConstant(A._#new#tearOff<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:18:13 -> InstantiationConstant(A._#new#tearOff<int*>)
-Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:19:31 -> InstantiationConstant(A._#new#tearOff<int>)
+Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:19:31 -> InstantiationConstant(A._#new#tearOff<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:20:13 -> InstantiationConstant(A._#fact#tearOff<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:21:13 -> InstantiationConstant(A._#fact#tearOff<int*>)
-Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:22:31 -> InstantiationConstant(A._#fact#tearOff<int>)
+Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:22:31 -> InstantiationConstant(A._#fact#tearOff<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:23:13 -> InstantiationConstant(A._#redirect#tearOff<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:24:13 -> InstantiationConstant(A._#redirect#tearOff<int*>)
-Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:25:31 -> InstantiationConstant(A._#redirect#tearOff<int>)
+Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:25:31 -> InstantiationConstant(A._#redirect#tearOff<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:27:13 -> InstantiationConstant(A._#new#tearOff<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:28:13 -> InstantiationConstant(A._#new#tearOff<int*>)
-Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:29:31 -> InstantiationConstant(A._#new#tearOff<int>)
+Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:29:31 -> InstantiationConstant(A._#new#tearOff<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:31:13 -> InstantiationConstant(A._#new#tearOff<int*>)
 Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:32:13 -> InstantiationConstant(A._#new#tearOff<int*>)
-Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:33:31 -> InstantiationConstant(A._#new#tearOff<int>)
+Evaluated: Instantiation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:33:31 -> InstantiationConstant(A._#new#tearOff<int*>)
 Extra constant evaluation: evaluated: 30, effectively constant: 15
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_non_proper_rename.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_non_proper_rename.dart.weak.transformed.expect
index 5829743..3d86e63 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_non_proper_rename.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/inferred_non_proper_rename.dart.weak.transformed.expect
@@ -24,45 +24,45 @@
 static final field core::bool inSoundMode = !(core::_GrowableList::•<core::int?>(0) is{ForNonNullableByDefault} core::List<core::int>);
 static const field () → self::A<core::int> f1a = #C2;
 static const field () → self::A<core::int> f1b = #C2;
-static const field () → self::A<core::int> f1c = #C3;
-static const field () → self::A<core::int> f1d = #C5;
-static const field () → self::A<core::int> f1e = #C5;
-static const field () → self::A<core::int> f1f = #C6;
-static const field () → self::A<core::int> f1g = #C8;
-static const field () → self::A<core::int> f1h = #C8;
-static const field () → self::A<core::int> f1i = #C9;
+static const field () → self::A<core::int> f1c = #C2;
+static const field () → self::A<core::int> f1d = #C4;
+static const field () → self::A<core::int> f1e = #C4;
+static const field () → self::A<core::int> f1f = #C4;
+static const field () → self::A<core::int> f1g = #C6;
+static const field () → self::A<core::int> f1h = #C6;
+static const field () → self::A<core::int> f1i = #C6;
 static const field () → self::A<core::int> g1a = #C2;
 static const field () → self::A<core::int> g1b = #C2;
-static const field () → self::A<core::int> g1c = #C3;
+static const field () → self::A<core::int> g1c = #C2;
 static const field () → self::A<core::int> h1a = #C2;
 static const field () → self::A<core::int> h1b = #C2;
-static const field () → self::A<core::int> h1c = #C3;
+static const field () → self::A<core::int> h1c = #C2;
 static method main() → dynamic {
   self::test<core::int>();
   core::identical(#C2, #C2);
-  core::identical(#C2, #C3);
-  core::identical(#C5, #C5);
-  core::identical(#C5, #C6);
-  core::identical(#C8, #C8);
-  core::identical(#C8, #C9);
   core::identical(#C2, #C2);
-  core::identical(#C2, #C3);
+  core::identical(#C4, #C4);
+  core::identical(#C4, #C4);
+  core::identical(#C6, #C6);
+  core::identical(#C6, #C6);
   core::identical(#C2, #C2);
-  core::identical(#C2, #C3);
+  core::identical(#C2, #C2);
+  core::identical(#C2, #C2);
+  core::identical(#C2, #C2);
 }
 static method test<T extends core::num>() → dynamic {
   () → self::A<self::test::T> f2a = #C1<self::test::T>;
   () → self::A<self::test::T> f2b = #C1<self::test::T>;
   () → self::A<self::test::T> f2c = #C1<self::test::T>;
-  () → self::A<self::test::T> f2d = #C4<self::test::T>;
-  () → self::A<self::test::T> f2e = #C4<self::test::T>;
-  () → self::A<self::test::T> f2f = #C4<self::test::T>;
-  () → self::A<self::test::T> f2g = #C7<self::test::T>;
-  () → self::A<self::test::T> f2h = #C7<self::test::T>;
-  () → self::A<self::test::T> f2i = #C7<self::test::T>;
+  () → self::A<self::test::T> f2d = #C3<self::test::T>;
+  () → self::A<self::test::T> f2e = #C3<self::test::T>;
+  () → self::A<self::test::T> f2f = #C3<self::test::T>;
+  () → self::A<self::test::T> f2g = #C5<self::test::T>;
+  () → self::A<self::test::T> f2h = #C5<self::test::T>;
+  () → self::A<self::test::T> f2i = #C5<self::test::T>;
   () → self::A<core::int> g2a = #C2;
   () → self::A<core::int> g2b = #C2;
-  () → self::A<core::int> g2c = #C3;
+  () → self::A<core::int> g2c = #C2;
   () → self::A<self::test::T> h2a = #C1<self::test::T>;
   () → self::A<self::test::T> h2b = #C1<self::test::T>;
   () → self::A<self::test::T> h2c = #C1<self::test::T>;
@@ -98,24 +98,21 @@
 constants  {
   #C1 = static-tearoff self::A::_#new#tearOff
   #C2 = instantiation self::A::_#new#tearOff <core::int*>
-  #C3 = instantiation self::A::_#new#tearOff <core::int>
-  #C4 = static-tearoff self::A::_#fact#tearOff
-  #C5 = instantiation self::A::_#fact#tearOff <core::int*>
-  #C6 = instantiation self::A::_#fact#tearOff <core::int>
-  #C7 = static-tearoff self::A::_#redirect#tearOff
-  #C8 = instantiation self::A::_#redirect#tearOff <core::int*>
-  #C9 = instantiation self::A::_#redirect#tearOff <core::int>
+  #C3 = static-tearoff self::A::_#fact#tearOff
+  #C4 = instantiation self::A::_#fact#tearOff <core::int*>
+  #C5 = static-tearoff self::A::_#redirect#tearOff
+  #C6 = instantiation self::A::_#redirect#tearOff <core::int*>
 }
 
 Extra constant evaluation status:
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:38:3 -> BoolConstant(true)
-Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:39:3 -> BoolConstant(false)
+Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:39:3 -> BoolConstant(true)
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:41:3 -> BoolConstant(true)
-Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:42:3 -> BoolConstant(false)
+Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:42:3 -> BoolConstant(true)
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:44:3 -> BoolConstant(true)
-Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:45:3 -> BoolConstant(false)
+Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:45:3 -> BoolConstant(true)
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:47:3 -> BoolConstant(true)
-Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:48:3 -> BoolConstant(false)
+Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:48:3 -> BoolConstant(true)
 Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:50:3 -> BoolConstant(true)
-Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:51:3 -> BoolConstant(false)
+Evaluated: StaticInvocation @ org-dartlang-testcase:///inferred_non_proper_rename.dart:51:3 -> BoolConstant(true)
 Extra constant evaluation: evaluated: 59, effectively constant: 10
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart
new file mode 100644
index 0000000..a9b94ff
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart
@@ -0,0 +1,13 @@
+// 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";
+
+typedef S1<T> = dynamic;
+typedef S2<T> = Null;
+typedef S3<T> = void;
+typedef S4<T> = FutureOr;
+typedef S5<T> = FutureOr<T>;
+
+main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.strong.expect
new file mode 100644
index 0000000..715328b
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.strong.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "dart:async";
+
+typedef S1<unrelated T extends core::Object? = dynamic> = dynamic;
+typedef S2<unrelated T extends core::Object? = dynamic> = Null;
+typedef S3<unrelated T extends core::Object? = dynamic> = void;
+typedef S4<unrelated T extends core::Object? = dynamic> = FutureOr<dynamic>;
+typedef S5<T extends core::Object? = dynamic> = FutureOr<T%>;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.strong.transformed.expect
new file mode 100644
index 0000000..715328b
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "dart:async";
+
+typedef S1<unrelated T extends core::Object? = dynamic> = dynamic;
+typedef S2<unrelated T extends core::Object? = dynamic> = Null;
+typedef S3<unrelated T extends core::Object? = dynamic> = void;
+typedef S4<unrelated T extends core::Object? = dynamic> = FutureOr<dynamic>;
+typedef S5<T extends core::Object? = dynamic> = FutureOr<T%>;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.textual_outline.expect
new file mode 100644
index 0000000..2114f5f
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+import "dart:async";
+
+typedef S1<T> = dynamic;
+typedef S2<T> = Null;
+typedef S3<T> = void;
+typedef S4<T> = FutureOr;
+typedef S5<T> = FutureOr<T>;
+main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..392a9cf
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+import "dart:async";
+
+main() {}
+typedef S1<T> = dynamic;
+typedef S2<T> = Null;
+typedef S3<T> = void;
+typedef S4<T> = FutureOr;
+typedef S5<T> = FutureOr<T>;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.weak.expect
new file mode 100644
index 0000000..715328b
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.weak.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "dart:async";
+
+typedef S1<unrelated T extends core::Object? = dynamic> = dynamic;
+typedef S2<unrelated T extends core::Object? = dynamic> = Null;
+typedef S3<unrelated T extends core::Object? = dynamic> = void;
+typedef S4<unrelated T extends core::Object? = dynamic> = FutureOr<dynamic>;
+typedef S5<T extends core::Object? = dynamic> = FutureOr<T%>;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.weak.outline.expect
new file mode 100644
index 0000000..ddea941
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.weak.outline.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "dart:async";
+
+typedef S1<unrelated T extends core::Object? = dynamic> = dynamic;
+typedef S2<unrelated T extends core::Object? = dynamic> = Null;
+typedef S3<unrelated T extends core::Object? = dynamic> = void;
+typedef S4<unrelated T extends core::Object? = dynamic> = FutureOr<dynamic>;
+typedef S5<T extends core::Object? = dynamic> = FutureOr<T%>;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.weak.transformed.expect
new file mode 100644
index 0000000..715328b
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/lowering/non_class_typedefs.dart.weak.transformed.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "dart:async";
+
+typedef S1<unrelated T extends core::Object? = dynamic> = dynamic;
+typedef S2<unrelated T extends core::Object? = dynamic> = Null;
+typedef S3<unrelated T extends core::Object? = dynamic> = void;
+typedef S4<unrelated T extends core::Object? = dynamic> = FutureOr<dynamic>;
+typedef S5<T extends core::Object? = dynamic> = FutureOr<T%>;
+static method main() → dynamic {}
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 c139fe9..525fab5 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:762:8 -> SymbolConstant(#clear)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:762:8 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:762:8 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/_http/http.dart:762:8 -> 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>[]})
 Extra constant evaluation: evaluated: 268, effectively constant: 91
diff --git a/sdk/lib/_http/http.dart b/sdk/lib/_http/http.dart
index 47e481a..abc401e 100644
--- a/sdk/lib/_http/http.dart
+++ b/sdk/lib/_http/http.dart
@@ -391,6 +391,18 @@
   static const acceptEncodingHeader = "accept-encoding";
   static const acceptLanguageHeader = "accept-language";
   static const acceptRangesHeader = "accept-ranges";
+  static const accessControlAllowCredentialsHeader =
+      'access-control-allow-credentials';
+  static const accessControlAllowHeadersHeader = 'access-control-allow-headers';
+  static const accessControlAllowMethodsHeader = 'access-control-allow-methods';
+  static const accessControlAllowOriginHeader = 'access-control-allow-origin';
+  static const accessControlExposeHeadersHeader =
+      'access-control-expose-headers';
+  static const accessControlMaxAgeHeader = 'access-control-max-age';
+  static const accessControlRequestHeadersHeader =
+      'access-control-request-headers';
+  static const accessControlRequestMethodHeader =
+      'access-control-request-method';
   static const ageHeader = "age";
   static const allowHeader = "allow";
   static const authorizationHeader = "authorization";
diff --git a/tests/language/typedef/aliased_type_literal_instantiation_test.dart b/tests/language/typedef/aliased_type_literal_instantiation_test.dart
index 25dc8f9..d30640f 100644
--- a/tests/language/typedef/aliased_type_literal_instantiation_test.dart
+++ b/tests/language/typedef/aliased_type_literal_instantiation_test.dart
@@ -23,9 +23,11 @@
 
 void main() {
   const Type co = C<Object?>;
+  const Type cd = C<dynamic>;
   const Type cn = C<num>;
   const Type ci = C<int>;
   const Type cco = C<C<Object?>>;
+  const Type ccd = C<C<dynamic>>;
   const Type cci = C<C<int>>;
   const Type s1 = Special;
   const Type d1 = Direct;
@@ -42,16 +44,16 @@
   const Type e3 = Extra<int, bool>;
 
   Expect.identical(s1, ci);
-  Expect.identical(d1, co);
+  Expect.identical(d1, cd);
   Expect.identical(d2, co);
   Expect.identical(d3, ci);
   Expect.identical(b1, cn);
   Expect.identical(b2, cn);
   Expect.identical(b3, ci);
-  Expect.identical(w1, cco);
+  Expect.identical(w1, ccd);
   Expect.identical(w2, cco);
   Expect.identical(w3, cci);
-  Expect.identical(e1, co);
+  Expect.identical(e1, cd);
   Expect.identical(e2, co);
   Expect.identical(e3, ci);
 
diff --git a/tools/VERSION b/tools/VERSION
index 7ff6d89..3cb9897 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 384
+PRERELEASE 385
 PRERELEASE_PATCH 0
\ No newline at end of file