Version 2.15.0-216.0.dev

Merge commit '868b6a898ca96ad9569ecc4b3ca3925441038841' into 'dev'
diff --git a/DEPS b/DEPS
index d2446c0..54d174b 100644
--- a/DEPS
+++ b/DEPS
@@ -603,11 +603,12 @@
       "dep_type": "cipd",
   },
 
+  # Update from https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/gn
   Var("dart_root") + "/third_party/fuchsia/sdk/linux": {
     "packages": [
       {
       "package": "fuchsia/sdk/gn/linux-amd64",
-      "version": "git_revision:e0a61431eb6e28d31d293cbb0c12f6b3a089bba4"
+      "version": "git_revision:190502a955c482431c2edd0525e128423728b662"
       }
     ],
     "condition": 'host_os == "linux" and host_cpu == "x64"',
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index 2d4f96e..896bede 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -8257,6 +8257,16 @@
     if (token.isIdentifier && optional('.', token.next!)) {
       prefix = token;
       period = token.next!;
+      Token identifier = period.next!;
+      if (identifier.kind == KEYWORD_TOKEN && optional('new', identifier)) {
+        // Treat `new` after `.` is as an identifier so that it can represent an
+        // unnamed constructor. This support is separate from the
+        // constructor-tearoffs feature.
+        rewriter.replaceTokenFollowing(
+            period,
+            new StringToken(TokenType.IDENTIFIER, identifier.lexeme,
+                identifier.charOffset));
+      }
       token = period.next!;
     }
     if (token.isEof) {
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index 55ab879..326a8eb 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -95,30 +95,32 @@
   Future<void> test_constructor_unnamed() async {
     addTestFile('''
 /// [new A] 1
+/// [A.new] 2
 class A {
   A() {}
-  A.other() : this(); // 2
+  A.other() : this(); // 3
 }
 
 class B extends A {
-  B() : super(); // 3
-  factory B.other() = A; // 4
+  B() : super(); // 4
+  factory B.other() = A; // 5
 }
 
 void f() {
-  A(); // 5
-  A.new; // 6
+  A(); // 6
+  A.new; // 7
 }
 ''');
     await findElementReferences('A() {}', false);
     expect(searchElement!.kind, ElementKind.CONSTRUCTOR);
-    expect(results, hasLength(6));
+    expect(results, hasLength(7));
     assertHasResult(SearchResultKind.REFERENCE, '] 1', 0);
-    assertHasResult(SearchResultKind.INVOCATION, '(); // 2', 0);
+    assertHasResult(SearchResultKind.REFERENCE, '.new] 2', 4);
     assertHasResult(SearchResultKind.INVOCATION, '(); // 3', 0);
-    assertHasResult(SearchResultKind.REFERENCE, '; // 4', 0);
-    assertHasResult(SearchResultKind.INVOCATION, '(); // 5', 0);
-    assertHasResult(SearchResultKind.REFERENCE, '.new; // 6', 4);
+    assertHasResult(SearchResultKind.INVOCATION, '(); // 4', 0);
+    assertHasResult(SearchResultKind.REFERENCE, '; // 5', 0);
+    assertHasResult(SearchResultKind.INVOCATION, '(); // 6', 0);
+    assertHasResult(SearchResultKind.REFERENCE, '.new; // 7', 4);
   }
 
   Future<void> test_constructor_unnamed_potential() async {
diff --git a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
index cd2d918..ae554f5 100644
--- a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
+++ b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
@@ -380,14 +380,10 @@
 
   /// Return `true` if the [node] is a (potentially) constant type expression.
   bool check(TypeAnnotation? node) {
-    if (potentially) {
-      if (node is NamedType) {
-        var element = node.name.staticElement;
-        if (element is TypeParameterElement) {
-          var enclosing = element.enclosingElement;
-          return enclosing is ClassElement && !enclosing.isMixin;
-        }
-      }
+    if (potentially &&
+        node is NamedType &&
+        node.name.staticElement is TypeParameterElement) {
+      return true;
     }
 
     if (node is NamedType) {
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
index 3406875..0608b1f 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.g.dart
@@ -1232,12 +1232,11 @@
    * This hint is generated anywhere where `@nonVirtual` annotates something
    * other than a non-abstract instance member in a class or mixin.
    *
-   * Parameters:
-   * 0: the name of the member
+   * No Parameters.
    */
   static const HintCode INVALID_NON_VIRTUAL_ANNOTATION = HintCode(
     'INVALID_NON_VIRTUAL_ANNOTATION',
-    "The member '{0}' can't be '@nonVirtual' because it isn't a concrete instance member.",
+    "The annotation '@nonVirtual' can only be applied to a concrete instance member.",
     correctionMessage: "Try removing @nonVirtual.",
   );
 
@@ -1297,12 +1296,11 @@
    * This hint is generated anywhere where `@sealed` annotates something other
    * than a class.
    *
-   * Parameters:
-   * 0: the name of the member
+   * No parameters.
    */
   static const HintCode INVALID_SEALED_ANNOTATION = HintCode(
     'INVALID_SEALED_ANNOTATION',
-    "The member '{0}' is annotated with '@sealed' but only classes can be annotated with it.",
+    "The annotation '@sealed' can only be applied to classes.",
     correctionMessage: "Remove @sealed.",
   );
 
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
index a611f9f..52c0c39 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
@@ -595,7 +595,7 @@
         _resolver.errorReporter.reportErrorForNode(
           CompileTimeErrorCode.UNDEFINED_METHOD,
           function,
-          [function.name, enclosingClass],
+          [function.name, receiverType],
         );
         function.staticType = DynamicTypeImpl.instance;
         node.staticType = DynamicTypeImpl.instance;
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 3900f37..a8de577 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -201,29 +201,23 @@
       if (parent is FieldDeclaration) {
         if (parent.isStatic) {
           _errorReporter.reportErrorForNode(
-              HintCode.INVALID_NON_VIRTUAL_ANNOTATION,
-              node,
-              [node.element!.name]);
+              HintCode.INVALID_NON_VIRTUAL_ANNOTATION, node);
         }
       } else if (parent is MethodDeclaration) {
         if (parent.parent is ExtensionDeclaration ||
             parent.isStatic ||
             parent.isAbstract) {
           _errorReporter.reportErrorForNode(
-              HintCode.INVALID_NON_VIRTUAL_ANNOTATION,
-              node,
-              [node.element!.name]);
+              HintCode.INVALID_NON_VIRTUAL_ANNOTATION, node);
         }
       } else {
         _errorReporter.reportErrorForNode(
-            HintCode.INVALID_NON_VIRTUAL_ANNOTATION,
-            node,
-            [node.element!.name]);
+            HintCode.INVALID_NON_VIRTUAL_ANNOTATION, node);
       }
     } else if (element.isSealed == true) {
       if (!(parent is ClassDeclaration || parent is ClassTypeAlias)) {
         _errorReporter.reportErrorForNode(
-            HintCode.INVALID_SEALED_ANNOTATION, node, [node.element!.name]);
+            HintCode.INVALID_SEALED_ANNOTATION, node);
       }
     } else if (element.isVisibleForTemplate == true ||
         element.isVisibleForTesting == true ||
@@ -240,7 +234,7 @@
           _errorReporter.reportErrorForNode(
               HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION,
               node,
-              [declaredElement.name]);
+              [declaredElement.name ?? '<unnamed>']);
         }
 
         if (parent is TopLevelVariableDeclaration) {
@@ -275,7 +269,8 @@
             reportInvalidVisibleForOverriding(declaredElement);
           }
 
-          if (Identifier.isPrivateName(declaredElement.name!)) {
+          var name = declaredElement.name;
+          if (name != null && Identifier.isPrivateName(name)) {
             reportInvalidAnnotation(declaredElement);
           }
         }
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index ca0efc9..684e1ac8 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -112,7 +112,7 @@
               _errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
                 identifier,
-                [node.declaredElement!.name, name],
+                [node.declaredElement!.name ?? '<unnamed>', name],
               );
             }
           }
@@ -126,7 +126,7 @@
             _errorReporter.reportErrorForNode(
               CompileTimeErrorCode.EXTENSION_CONFLICTING_STATIC_AND_INSTANCE,
               identifier,
-              [node.declaredElement!.name, name],
+              [node.declaredElement!.name ?? '<unnamed>', name],
             );
           }
         }
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 7f2a709..daa682e 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -129,27 +129,19 @@
     if (identifier is SimpleIdentifierImpl) {
       var element = _resolveSimpleIdentifier(identifier);
       if (element == null) {
-        // TODO(brianwilkerson) Report this error?
-        //        resolver.reportError(
-        //            CompileTimeErrorCode.UNDEFINED_IDENTIFIER,
-        //            simpleIdentifier,
-        //            simpleIdentifier.getName());
-      } else {
-        if (element.library == null || element.library != _definingLibrary) {
-          // TODO(brianwilkerson) Report this error?
-        }
-        identifier.staticElement = element;
-        if (node.newKeyword != null) {
-          if (element is ClassElement) {
-            var constructor = element.unnamedConstructor;
-            if (constructor == null) {
-              // TODO(brianwilkerson) Report this error.
-            } else {
-              identifier.staticElement = constructor;
-            }
-          } else {
+        return;
+      }
+      identifier.staticElement = element;
+      if (node.newKeyword != null) {
+        if (element is ClassElement) {
+          var constructor = element.unnamedConstructor;
+          if (constructor == null) {
             // TODO(brianwilkerson) Report this error.
+          } else {
+            identifier.staticElement = constructor;
           }
+        } else {
+          // TODO(brianwilkerson) Report this error.
         }
       }
     } else if (identifier is PrefixedIdentifierImpl) {
@@ -160,7 +152,6 @@
       var name = identifier.identifier;
 
       if (prefixElement == null) {
-//        resolver.reportError(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, prefix, prefix.getName());
         return;
       }
 
@@ -173,11 +164,6 @@
         return;
       }
 
-      var library = prefixElement.library;
-      if (library != _definingLibrary) {
-        // TODO(brianwilkerson) Report this error.
-      }
-
       if (node.newKeyword == null) {
         if (prefixElement is ClassElement) {
           name.staticElement = prefixElement.getMethod(name.name) ??
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 2efaaa1..6ae58a0 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -385,7 +385,7 @@
               reporter.reportErrorForSpan(
                   AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE,
                   k.span,
-                  [k.value?.toString()]);
+                  [k.value.toString()]);
             }
           }
           if (v is YamlScalar) {
@@ -397,7 +397,7 @@
                   v.span,
                   [
                     AnalyzerOptions.errors,
-                    v.value?.toString(),
+                    v.value.toString(),
                     legalValueString
                   ]);
             }
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index bee1e35..cf4a160 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -14959,14 +14959,13 @@
       var x;
       ```
   INVALID_NON_VIRTUAL_ANNOTATION:
-    problemMessage: "The member '{0}' can't be '@nonVirtual' because it isn't a concrete instance member."
+    problemMessage: "The annotation '@nonVirtual' can only be applied to a concrete instance member."
     correctionMessage: Try removing @nonVirtual.
     comment: |-
       This hint is generated anywhere where `@nonVirtual` annotates something
       other than a non-abstract instance member in a class or mixin.
 
-      Parameters:
-      0: the name of the member
+      No Parameters.
   INVALID_OVERRIDE_OF_NON_VIRTUAL_MEMBER:
     problemMessage: "The member '{0}' is declared non-virtual in '{1}' and can't be overridden in subclasses."
     comment: |-
@@ -15070,14 +15069,13 @@
       }
       ```
   INVALID_SEALED_ANNOTATION:
-    problemMessage: "The member '{0}' is annotated with '@sealed' but only classes can be annotated with it."
+    problemMessage: "The annotation '@sealed' can only be applied to classes."
     correctionMessage: Remove @sealed.
     comment: |-
       This hint is generated anywhere where `@sealed` annotates something other
       than a class.
 
-      Parameters:
-      0: the name of the member
+      No parameters.
   INVALID_USE_OF_INTERNAL_MEMBER:
     problemMessage: "The member '{0}' can only be used within its package."
     comment: |-
diff --git a/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart b/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart
index 3f6571e..7fbe061 100644
--- a/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart
+++ b/pkg/analyzer/test/generated/new_as_identifier_parser_test.dart
@@ -256,6 +256,14 @@
     expect(methodInvocation.argumentList, isNotNull);
   }
 
+  void test_constructor_tearoff_in_comment_reference() {
+    createParser('');
+    var commentReference = parseCommentReference('C.new', 5)!;
+    var identifier = commentReference.identifier as PrefixedIdentifier;
+    expect(identifier.prefix.name, 'C');
+    expect(identifier.identifier.name, 'new');
+  }
+
   void test_constructor_tearoff_method_invocation() {
     var methodInvocation =
         parseExpression('C.new.toString()', featureSet: constructorTearoffs)
diff --git a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
index 8a70510..e356a67 100644
--- a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
@@ -118,42 +118,25 @@
 ''');
   }
 
-  test_typeParameter_ofExtension() async {
-    await _assertNeverConst(r'''
-extension E<T> on int {
-  void foo() {
-    T x;
-  }
-}
-''');
-  }
-
   test_typeParameter_ofFunction() async {
-    await _assertNeverConst(r'''
+    await _assertPotentiallyConst('''
 void foo<T>() {
   T x;
 }
 ''');
   }
 
-  test_typeParameter_ofMethod() async {
-    await _assertNeverConst(r'''
-class A {
-  void foo<T>() {
-    T x;
+  test_typeParameter_ofFunctionType() async {
+    await _assertPotentiallyConst('''
+class A<U> {
+  const A();
+  void foo() {
+    void Function<X>(X) x;
   }
 }
 ''');
   }
 
-  test_typeParameter_ofMixin() async {
-    await _assertNeverConst(r'''
-mixin M<T> {
-  T x;
-}
-''');
-  }
-
   test_void() async {
     await _assertConst(r'''
 void x;
diff --git a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
index fea1532..7f61cf5 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_reference_test.dart
@@ -338,6 +338,23 @@
         reference, findElement.method('foo'), 'void Function(int)');
   }
 
+  test_extensionMethod_unknown() async {
+    await assertErrorsInCode('''
+extension on double {
+  bar() {
+    foo<int>;
+  }
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 24, 3),
+      error(CompileTimeErrorCode.UNDEFINED_METHOD, 36, 3,
+          messageContains: "for the type 'double'"),
+    ]);
+
+    assertFunctionReference(
+        findNode.functionReference('foo<int>;'), null, 'dynamic');
+  }
+
   test_function_call() async {
     await assertNoErrorsInCode('''
 void foo<T>(T a) {}
@@ -874,7 +891,8 @@
   }
 }
 ''', [
-      error(CompileTimeErrorCode.UNDEFINED_METHOD, 24, 3),
+      error(CompileTimeErrorCode.UNDEFINED_METHOD, 24, 3,
+          messageContains: "for the type 'A'"),
     ]);
 
     assertFunctionReference(
diff --git a/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart b/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart
index d2581f7..b85b744 100644
--- a/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/extension_conflicting_static_and_instance_test.dart
@@ -86,6 +86,19 @@
     ]);
   }
 
+  test_field_getter_unnamed() async {
+    await assertErrorsInCode('''
+extension on String {
+  static int foo = 0;
+  int get foo => 0;
+}
+''', [
+      error(HintCode.UNUSED_FIELD, 35, 3),
+      error(_errorCode, 35, 3, messageContains: "Extension '<unnamed>'"),
+      error(HintCode.UNUSED_ELEMENT, 54, 3),
+    ]);
+  }
+
   test_field_method() async {
     await assertErrorsInCode('''
 extension E on String {
@@ -93,7 +106,7 @@
   void foo() {}
 }
 ''', [
-      error(_errorCode, 37, 3),
+      error(_errorCode, 37, 3, messageContains: "Extension 'E'"),
     ]);
   }
 
@@ -115,7 +128,20 @@
   int get foo => 0;
 }
 ''', [
-      error(_errorCode, 41, 3),
+      error(_errorCode, 41, 3, messageContains: "Extension 'E'"),
+    ]);
+  }
+
+  test_getter_getter_unnamed() async {
+    await assertErrorsInCode('''
+extension on String {
+  static int get foo => 0;
+  int get foo => 0;
+}
+''', [
+      error(HintCode.UNUSED_ELEMENT, 39, 3),
+      error(_errorCode, 39, 3, messageContains: "Extension '<unnamed>'"),
+      error(HintCode.UNUSED_ELEMENT, 59, 3),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_visible_for_overriding_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_visible_for_overriding_annotation_test.dart
index 910acf3..9fa9832 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_visible_for_overriding_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_visible_for_overriding_annotation_test.dart
@@ -27,7 +27,10 @@
 import 'package:meta/meta.dart';
 @visibleForOverriding
 class C {}
-''', [error(HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION, 33, 21)]);
+''', [
+      error(HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION, 33, 21,
+          messageContains: "The declaration 'C'")
+    ]);
   }
 
   test_invalid_constructor() async {
@@ -42,6 +45,17 @@
     ]);
   }
 
+  test_invalid_extension_unnamed() async {
+    await assertErrorsInCode('''
+import 'package:meta/meta.dart';
+@visibleForOverriding
+extension on double {}
+''', [
+      error(HintCode.INVALID_VISIBLE_FOR_OVERRIDING_ANNOTATION, 33, 21,
+          messageContains: "The declaration '<unnamed>'")
+    ]);
+  }
+
   test_invalid_extensionMember() async {
     await assertErrorsInCode(r'''
 import 'package:meta/meta.dart';
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 1deba37c..fe27110 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -333,19 +333,43 @@
   }
 
   test_analyzer_error_code_supported_bad_value() {
-    validate('''
+    var errors = validate('''
 analyzer:
   errors:
     unused_local_variable: ftw
     ''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
+    expect(errors.single.problemMessage.messageText(includeUrl: false),
+        contains("The option 'ftw'"));
+  }
+
+  test_analyzer_error_code_supported_bad_value_null() {
+    var errors = validate('''
+analyzer:
+  errors:
+    unused_local_variable: null
+    ''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES]);
+    expect(errors.single.problemMessage.messageText(includeUrl: false),
+        contains("The option 'null'"));
   }
 
   test_analyzer_error_code_unsupported() {
-    validate('''
+    var errors = validate('''
 analyzer:
   errors:
     not_supported: ignore
     ''', [AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE]);
+    expect(errors.single.problemMessage.messageText(includeUrl: false),
+        contains("'not_supported' isn't a recognized error code"));
+  }
+
+  test_analyzer_error_code_unsupported_null() {
+    var errors = validate('''
+analyzer:
+  errors:
+    null: ignore
+    ''', [AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE]);
+    expect(errors.single.problemMessage.messageText(includeUrl: false),
+        contains("'null' isn't a recognized error code"));
   }
 
   test_analyzer_errors_notAMap() {
@@ -521,11 +545,12 @@
     ''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE]);
   }
 
-  void validate(String source, List<ErrorCode> expected) {
+  List<AnalysisError> validate(String source, List<ErrorCode> expected) {
     var options = optionsProvider.getOptionsFromString(source);
     var errors = validator.validate(options);
     expect(errors.map((AnalysisError e) => e.errorCode),
         unorderedEquals(expected));
+    return errors;
   }
 }
 
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 82d3011..452d6e7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -836,6 +836,16 @@
           // The initializer was already compiled (e.g., if it appear in the
           // outline, like constant field initializers) so we do not need to
           // perform type inference or transformations.
+
+          // If the body is already built and it's a type aliased constructor or
+          // factory invocation, they shouldn't be checked or resolved the
+          // second time, so they are removed from the corresponding lists.
+          if (initializer is TypeAliasedConstructorInvocation) {
+            typeAliasedConstructorInvocations.remove(initializer);
+          }
+          if (initializer is TypeAliasedFactoryInvocation) {
+            typeAliasedFactoryInvocations.remove(initializer);
+          }
         } else {
           initializer = typeInferrer.inferFieldInitializer(
               this, fieldBuilder.builtType, initializer);
diff --git a/pkg/front_end/parser_testcases/general/new_as_identifier.dart b/pkg/front_end/parser_testcases/general/new_as_identifier.dart
index 32a868f..30b926d 100644
--- a/pkg/front_end/parser_testcases/general/new_as_identifier.dart
+++ b/pkg/front_end/parser_testcases/general/new_as_identifier.dart
@@ -7,6 +7,7 @@
 //
 // Unless otherwise noted, these tests cases should not result in a parse error.
 
+/// See [C.new].
 class C {
   C.new();
 
diff --git a/pkg/front_end/parser_testcases/general/new_as_identifier.dart.expect b/pkg/front_end/parser_testcases/general/new_as_identifier.dart.expect
index e3d208d..89b9611 100644
--- a/pkg/front_end/parser_testcases/general/new_as_identifier.dart.expect
+++ b/pkg/front_end/parser_testcases/general/new_as_identifier.dart.expect
@@ -1,42 +1,42 @@
 Problems reported:
 
-parser/general/new_as_identifier:15:44: Expected an identifier, but got 'new'.
+parser/general/new_as_identifier:16:44: Expected an identifier, but got 'new'.
   C.constructor_field_initializer() : this.new = null;
                                            ^^^
 
-parser/general/new_as_identifier:15:39: Expected an assignment after the field name.
+parser/general/new_as_identifier:16:39: Expected an assignment after the field name.
   C.constructor_field_initializer() : this.new = null;
                                       ^^^^
 
-parser/general/new_as_identifier:15:44: Expected a function body, but got 'new'.
+parser/general/new_as_identifier:16:44: Expected a function body, but got 'new'.
   C.constructor_field_initializer() : this.new = null;
                                            ^^^
 
-parser/general/new_as_identifier:15:44: Expected a class member, but got 'new'.
+parser/general/new_as_identifier:16:44: Expected a class member, but got 'new'.
   C.constructor_field_initializer() : this.new = null;
                                            ^^^
 
-parser/general/new_as_identifier:15:48: Operator declarations must be preceded by the keyword 'operator'.
+parser/general/new_as_identifier:16:48: Operator declarations must be preceded by the keyword 'operator'.
   C.constructor_field_initializer() : this.new = null;
                                                ^
 
-parser/general/new_as_identifier:15:48: The string '=' isn't a user-definable operator.
+parser/general/new_as_identifier:16:48: The string '=' isn't a user-definable operator.
   C.constructor_field_initializer() : this.new = null;
                                                ^
 
-parser/general/new_as_identifier:15:48: A method declaration needs an explicit list of parameters.
+parser/general/new_as_identifier:16:48: A method declaration needs an explicit list of parameters.
   C.constructor_field_initializer() : this.new = null;
                                                ^
 
-parser/general/new_as_identifier:15:50: Expected a function body, but got 'null'.
+parser/general/new_as_identifier:16:50: Expected a function body, but got 'null'.
   C.constructor_field_initializer() : this.new = null;
                                                  ^^^^
 
-parser/general/new_as_identifier:15:50: Expected a class member, but got 'null'.
+parser/general/new_as_identifier:16:50: Expected a class member, but got 'null'.
   C.constructor_field_initializer() : this.new = null;
                                                  ^^^^
 
-parser/general/new_as_identifier:15:54: Expected a class member, but got ';'.
+parser/general/new_as_identifier:16:54: Expected a class member, but got ';'.
   C.constructor_field_initializer() : this.new = null;
                                                      ^
 
diff --git a/pkg/front_end/testcases/general/issue47339.dart b/pkg/front_end/testcases/general/issue47339.dart
new file mode 100644
index 0000000..0637fa2
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47339.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Foo {
+  const Foo.named();
+  const factory Foo.namedFactory() = Foo.named;
+}
+
+typedef Bar = Foo;
+
+const Bar bar = Bar.named();
+
+const Bar bar2 = Bar.namedFactory();
+
+class FooGeneric<X> {
+  const FooGeneric.named();
+  const factory FooGeneric.namedFactory() = FooGeneric.named;
+}
+
+typedef BarGeneric<X> = FooGeneric<X>;
+
+const BarGeneric<int> barGeneric = BarGeneric.named();
+
+const BarGeneric<int> barGeneric2 = BarGeneric.namedFactory();
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue47339.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue47339.dart.textual_outline.expect
new file mode 100644
index 0000000..5f8c270
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47339.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+class Foo {
+  const Foo.named();
+  const factory Foo.namedFactory() = Foo.named;
+}
+
+typedef Bar = Foo;
+const Bar bar = Bar.named();
+const Bar bar2 = Bar.namedFactory();
+
+class FooGeneric<X> {
+  const FooGeneric.named();
+  const factory FooGeneric.namedFactory() = FooGeneric.named;
+}
+
+typedef BarGeneric<X> = FooGeneric<X>;
+const BarGeneric<int> barGeneric = BarGeneric.named();
+const BarGeneric<int> barGeneric2 = BarGeneric.namedFactory();
+main() {}
diff --git a/pkg/front_end/testcases/general/issue47339.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue47339.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..cb8bacb
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47339.dart.textual_outline_modelled.expect
@@ -0,0 +1,17 @@
+class Foo {
+  const Foo.named();
+  const factory Foo.namedFactory() = Foo.named;
+}
+
+class FooGeneric<X> {
+  const FooGeneric.named();
+  const factory FooGeneric.namedFactory() = FooGeneric.named;
+}
+
+const Bar bar = Bar.named();
+const Bar bar2 = Bar.namedFactory();
+const BarGeneric<int> barGeneric = BarGeneric.named();
+const BarGeneric<int> barGeneric2 = BarGeneric.namedFactory();
+main() {}
+typedef Bar = Foo;
+typedef BarGeneric<X> = FooGeneric<X>;
diff --git a/pkg/front_end/testcases/general/issue47339.dart.weak.expect b/pkg/front_end/testcases/general/issue47339.dart.weak.expect
new file mode 100644
index 0000000..eb5e9b2
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47339.dart.weak.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef Bar = self::Foo;
+typedef BarGeneric<X extends core::Object? = dynamic> = self::FooGeneric<X%>;
+class Foo extends core::Object /*hasConstConstructor*/  {
+  static final field dynamic _redirecting# = <dynamic>[self::Foo::namedFactory]/*isLegacy*/;
+  const constructor named() → self::Foo
+    : super core::Object::•()
+    ;
+  static factory namedFactory() → self::Foo
+    return new self::Foo::named();
+}
+class FooGeneric<X extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  static final field dynamic _redirecting# = <dynamic>[self::FooGeneric::namedFactory]/*isLegacy*/;
+  const constructor named() → self::FooGeneric<self::FooGeneric::X%>
+    : super core::Object::•()
+    ;
+  static factory namedFactory<X extends core::Object? = dynamic>() → self::FooGeneric<self::FooGeneric::namedFactory::X%>
+    return new self::FooGeneric::named<self::FooGeneric::namedFactory::X%>();
+}
+static const field self::Foo bar = #C1;
+static const field self::Foo bar2 = #C1;
+static const field self::FooGeneric<core::int> barGeneric = #C2;
+static const field self::FooGeneric<core::int> barGeneric2 = #C2;
+static method main() → dynamic {}
+
+constants  {
+  #C1 = self::Foo {}
+  #C2 = self::FooGeneric<core::int*> {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue47339.dart:
+- Foo.named (from org-dartlang-testcase:///issue47339.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- FooGeneric.named (from org-dartlang-testcase:///issue47339.dart:17:9)
diff --git a/pkg/front_end/testcases/general/issue47339.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue47339.dart.weak.outline.expect
new file mode 100644
index 0000000..0a83431
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47339.dart.weak.outline.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef Bar = self::Foo;
+typedef BarGeneric<X extends core::Object? = dynamic> = self::FooGeneric<X%>;
+class Foo extends core::Object /*hasConstConstructor*/  {
+  static final field dynamic _redirecting# = <dynamic>[self::Foo::namedFactory]/*isLegacy*/;
+  const constructor named() → self::Foo
+    : super core::Object::•()
+    ;
+  static factory namedFactory() → self::Foo
+    return new self::Foo::named();
+}
+class FooGeneric<X extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  static final field dynamic _redirecting# = <dynamic>[self::FooGeneric::namedFactory]/*isLegacy*/;
+  const constructor named() → self::FooGeneric<self::FooGeneric::X%>
+    : super core::Object::•()
+    ;
+  static factory namedFactory<X extends core::Object? = dynamic>() → self::FooGeneric<self::FooGeneric::namedFactory::X%>
+    return new self::FooGeneric::named<self::FooGeneric::namedFactory::X%>();
+}
+static const field self::Foo bar = const self::Foo::named();
+static const field self::Foo bar2 = const self::Foo::named();
+static const field self::FooGeneric<core::int> barGeneric = const self::FooGeneric::named<core::int>();
+static const field self::FooGeneric<core::int> barGeneric2 = const self::FooGeneric::named<core::int>();
+static method main() → dynamic
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue47339.dart:12:11 -> InstanceConstant(const Foo{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue47339.dart:14:22 -> InstanceConstant(const Foo{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue47339.dart:23:23 -> InstanceConstant(const FooGeneric<int*>{})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///issue47339.dart:25:48 -> InstanceConstant(const FooGeneric<int*>{})
+Extra constant evaluation: evaluated: 10, effectively constant: 4
diff --git a/pkg/front_end/testcases/general/issue47339.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue47339.dart.weak.transformed.expect
new file mode 100644
index 0000000..eb5e9b2
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47339.dart.weak.transformed.expect
@@ -0,0 +1,39 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef Bar = self::Foo;
+typedef BarGeneric<X extends core::Object? = dynamic> = self::FooGeneric<X%>;
+class Foo extends core::Object /*hasConstConstructor*/  {
+  static final field dynamic _redirecting# = <dynamic>[self::Foo::namedFactory]/*isLegacy*/;
+  const constructor named() → self::Foo
+    : super core::Object::•()
+    ;
+  static factory namedFactory() → self::Foo
+    return new self::Foo::named();
+}
+class FooGeneric<X extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  static final field dynamic _redirecting# = <dynamic>[self::FooGeneric::namedFactory]/*isLegacy*/;
+  const constructor named() → self::FooGeneric<self::FooGeneric::X%>
+    : super core::Object::•()
+    ;
+  static factory namedFactory<X extends core::Object? = dynamic>() → self::FooGeneric<self::FooGeneric::namedFactory::X%>
+    return new self::FooGeneric::named<self::FooGeneric::namedFactory::X%>();
+}
+static const field self::Foo bar = #C1;
+static const field self::Foo bar2 = #C1;
+static const field self::FooGeneric<core::int> barGeneric = #C2;
+static const field self::FooGeneric<core::int> barGeneric2 = #C2;
+static method main() → dynamic {}
+
+constants  {
+  #C1 = self::Foo {}
+  #C2 = self::FooGeneric<core::int*> {}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///issue47339.dart:
+- Foo.named (from org-dartlang-testcase:///issue47339.dart:6:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
+- FooGeneric.named (from org-dartlang-testcase:///issue47339.dart:17:9)
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index b8e3e6c..5b236c2 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -103,6 +103,18 @@
   } while (size > 0);
 }
 
+DART_FORCE_INLINE
+static uword ReadHeaderRelaxed(ObjectPtr raw_obj) {
+  return reinterpret_cast<std::atomic<uword>*>(UntaggedObject::ToAddr(raw_obj))
+      ->load(std::memory_order_relaxed);
+}
+
+DART_FORCE_INLINE
+static void WriteHeaderRelaxed(ObjectPtr raw_obj, uword header) {
+  reinterpret_cast<std::atomic<uword>*>(UntaggedObject::ToAddr(raw_obj))
+      ->store(header, std::memory_order_relaxed);
+}
+
 template <bool parallel>
 class ScavengerVisitorBase : public ObjectPointerVisitor {
  public:
@@ -154,16 +166,14 @@
     }
 
     // Validate 'this' is a typed data view.
-    const uword view_header =
-        *reinterpret_cast<uword*>(UntaggedObject::ToAddr(view));
+    const uword view_header = ReadHeaderRelaxed(view);
     ASSERT(!IsForwarding(view_header) || view->IsOldObject());
     ASSERT(IsTypedDataViewClassId(view->GetClassIdMayBeSmi()));
 
     // Validate that the backing store is not a forwarding word.
     TypedDataBasePtr td = view->untag()->typed_data();
     ASSERT(td->IsHeapObject());
-    const uword td_header =
-        *reinterpret_cast<uword*>(UntaggedObject::ToAddr(td));
+    const uword td_header = ReadHeaderRelaxed(td);
     ASSERT(!IsForwarding(td_header) || td->IsOldObject());
 
     if (!parallel) {
@@ -356,8 +366,7 @@
     ASSERT(from_->Contains(raw_addr));
     // Read the header word of the object and determine if the object has
     // already been copied.
-    uword header = reinterpret_cast<std::atomic<uword>*>(raw_addr)->load(
-        std::memory_order_relaxed);
+    uword header = ReadHeaderRelaxed(raw_obj);
     ObjectPtr new_obj;
     if (IsForwarding(header)) {
       // Get the new location of the object.
@@ -1306,7 +1315,7 @@
     ASSERT(raw_key->IsNewObject());
     uword raw_addr = UntaggedObject::ToAddr(raw_key);
     ASSERT(from_->Contains(raw_addr));
-    uword header = *reinterpret_cast<uword*>(raw_addr);
+    uword header = ReadHeaderRelaxed(raw_key);
     // Reset the next pointer in the weak property.
     cur_weak->untag()->next_ = WeakProperty::null();
     if (IsForwarding(header)) {
@@ -1351,8 +1360,7 @@
   ASSERT(raw_weak->IsNewObject());
   ASSERT(raw_weak->IsWeakProperty());
 #if defined(DEBUG)
-  uword raw_addr = UntaggedObject::ToAddr(raw_weak);
-  uword header = *reinterpret_cast<uword*>(raw_addr);
+  uword header = ReadHeaderRelaxed(raw_weak);
   ASSERT(!IsForwarding(header));
 #endif  // defined(DEBUG)
   ASSERT(raw_weak->untag()->next_ ==
@@ -1369,8 +1377,7 @@
     // The fate of the weak property is determined by its key.
     ObjectPtr raw_key = raw_weak->untag()->key();
     if (raw_key->IsHeapObject() && raw_key->IsNewObject()) {
-      uword raw_addr = UntaggedObject::ToAddr(raw_key);
-      uword header = *reinterpret_cast<uword*>(raw_addr);
+      uword header = ReadHeaderRelaxed(raw_key);
       if (!IsForwarding(header)) {
         // Key is white.  Enqueue the weak property.
         EnqueueWeakProperty(raw_weak);
@@ -1714,20 +1721,11 @@
   TIMELINE_FUNCTION_GC_DURATION(thread, "ReverseScavenge");
 
   class ReverseFromForwardingVisitor : public ObjectVisitor {
-    uword ReadHeader(ObjectPtr raw_obj) {
-      return reinterpret_cast<std::atomic<uword>*>(
-                 UntaggedObject::ToAddr(raw_obj))
-          ->load(std::memory_order_relaxed);
-    }
-    void WriteHeader(ObjectPtr raw_obj, uword header) {
-      reinterpret_cast<std::atomic<uword>*>(UntaggedObject::ToAddr(raw_obj))
-          ->store(header, std::memory_order_relaxed);
-    }
     void VisitObject(ObjectPtr from_obj) {
-      uword from_header = ReadHeader(from_obj);
+      uword from_header = ReadHeaderRelaxed(from_obj);
       if (IsForwarding(from_header)) {
         ObjectPtr to_obj = ForwardedObj(from_header);
-        uword to_header = ReadHeader(to_obj);
+        uword to_header = ReadHeaderRelaxed(to_obj);
         intptr_t size = to_obj->untag()->HeapSize();
 
         // Reset the ages bits in case this was a promotion.
@@ -1739,7 +1737,7 @@
         from_header =
             UntaggedObject::OldAndNotMarkedBit::update(false, from_header);
 
-        WriteHeader(from_obj, from_header);
+        WriteHeaderRelaxed(from_obj, from_header);
 
         ForwardingCorpse::AsForwarder(UntaggedObject::ToAddr(to_obj), size)
             ->set_target(from_obj);
diff --git a/sdk/lib/ffi/dynamic_library.dart b/sdk/lib/ffi/dynamic_library.dart
index 737f28c..3f740d5 100644
--- a/sdk/lib/ffi/dynamic_library.dart
+++ b/sdk/lib/ffi/dynamic_library.dart
@@ -77,9 +77,9 @@
   /// ```
   ///
   /// ```dart
-  /// DynamicLibrary dylib;
-  /// final add = dylib.lookupFunction<Int32 Function(Int32, Int32),
-  ///                                  int Function(int, int)>('add');
+  /// DynamicLibrary dylib = DynamicLibrary.executable();
+  /// final add = dylib.lookupFunction<Int32 Function(Int32, Int32), int Function(int, int)>(
+  ///         'add');
   /// ```
   external F lookupFunction<T extends Function, F extends Function>(
       String symbolName,
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index bffde99..f8283f9 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -7,6 +7,10 @@
 /// but don't share memory,
 /// communicating only via messages.
 ///
+/// *NOTE*: The `dart:isolate` library is currently only supported by the
+/// [Dart Native](https://dart.dev/overview#platform) platform.
+
+///
 /// To use this library in your code:
 /// ```dart
 /// import 'dart:isolate';
@@ -608,9 +612,7 @@
   /// In the special circumstances when two isolates share the same code and are
   /// running in the same process (e.g. isolates created via [Isolate.spawn]),
   /// it is also possible to send object instances (which would be copied in the
-  /// process). This is currently only supported by the
-  /// [Dart Native](https://dart.dev/platforms#dart-native-vm-jit-and-aot)
-  /// platform.
+  /// process).
   ///
   /// The send happens immediately and doesn't block.  The corresponding receive
   /// port can receive the message as soon as its isolate's event loop is ready
diff --git a/tools/VERSION b/tools/VERSION
index 1328561..d6d0abc 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 215
+PRERELEASE 216
 PRERELEASE_PATCH 0
\ No newline at end of file