Version 2.15.0-23.0.dev

Merge commit 'f5a3bce734ac8b77e94c255899d65997c4677ace' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4f6512f..944c834 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,26 @@
+## 2.15.0
+
+### Language
+
+- Annotations on type parameters of classes can no longer refer to class members
+  without a prefix.  For example, this used to be permitted:
+
+  ```dart
+  class C<@Annotation(foo) T> {
+    static void foo() {}
+  }
+  ```
+
+  Now, the reference must be qualified with the class name, i.e.:
+
+  ```dart
+  class C<@Annotation(C.foo) T> {
+    static void foo() {}
+  }
+  ```
+
+  This brings the implementation behavior in line with the spec.
+
 ## 2.14.0
 
 ### Language
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 9fad340..92573bd 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -2008,17 +2008,6 @@
   void visitTypeName(TypeName node) {}
 
   @override
-  void visitTypeParameter(TypeParameter node) {
-    var previousThisType = _thisType;
-    try {
-      _setupThisType();
-      super.visitTypeParameter(node);
-    } finally {
-      _thisType = previousThisType;
-    }
-  }
-
-  @override
   void visitVariableDeclaration(VariableDeclaration node) {
     _variableDeclarationResolver.resolve(node as VariableDeclarationImpl);
 
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_identifier_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_identifier_test.dart
index c339039..c484dd0 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_identifier_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_identifier_test.dart
@@ -43,61 +43,6 @@
 }
 
 mixin UndefinedIdentifierTestCases on PubPackageResolutionTest {
-  test_annotation_favors_scope_resolution_over_this_resolution_class() async {
-    // If an annotation on a class type parameter cannot be resolved using the
-    // normal scope resolution mechanism, it is resolved via implicit `this`.
-    // Note: this behavior doesn't match the spec so we may change it - see
-    // https://github.com/dart-lang/language/issues/1790
-    await assertNoErrorsInCode('''
-class C<@Annotation.function(foo) @Annotation.type(B) T> {
-  static void foo() {}
-  static void B() {}
-}
-class B {}
-class Annotation {
-  const Annotation.function(void Function() f);
-  const Annotation.type(Type t);
-}
-''');
-  }
-
-  test_annotation_favors_scope_resolution_over_this_resolution_extension() async {
-    // If an annotation on an extension type parameter cannot be resolved using
-    // the normal scope resolution mechanism, it is resolved via implicit
-    // `this`.  Note: this behavior doesn't match the spec so we may change it -
-    // see https://github.com/dart-lang/language/issues/1790
-    await assertNoErrorsInCode('''
-extension E<@Annotation.function(foo) @Annotation.type(B) T> on C {}
-class C {
-  static void foo() {}
-  static void B() {}
-}
-class B {}
-class Annotation {
-  const Annotation.function(void Function() f);
-  const Annotation.type(Type t);
-}
-''');
-  }
-
-  test_annotation_favors_scope_resolution_over_this_resolution_mixin() async {
-    // If an annotation on a mixin type parameter cannot be resolved using the
-    // normal scope resolution mechanism, it is resolved via implicit `this`.
-    // Note: this behavior doesn't match the spec so we may change it - see
-    // https://github.com/dart-lang/language/issues/1790
-    await assertNoErrorsInCode('''
-mixin M<@Annotation.function(foo) @Annotation.type(B) T> {
-  static void foo() {}
-  static void B() {}
-}
-class B {}
-class Annotation {
-  const Annotation.function(void Function() f);
-  const Annotation.type(Type t);
-}
-''');
-  }
-
   test_annotation_references_static_method_in_class() async {
     await assertErrorsInCode('''
 @Annotation(foo)
@@ -114,18 +59,19 @@
   }
 
   test_annotation_references_static_method_in_class_from_type_parameter() async {
-    // It is allowed for an annotation of a class type parameter to refer to
-    // a method in a class (note: this doesn't match the spec but we currently
-    // test it to make sure we match CFE behavior - see
-    // https://github.com/dart-lang/language/issues/1790)
-    await assertNoErrorsInCode('''
+    // It not is allowed for an annotation of a class type parameter to refer to
+    // a method in a class.
+    await assertErrorsInCode('''
 class C<@Annotation(foo) T> {
   static void foo() {}
 }
 class Annotation {
   const Annotation(dynamic d);
 }
-''');
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 20, 3),
+      error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 20, 3),
+    ]);
   }
 
   test_annotation_references_static_method_in_extension() async {
@@ -144,18 +90,19 @@
   }
 
   test_annotation_references_static_method_in_extension_from_type_parameter() async {
-    // It is allowed for an annotation of a mixin type parameter to refer to
-    // a method in a class (note: this doesn't match the spec but we currently
-    // test it to make sure we match CFE behavior - see
-    // https://github.com/dart-lang/language/issues/1790)
-    await assertNoErrorsInCode('''
+    // It is not allowed for an annotation of an extension type parameter to
+    // refer to a method in a class.
+    await assertErrorsInCode('''
 extension E<@Annotation(foo) T> on T {
   static void foo() {}
 }
 class Annotation {
   const Annotation(dynamic d);
 }
-''');
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 24, 3),
+      error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 24, 3),
+    ]);
   }
 
   test_annotation_references_static_method_in_mixin() async {
@@ -174,18 +121,80 @@
   }
 
   test_annotation_references_static_method_in_mixin_from_type_parameter() async {
-    // It is allowed for an annotation of a mixin type parameter to refer to
-    // a method in a class (note: this doesn't match the spec but we currently
-    // test it to make sure we match CFE behavior - see
-    // https://github.com/dart-lang/language/issues/1790)
-    await assertNoErrorsInCode('''
+    // It is not allowed for an annotation of a mixin type parameter to refer to
+    // a method in a class.
+    await assertErrorsInCode('''
 mixin M<@Annotation(foo) T> {
   static void foo() {}
 }
 class Annotation {
   const Annotation(dynamic d);
 }
-''');
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 20, 3),
+      error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 20, 3),
+    ]);
+  }
+
+  test_annotation_uses_scope_resolution_class() async {
+    // If an annotation on a class type parameter cannot be resolved using the
+    // normal scope resolution mechanism, it is not resolved via implicit
+    // `this`.
+    await assertErrorsInCode('''
+class C<@Annotation.function(foo) @Annotation.type(B) T> {
+  static void foo() {}
+  static void B() {}
+}
+class B {}
+class Annotation {
+  const Annotation.function(void Function() f);
+  const Annotation.type(Type t);
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 29, 3),
+      error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 29, 3),
+    ]);
+  }
+
+  test_annotation_uses_scope_resolution_extension() async {
+    // If an annotation on an extension type parameter cannot be resolved using
+    // the normal scope resolution mechanism, it is not resolved via implicit
+    // `this`.
+    await assertErrorsInCode('''
+extension E<@Annotation.function(foo) @Annotation.type(B) T> on C {}
+class C {
+  static void foo() {}
+  static void B() {}
+}
+class B {}
+class Annotation {
+  const Annotation.function(void Function() f);
+  const Annotation.type(Type t);
+}
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 33, 3),
+      error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 33, 3),
+    ]);
+  }
+
+  test_annotation_uses_scope_resolution_mixin() async {
+    // If an annotation on a mixin type parameter cannot be resolved using the
+    // normal scope resolution mechanism, it is not resolved via implicit
+    // `this`.
+    await assertErrorsInCode('''
+mixin M<@Annotation.function(foo) @Annotation.type(B) T> {
+  static void foo() {}
+  static void B() {}
+}
+class B {}
+class Annotation {
+  const Annotation.function(void Function() f);
+  const Annotation.type(Type t);
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 29, 3),
+      error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 29, 3),
+    ]);
   }
 
   @failingTest
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index 5d66e3c..eaf482e 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -354,12 +354,12 @@
           delayedActionPerformers, synthesizedFunctionNodes);
     }
 
-    MetadataBuilder.buildAnnotations(
-        isPatch ? origin.cls : cls, metadata, library, this, null, fileUri);
+    MetadataBuilder.buildAnnotations(isPatch ? origin.cls : cls, metadata,
+        library, this, null, fileUri, library.scope);
     if (typeVariables != null) {
       for (int i = 0; i < typeVariables!.length; i++) {
-        typeVariables![i].buildOutlineExpressions(
-            library, this, null, coreTypes, delayedActionPerformers);
+        typeVariables![i].buildOutlineExpressions(library, this, null,
+            coreTypes, delayedActionPerformers, scope.parent!);
       }
     }
 
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index eceff88..e898f39 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -400,8 +400,8 @@
     _fieldEncoding.completeSignature(coreTypes);
 
     for (Annotatable annotatable in _fieldEncoding.annotatables) {
-      MetadataBuilder.buildAnnotations(
-          annotatable, metadata, library, classBuilder, this, fileUri);
+      MetadataBuilder.buildAnnotations(annotatable, metadata, library,
+          classBuilder, this, fileUri, classBuilder?.scope ?? library.scope);
     }
 
     // For modular compilation we need to include initializers of all const
diff --git a/pkg/front_end/lib/src/fasta/builder/function_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
index 71dc58a..1d02cb5 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
@@ -486,8 +486,9 @@
           isClassMember || isExtensionMember
               ? parent as DeclarationBuilder
               : null;
-      MetadataBuilder.buildAnnotations(
-          member, metadata, library, classOrExtensionBuilder, this, fileUri);
+      Scope parentScope = classOrExtensionBuilder?.scope ?? library.scope;
+      MetadataBuilder.buildAnnotations(member, metadata, library,
+          classOrExtensionBuilder, this, fileUri, parentScope);
       if (typeVariables != null) {
         for (int i = 0; i < typeVariables!.length; i++) {
           typeVariables![i].buildOutlineExpressions(
@@ -495,7 +496,8 @@
               classOrExtensionBuilder,
               this,
               coreTypes,
-              delayedActionPerformers);
+              delayedActionPerformers,
+              computeTypeParameterScope(parentScope));
         }
       }
 
diff --git a/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart b/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart
index 21d767b..c4497b1 100644
--- a/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart
@@ -30,14 +30,8 @@
       SourceLibraryBuilder library,
       DeclarationBuilder? classOrExtensionBuilder,
       MemberBuilder? member,
-      Uri fileUri) {
+      Uri fileUri, Scope scope) {
     if (metadata == null) return;
-    Scope scope = parent is Library ||
-            parent is Class ||
-            parent is Extension ||
-            classOrExtensionBuilder == null
-        ? library.scope
-        : classOrExtensionBuilder.scope;
     BodyBuilder bodyBuilder = library.loader
         .createBodyBuilderForOutlineExpression(library, classOrExtensionBuilder,
             member ?? classOrExtensionBuilder ?? library, scope, fileUri);
diff --git a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
index 9d91421..b6a6ed9 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
@@ -13,6 +13,7 @@
         templateInternalProblemUnfinishedTypeVariable,
         templateTypeArgumentsOnTypeVariable;
 
+import '../scope.dart';
 import '../source/source_library_builder.dart';
 import '../util/helpers.dart';
 
@@ -200,9 +201,9 @@
       DeclarationBuilder? classOrExtensionBuilder,
       MemberBuilder? memberBuilder,
       CoreTypes coreTypes,
-      List<DelayedActionPerformer> delayedActionPerformers) {
+      List<DelayedActionPerformer> delayedActionPerformers, Scope scope) {
     MetadataBuilder.buildAnnotations(parameter, metadata, libraryBuilder,
-        classOrExtensionBuilder, memberBuilder, fileUri!);
+        classOrExtensionBuilder, memberBuilder, fileUri!, scope);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
index 5ffcb20..8bb7538 100644
--- a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
@@ -278,11 +278,11 @@
       List<DelayedActionPerformer> delayedActionPerformers,
       List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
     MetadataBuilder.buildAnnotations(isPatch ? origin.extension : extension,
-        metadata, library, this, null, fileUri);
+        metadata, library, this, null, fileUri, library.scope);
     if (typeParameters != null) {
       for (int i = 0; i < typeParameters!.length; i++) {
-        typeParameters![i].buildOutlineExpressions(
-            library, this, null, coreTypes, delayedActionPerformers);
+        typeParameters![i].buildOutlineExpressions(library, this, null,
+            coreTypes, delayedActionPerformers, scope.parent!);
       }
     }
 
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 4ed49c9..5c4ebef3 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -2648,7 +2648,7 @@
   @override
   void buildOutlineExpressions() {
     MetadataBuilder.buildAnnotations(
-        library, metadata, this, null, null, fileUri);
+        library, metadata, this, null, null, fileUri, scope);
   }
 
   /// Builds the core AST structures for [declaration] needed for the outline.
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 5bdcbaa..a64606e 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
@@ -18,7 +18,9 @@
     show noLength, templateCyclicTypedef, templateTypeArgumentMismatch;
 
 import '../problems.dart' show unhandled;
+import '../scope.dart';
 
+import '../builder/builder.dart';
 import '../builder/class_builder.dart';
 import '../builder/fixed_type_builder.dart';
 import '../builder/formal_parameter_builder.dart';
@@ -256,11 +258,16 @@
       List<DelayedActionPerformer> delayedActionPerformers,
       List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
     MetadataBuilder.buildAnnotations(
-        typedef, metadata, library, null, null, fileUri);
+        typedef, metadata, library, null, null, fileUri, library.scope);
     if (typeVariables != null) {
       for (int i = 0; i < typeVariables!.length; i++) {
         typeVariables![i].buildOutlineExpressions(
-            library, null, null, coreTypes, delayedActionPerformers);
+            library,
+            null,
+            null,
+            coreTypes,
+            delayedActionPerformers,
+            computeTypeParameterScope(library.scope));
       }
     }
     _tearOffDependencies?.forEach((Procedure tearOff, Member target) {
@@ -273,6 +280,19 @@
     });
   }
 
+  Scope computeTypeParameterScope(Scope parent) {
+    if (typeVariables == null) return parent;
+    Map<String, Builder> local = <String, Builder>{};
+    for (TypeVariableBuilder variable in typeVariables!) {
+      local[variable.name] = variable;
+    }
+    return new Scope(
+        local: local,
+        parent: parent,
+        debugName: "type parameter",
+        isModifiable: false);
+  }
+
   Map<Procedure, Member>? _tearOffDependencies;
 
   void buildTypedefTearOffs(
diff --git a/tests/language/metadata/type_parameter_scope_inner_test.dart b/tests/language/metadata/type_parameter_scope_inner_test.dart
new file mode 100644
index 0000000..ecbb4a2
--- /dev/null
+++ b/tests/language/metadata/type_parameter_scope_inner_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that metadata on a type parameter cannot refer to declarations in an
+// inner scope.  See https://github.com/dart-lang/language/issues/1790.
+
+class Annotation {
+  const Annotation(dynamic d);
+}
+
+class Class<@Annotation(foo) T> {
+//                      ^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+// [cfe] Getter not found: 'foo'.
+  static void foo() {}
+}
+
+void function<@Annotation(foo) T>(dynamic foo) {
+//                        ^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+// [cfe] Getter not found: 'foo'.
+  dynamic foo;
+}
+
+extension Extension<@Annotation(foo) T> on Class<T> {
+//                              ^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+// [cfe] Getter not found: 'foo'.
+  static void foo() {}
+
+  void extensionMethod<@Annotation(foo) T, @Annotation(bar) U>() {}
+  //                                                   ^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+  // [cfe] Getter not found: 'bar'.
+}
+
+class C {
+  void method<@Annotation(foo) T, @Annotation(bar) U>(dynamic foo) {
+  //                      ^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+  // [cfe] Getter not found: 'foo'.
+    dynamic foo;
+  }
+
+  static void bar() {}
+}
+
+mixin Mixin<@Annotation(foo) T> {
+//                      ^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+// [cfe] Getter not found: 'foo'.
+  static void foo() {}
+}
+
+typedef Typedef<@Annotation(foo) T> = void Function<foo>();
+//                          ^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+// [cfe] Getter not found: 'foo'.
diff --git a/tests/language/metadata/type_parameter_scope_other_test.dart b/tests/language/metadata/type_parameter_scope_other_test.dart
new file mode 100644
index 0000000..d411e2f
--- /dev/null
+++ b/tests/language/metadata/type_parameter_scope_other_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that identifiers in type parameter metadata can refer to other type
+// parameters in the same declaration; they are in scope and take precedence
+// over top level declarations, even if this leads to compile errors.
+
+/// Top level declaration of T; nothing should resolve to this.
+void T() {}
+
+class Annotation {
+  const Annotation(dynamic d);
+}
+
+class Class<T, @Annotation(T) U> {}
+//                         ^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [cfe] Type variables can't be used in static members.
+
+void function<T, @Annotation(T) U>() {}
+//                           ^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [cfe] Type variables can't be used as constants.
+
+extension Extension<T, @Annotation(T) U> on Map<T, U> {}
+//                                 ^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [cfe] Type variables can't be used in static members.
+
+class C {
+  void method<T, @Annotation(T) U>() {}
+  //                         ^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+  // [cfe] Type variables can't be used as constants.
+}
+
+mixin Mixin<T, @Annotation(T) U> {}
+//                         ^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [cfe] Type variables can't be used in static members.
+
+typedef void Typedef1<T, @Annotation(T) U>(T t, U u);
+//                                   ^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [cfe] Type variables can't be used as constants.
+
+typedef Typedef2<T, @Annotation(T) U> = void Function(T t, U u);
+//                              ^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [cfe] Type variables can't be used as constants.
diff --git a/tests/language_2/metadata/type_parameter_scope_inner_test.dart b/tests/language_2/metadata/type_parameter_scope_inner_test.dart
new file mode 100644
index 0000000..ecbb4a2
--- /dev/null
+++ b/tests/language_2/metadata/type_parameter_scope_inner_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that metadata on a type parameter cannot refer to declarations in an
+// inner scope.  See https://github.com/dart-lang/language/issues/1790.
+
+class Annotation {
+  const Annotation(dynamic d);
+}
+
+class Class<@Annotation(foo) T> {
+//                      ^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+// [cfe] Getter not found: 'foo'.
+  static void foo() {}
+}
+
+void function<@Annotation(foo) T>(dynamic foo) {
+//                        ^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+// [cfe] Getter not found: 'foo'.
+  dynamic foo;
+}
+
+extension Extension<@Annotation(foo) T> on Class<T> {
+//                              ^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+// [cfe] Getter not found: 'foo'.
+  static void foo() {}
+
+  void extensionMethod<@Annotation(foo) T, @Annotation(bar) U>() {}
+  //                                                   ^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+  // [cfe] Getter not found: 'bar'.
+}
+
+class C {
+  void method<@Annotation(foo) T, @Annotation(bar) U>(dynamic foo) {
+  //                      ^^^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+  // [cfe] Getter not found: 'foo'.
+    dynamic foo;
+  }
+
+  static void bar() {}
+}
+
+mixin Mixin<@Annotation(foo) T> {
+//                      ^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+// [cfe] Getter not found: 'foo'.
+  static void foo() {}
+}
+
+typedef Typedef<@Annotation(foo) T> = void Function<foo>();
+//                          ^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_IDENTIFIER
+// [cfe] Getter not found: 'foo'.
diff --git a/tests/language_2/metadata/type_parameter_scope_other_test.dart b/tests/language_2/metadata/type_parameter_scope_other_test.dart
new file mode 100644
index 0000000..d411e2f
--- /dev/null
+++ b/tests/language_2/metadata/type_parameter_scope_other_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that identifiers in type parameter metadata can refer to other type
+// parameters in the same declaration; they are in scope and take precedence
+// over top level declarations, even if this leads to compile errors.
+
+/// Top level declaration of T; nothing should resolve to this.
+void T() {}
+
+class Annotation {
+  const Annotation(dynamic d);
+}
+
+class Class<T, @Annotation(T) U> {}
+//                         ^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [cfe] Type variables can't be used in static members.
+
+void function<T, @Annotation(T) U>() {}
+//                           ^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [cfe] Type variables can't be used as constants.
+
+extension Extension<T, @Annotation(T) U> on Map<T, U> {}
+//                                 ^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [cfe] Type variables can't be used in static members.
+
+class C {
+  void method<T, @Annotation(T) U>() {}
+  //                         ^
+  // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+  // [cfe] Type variables can't be used as constants.
+}
+
+mixin Mixin<T, @Annotation(T) U> {}
+//                         ^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [cfe] Type variables can't be used in static members.
+
+typedef void Typedef1<T, @Annotation(T) U>(T t, U u);
+//                                   ^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [cfe] Type variables can't be used as constants.
+
+typedef Typedef2<T, @Annotation(T) U> = void Function(T t, U u);
+//                              ^
+// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+// [cfe] Type variables can't be used as constants.
diff --git a/tests/lib/mirrors/metadata_scope_test.dart b/tests/lib/mirrors/metadata_scope_test.dart
index 8848d41..0596b39 100644
--- a/tests/lib/mirrors/metadata_scope_test.dart
+++ b/tests/lib/mirrors/metadata_scope_test.dart
@@ -15,8 +15,10 @@
 
 // Note there is no compile-time constant 'foo' in scope. In particular, A.foo
 // is not in scope here.
-@Annotation(foo) // //# 01: compile-time error
-class A<@Annotation(foo) T> {
+@Annotation(foo) //# 01: compile-time error
+class A<
+    @Annotation(foo) //# 02: compile-time error
+        T> {
   @Annotation(foo)
   static foo() {}
 
diff --git a/tests/lib_2/mirrors/metadata_scope_test.dart b/tests/lib_2/mirrors/metadata_scope_test.dart
index 0ecaeb1..fec9be7 100644
--- a/tests/lib_2/mirrors/metadata_scope_test.dart
+++ b/tests/lib_2/mirrors/metadata_scope_test.dart
@@ -17,8 +17,10 @@
 
 // Note there is no compile-time constant 'foo' in scope. In particular, A.foo
 // is not in scope here.
-@Annotation(foo) // //# 01: compile-time error
-class A<@Annotation(foo) T> {
+@Annotation(foo) //# 01: compile-time error
+class A<
+    @Annotation(foo) //# 02: compile-time error
+        T> {
   @Annotation(foo)
   static foo() {}
 
diff --git a/tools/VERSION b/tools/VERSION
index b02aaac..f5bacd2 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 22
+PRERELEASE 23
 PRERELEASE_PATCH 0
\ No newline at end of file