[cfe] Add error on static function tearoffs for instantiated classes

Closes #46889.

Bug: https://github.com/dart-lang/sdk/issues/46889
Change-Id: Ifb9242e3093c7e1ffb9d4e5e755bfb4576fbafb8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/210020
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index 01dd119..0e88d0e 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -8960,6 +8960,18 @@
     tip: r"""Try removing the keyword 'static'.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeStaticTearOffFromInstantiatedClass =
+    messageStaticTearOffFromInstantiatedClass;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageStaticTearOffFromInstantiatedClass = const MessageCode(
+    "StaticTearOffFromInstantiatedClass",
+    message:
+        r"""Cannot access static member on an instantiated generic class.""",
+    tip:
+        r"""Try removing the type arguments or placing them after the member name.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeStrongModeNNBDButOptOut = messageStrongModeNNBDButOptOut;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index 987f401..0ae336d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -2898,12 +2898,8 @@
               _uri, charOffset, lengthOfSpan(prefixGenerator.token, token));
     }
     // TODO(johnniwinther): Could we use a FixedTypeBuilder(InvalidType()) here?
-    NamedTypeBuilder result = new NamedTypeBuilder(
-        name,
-        nullabilityBuilder,
-        /* arguments = */ null,
-        /* fileUri = */ null,
-        /* charOffset = */ null);
+    NamedTypeBuilder result = new NamedTypeBuilder(name, nullabilityBuilder,
+        /* arguments = */ null, /* fileUri = */ null, /* charOffset = */ null);
     _helper.libraryBuilder.addProblem(
         message.messageObject, message.charOffset, message.length, message.uri);
     result.bind(result.buildInvalidTypeDeclarationBuilder(message));
@@ -3272,6 +3268,11 @@
       } else if (member is AmbiguousBuilder) {
         return _helper.buildProblem(
             member.message, member.charOffset, name.text.length);
+      } else if (member.isStatic &&
+          !member.isFactory &&
+          typeArguments != null) {
+        return _helper.buildProblem(messageStaticTearOffFromInstantiatedClass,
+            send.fileOffset, send.name.text.length);
       } else {
         Builder? setter;
         if (member.isSetter) {
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index a9154ac..daf3f6c 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -753,6 +753,7 @@
 SpreadMapEntryTypeMismatch/analyzerCode: Fail # There's no analyzer code for that error yet.
 SpreadTypeMismatch/analyzerCode: Fail # There's no analyzer code for that error yet.
 StackOverflow/example: Fail
+StaticTearOffFromInstantiatedClass/analyzerCode: Fail
 StrongModeNNBDButOptOut/analyzerCode: Fail
 StrongModeNNBDButOptOut/example: Fail
 StrongModeNNBDPackageOptOut/analyzerCode: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index e94eac1..8795748 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -5254,3 +5254,11 @@
   script: |
     abstract class Class {}
     main() => Class.new;
+
+StaticTearOffFromInstantiatedClass:
+  template: "Cannot access static member on an instantiated generic class."
+  tip: "Try removing the type arguments or placing them after the member name."
+  experiments: constructor-tearoffs
+  script: |
+    class A<X> { static f() {} }
+    main() => A<int>.f;
diff --git a/pkg/front_end/test/spell_checking_list_messages.txt b/pkg/front_end/test/spell_checking_list_messages.txt
index 808f9f1..5d363a0 100644
--- a/pkg/front_end/test/spell_checking_list_messages.txt
+++ b/pkg/front_end/test/spell_checking_list_messages.txt
@@ -59,6 +59,7 @@
 outdated
 part(s)
 patch(es)
+placing
 pubspec.yaml
 re
 sdksummary
diff --git a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart
new file mode 100644
index 0000000..80c48ab
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart
@@ -0,0 +1,32 @@
+// 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 A<X> {
+  static X foo<X>(X x) => x;
+}
+
+typedef D1<X> = A<X>;
+typedef D2<X extends num> = A<X>;
+
+test() {
+  Y Function<Y>(Y) f1 = A.foo; // Ok.
+  int Function(int) f2 = A.foo; // Ok.
+  int Function(int) f3 = A.foo<int>; // Ok.
+  int Function(int) f4 = A<int>.foo; // Error.
+  var f5 = A<int>.foo; // Error.
+
+  Y Function<Y>(Y) g1 = D1.foo; // Ok.
+  int Function(int) g2 = D1.foo; // Ok.
+  int Function(int) g3 = D1.foo<int>; // Ok.
+  int Function(int) g4 = D1<int>.foo; // Error.
+  var g5 = D1<int>.foo; // Error.
+
+  Y Function<Y>(Y) h1 = D2.foo; // Ok.
+  int Function(int) h2 = D2.foo; // Ok.
+  int Function(int) h3 = D2.foo<int>; // Ok.
+  int Function(int) h4 = D2<int>.foo; // Error.
+  var h5 = D2<int>.foo; // Error.
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.strong.expect
new file mode 100644
index 0000000..f018785e
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.strong.expect
@@ -0,0 +1,89 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:16:33: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   int Function(int) f4 = A<int>.foo; // Error.
+//                                 ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:17:19: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   var f5 = A<int>.foo; // Error.
+//                   ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:22:34: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   int Function(int) g4 = D1<int>.foo; // Error.
+//                                  ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:23:20: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   var g5 = D1<int>.foo; // Error.
+//                    ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:28:34: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   int Function(int) h4 = D2<int>.foo; // Error.
+//                                  ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:29:20: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   var h5 = D2<int>.foo; // Error.
+//                    ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef D1<X extends core::Object? = dynamic> = self::A<X%>;
+typedef D2<X extends core::num> = self::A<X>;
+class A<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%>
+    : super core::Object::•()
+    ;
+  static method foo<X extends core::Object? = dynamic>(self::A::foo::X% x) → self::A::foo::X%
+    return x;
+}
+static method test() → dynamic {
+  <Y extends core::Object? = dynamic>(Y%) → Y% f1 = #C1;
+  (core::int) → core::int f2 = #C2;
+  (core::int) → core::int f3 = #C2;
+  (core::int) → core::int f4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:16:33: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  int Function(int) f4 = A<int>.foo; // Error.
+                                ^^^";
+  invalid-type f5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:17:19: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  var f5 = A<int>.foo; // Error.
+                  ^^^";
+  <Y extends core::Object? = dynamic>(Y%) → Y% g1 = #C1;
+  (core::int) → core::int g2 = #C2;
+  (core::int) → core::int g3 = #C2;
+  (core::int) → core::int g4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:22:34: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  int Function(int) g4 = D1<int>.foo; // Error.
+                                 ^^^";
+  invalid-type g5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:23:20: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  var g5 = D1<int>.foo; // Error.
+                   ^^^";
+  <Y extends core::Object? = dynamic>(Y%) → Y% h1 = #C1;
+  (core::int) → core::int h2 = #C2;
+  (core::int) → core::int h3 = #C2;
+  (core::int) → core::int h4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:28:34: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  int Function(int) h4 = D2<int>.foo; // Error.
+                                 ^^^";
+  invalid-type h5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:29:20: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  var h5 = D2<int>.foo; // Error.
+                   ^^^";
+}
+static method main() → dynamic {}
+static method _#D2#new#tearOff<X extends core::num>() → self::A<self::_#D2#new#tearOff::X>
+  return new self::A::•<self::_#D2#new#tearOff::X>();
+
+constants  {
+  #C1 = static-tearoff self::A::foo
+  #C2 = instantiation self::A::foo <core::int>
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.strong.transformed.expect
new file mode 100644
index 0000000..f018785e
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.strong.transformed.expect
@@ -0,0 +1,89 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:16:33: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   int Function(int) f4 = A<int>.foo; // Error.
+//                                 ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:17:19: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   var f5 = A<int>.foo; // Error.
+//                   ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:22:34: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   int Function(int) g4 = D1<int>.foo; // Error.
+//                                  ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:23:20: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   var g5 = D1<int>.foo; // Error.
+//                    ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:28:34: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   int Function(int) h4 = D2<int>.foo; // Error.
+//                                  ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:29:20: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   var h5 = D2<int>.foo; // Error.
+//                    ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef D1<X extends core::Object? = dynamic> = self::A<X%>;
+typedef D2<X extends core::num> = self::A<X>;
+class A<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%>
+    : super core::Object::•()
+    ;
+  static method foo<X extends core::Object? = dynamic>(self::A::foo::X% x) → self::A::foo::X%
+    return x;
+}
+static method test() → dynamic {
+  <Y extends core::Object? = dynamic>(Y%) → Y% f1 = #C1;
+  (core::int) → core::int f2 = #C2;
+  (core::int) → core::int f3 = #C2;
+  (core::int) → core::int f4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:16:33: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  int Function(int) f4 = A<int>.foo; // Error.
+                                ^^^";
+  invalid-type f5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:17:19: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  var f5 = A<int>.foo; // Error.
+                  ^^^";
+  <Y extends core::Object? = dynamic>(Y%) → Y% g1 = #C1;
+  (core::int) → core::int g2 = #C2;
+  (core::int) → core::int g3 = #C2;
+  (core::int) → core::int g4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:22:34: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  int Function(int) g4 = D1<int>.foo; // Error.
+                                 ^^^";
+  invalid-type g5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:23:20: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  var g5 = D1<int>.foo; // Error.
+                   ^^^";
+  <Y extends core::Object? = dynamic>(Y%) → Y% h1 = #C1;
+  (core::int) → core::int h2 = #C2;
+  (core::int) → core::int h3 = #C2;
+  (core::int) → core::int h4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:28:34: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  int Function(int) h4 = D2<int>.foo; // Error.
+                                 ^^^";
+  invalid-type h5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:29:20: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  var h5 = D2<int>.foo; // Error.
+                   ^^^";
+}
+static method main() → dynamic {}
+static method _#D2#new#tearOff<X extends core::num>() → self::A<self::_#D2#new#tearOff::X>
+  return new self::A::•<self::_#D2#new#tearOff::X>();
+
+constants  {
+  #C1 = static-tearoff self::A::foo
+  #C2 = instantiation self::A::foo <core::int>
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.textual_outline.expect b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.textual_outline.expect
new file mode 100644
index 0000000..a3fb204
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.textual_outline.expect
@@ -0,0 +1,8 @@
+class A<X> {
+  static X foo<X>(X x) => x;
+}
+
+typedef D1<X> = A<X>;
+typedef D2<X extends num> = A<X>;
+test() {}
+main() {}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..37de545
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.textual_outline_modelled.expect
@@ -0,0 +1,8 @@
+class A<X> {
+  static X foo<X>(X x) => x;
+}
+
+main() {}
+test() {}
+typedef D1<X> = A<X>;
+typedef D2<X extends num> = A<X>;
diff --git a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.expect
new file mode 100644
index 0000000..67dd644
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.expect
@@ -0,0 +1,89 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:16:33: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   int Function(int) f4 = A<int>.foo; // Error.
+//                                 ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:17:19: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   var f5 = A<int>.foo; // Error.
+//                   ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:22:34: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   int Function(int) g4 = D1<int>.foo; // Error.
+//                                  ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:23:20: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   var g5 = D1<int>.foo; // Error.
+//                    ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:28:34: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   int Function(int) h4 = D2<int>.foo; // Error.
+//                                  ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:29:20: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   var h5 = D2<int>.foo; // Error.
+//                    ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef D1<X extends core::Object? = dynamic> = self::A<X%>;
+typedef D2<X extends core::num> = self::A<X>;
+class A<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%>
+    : super core::Object::•()
+    ;
+  static method foo<X extends core::Object? = dynamic>(self::A::foo::X% x) → self::A::foo::X%
+    return x;
+}
+static method test() → dynamic {
+  <Y extends core::Object? = dynamic>(Y%) → Y% f1 = #C1;
+  (core::int) → core::int f2 = #C2;
+  (core::int) → core::int f3 = #C2;
+  (core::int) → core::int f4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:16:33: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  int Function(int) f4 = A<int>.foo; // Error.
+                                ^^^";
+  invalid-type f5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:17:19: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  var f5 = A<int>.foo; // Error.
+                  ^^^";
+  <Y extends core::Object? = dynamic>(Y%) → Y% g1 = #C1;
+  (core::int) → core::int g2 = #C2;
+  (core::int) → core::int g3 = #C2;
+  (core::int) → core::int g4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:22:34: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  int Function(int) g4 = D1<int>.foo; // Error.
+                                 ^^^";
+  invalid-type g5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:23:20: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  var g5 = D1<int>.foo; // Error.
+                   ^^^";
+  <Y extends core::Object? = dynamic>(Y%) → Y% h1 = #C1;
+  (core::int) → core::int h2 = #C2;
+  (core::int) → core::int h3 = #C2;
+  (core::int) → core::int h4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:28:34: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  int Function(int) h4 = D2<int>.foo; // Error.
+                                 ^^^";
+  invalid-type h5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:29:20: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  var h5 = D2<int>.foo; // Error.
+                   ^^^";
+}
+static method main() → dynamic {}
+static method _#D2#new#tearOff<X extends core::num>() → self::A<self::_#D2#new#tearOff::X>
+  return new self::A::•<self::_#D2#new#tearOff::X>();
+
+constants  {
+  #C1 = static-tearoff self::A::foo
+  #C2 = instantiation self::A::foo <core::int*>
+}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.outline.expect b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.outline.expect
new file mode 100644
index 0000000..07e6b54
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.outline.expect
@@ -0,0 +1,18 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef D1<X extends core::Object? = dynamic> = self::A<X%>;
+typedef D2<X extends core::num> = self::A<X>;
+class A<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%>
+    ;
+  static method foo<X extends core::Object? = dynamic>(self::A::foo::X% x) → self::A::foo::X%
+    ;
+}
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
+static method _#D2#new#tearOff<X extends core::num>() → self::A<self::_#D2#new#tearOff::X>
+  return new self::A::•<self::_#D2#new#tearOff::X>();
diff --git a/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.transformed.expect
new file mode 100644
index 0000000..67dd644
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart.weak.transformed.expect
@@ -0,0 +1,89 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:16:33: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   int Function(int) f4 = A<int>.foo; // Error.
+//                                 ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:17:19: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   var f5 = A<int>.foo; // Error.
+//                   ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:22:34: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   int Function(int) g4 = D1<int>.foo; // Error.
+//                                  ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:23:20: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   var g5 = D1<int>.foo; // Error.
+//                    ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:28:34: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   int Function(int) h4 = D2<int>.foo; // Error.
+//                                  ^^^
+//
+// pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:29:20: Error: Cannot access static member on an instantiated generic class.
+// Try removing the type arguments or placing them after the member name.
+//   var h5 = D2<int>.foo; // Error.
+//                    ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef D1<X extends core::Object? = dynamic> = self::A<X%>;
+typedef D2<X extends core::num> = self::A<X>;
+class A<X extends core::Object? = dynamic> extends core::Object {
+  synthetic constructor •() → self::A<self::A::X%>
+    : super core::Object::•()
+    ;
+  static method foo<X extends core::Object? = dynamic>(self::A::foo::X% x) → self::A::foo::X%
+    return x;
+}
+static method test() → dynamic {
+  <Y extends core::Object? = dynamic>(Y%) → Y% f1 = #C1;
+  (core::int) → core::int f2 = #C2;
+  (core::int) → core::int f3 = #C2;
+  (core::int) → core::int f4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:16:33: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  int Function(int) f4 = A<int>.foo; // Error.
+                                ^^^";
+  invalid-type f5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:17:19: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  var f5 = A<int>.foo; // Error.
+                  ^^^";
+  <Y extends core::Object? = dynamic>(Y%) → Y% g1 = #C1;
+  (core::int) → core::int g2 = #C2;
+  (core::int) → core::int g3 = #C2;
+  (core::int) → core::int g4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:22:34: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  int Function(int) g4 = D1<int>.foo; // Error.
+                                 ^^^";
+  invalid-type g5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:23:20: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  var g5 = D1<int>.foo; // Error.
+                   ^^^";
+  <Y extends core::Object? = dynamic>(Y%) → Y% h1 = #C1;
+  (core::int) → core::int h2 = #C2;
+  (core::int) → core::int h3 = #C2;
+  (core::int) → core::int h4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:28:34: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  int Function(int) h4 = D2<int>.foo; // Error.
+                                 ^^^";
+  invalid-type h5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/static_tearoff_from_instantiated_class.dart:29:20: Error: Cannot access static member on an instantiated generic class.
+Try removing the type arguments or placing them after the member name.
+  var h5 = D2<int>.foo; // Error.
+                   ^^^";
+}
+static method main() → dynamic {}
+static method _#D2#new#tearOff<X extends core::num>() → self::A<self::_#D2#new#tearOff::X>
+  return new self::A::•<self::_#D2#new#tearOff::X>();
+
+constants  {
+  #C1 = static-tearoff self::A::foo
+  #C2 = instantiation self::A::foo <core::int*>
+}
diff --git a/pkg/front_end/tool/_fasta/generate_messages.dart b/pkg/front_end/tool/_fasta/generate_messages.dart
index 3a971c3..5420bf7 100644
--- a/pkg/front_end/tool/_fasta/generate_messages.dart
+++ b/pkg/front_end/tool/_fasta/generate_messages.dart
@@ -414,7 +414,7 @@
     if (analyzerCode is String) {
       analyzerCode = <String>[analyzerCode];
     }
-    List<Object> codes = analyzerCode as List<Object>;
+    List<Object?> codes = analyzerCode as List<Object?>;
     // If "index:" is defined, then "analyzerCode:" should not be generated
     // in the front end. See comment in messages.yaml
     codeArguments.add('analyzerCodes: <String>["${codes.join('", "')}"]');