[cfe] Correct argument count in extension member errors

Closes #45204.

Bug: https://github.com/dart-lang/sdk/issues/45204
Change-Id: I5295704a8d470e639fe346dbbbf80ad28ff614a6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/190520
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
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 4c6b895..93add07 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -4253,7 +4253,8 @@
       {bool isTearOff}) {
     List<TypeParameter> typeParameters = target.function.typeParameters;
     LocatedMessage argMessage = checkArgumentsForFunction(
-        target.function, arguments, fileOffset, typeParameters);
+        target.function, arguments, fileOffset, typeParameters,
+        isExtensionMemberInvocation: true);
     if (argMessage != null) {
       return throwNoSuchMethodError(forest.createNullLiteral(fileOffset),
           target.name.text, arguments, fileOffset,
@@ -4272,19 +4273,32 @@
 
   @override
   LocatedMessage checkArgumentsForFunction(FunctionNode function,
-      Arguments arguments, int offset, List<TypeParameter> typeParameters) {
+      Arguments arguments, int offset, List<TypeParameter> typeParameters,
+      {bool isExtensionMemberInvocation = false}) {
+    int requiredPositionalParameterCountToReport =
+        function.requiredParameterCount;
+    int positionalParameterCountToReport = function.positionalParameters.length;
+    int positionalArgumentCountToReport =
+        forest.argumentsPositional(arguments).length;
+    if (isExtensionMemberInvocation) {
+      // Extension member invocations have additional synthetic parameter for
+      // `this`.
+      --requiredPositionalParameterCountToReport;
+      --positionalParameterCountToReport;
+      --positionalArgumentCountToReport;
+    }
     if (forest.argumentsPositional(arguments).length <
         function.requiredParameterCount) {
       return fasta.templateTooFewArguments
-          .withArguments(function.requiredParameterCount,
-              forest.argumentsPositional(arguments).length)
+          .withArguments(requiredPositionalParameterCountToReport,
+              positionalArgumentCountToReport)
           .withLocation(uri, arguments.fileOffset, noLength);
     }
     if (forest.argumentsPositional(arguments).length >
         function.positionalParameters.length) {
       return fasta.templateTooManyArguments
-          .withArguments(function.positionalParameters.length,
-              forest.argumentsPositional(arguments).length)
+          .withArguments(
+              positionalParameterCountToReport, positionalArgumentCountToReport)
           .withLocation(uri, arguments.fileOffset, noLength);
     }
     List<NamedExpression> named = forest.argumentsNamed(arguments);
@@ -4331,19 +4345,32 @@
 
   @override
   LocatedMessage checkArgumentsForType(
-      FunctionType function, Arguments arguments, int offset) {
+      FunctionType function, Arguments arguments, int offset,
+      {bool isExtensionMemberInvocation = false}) {
+    int requiredPositionalParameterCountToReport =
+        function.requiredParameterCount;
+    int positionalParameterCountToReport = function.positionalParameters.length;
+    int positionalArgumentCountToReport =
+        forest.argumentsPositional(arguments).length;
+    if (isExtensionMemberInvocation) {
+      // Extension member invocations have additional synthetic parameter for
+      // `this`.
+      --requiredPositionalParameterCountToReport;
+      --positionalParameterCountToReport;
+      --positionalArgumentCountToReport;
+    }
     if (forest.argumentsPositional(arguments).length <
         function.requiredParameterCount) {
       return fasta.templateTooFewArguments
-          .withArguments(function.requiredParameterCount,
-              forest.argumentsPositional(arguments).length)
+          .withArguments(requiredPositionalParameterCountToReport,
+              positionalArgumentCountToReport)
           .withLocation(uri, arguments.fileOffset, noLength);
     }
     if (forest.argumentsPositional(arguments).length >
         function.positionalParameters.length) {
       return fasta.templateTooManyArguments
-          .withArguments(function.positionalParameters.length,
-              forest.argumentsPositional(arguments).length)
+          .withArguments(
+              positionalParameterCountToReport, positionalArgumentCountToReport)
           .withLocation(uri, arguments.fileOffset, noLength);
     }
     List<NamedExpression> named = forest.argumentsNamed(arguments);
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
index 24f2850..572feea 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
@@ -21,7 +21,8 @@
       {List<LocatedMessage> context, bool suppressMessage});
 
   LocatedMessage checkArgumentsForType(
-      FunctionType function, Arguments arguments, int offset);
+      FunctionType function, Arguments arguments, int offset,
+      {bool isExtensionMemberInvocation = false});
 
   void addProblem(Message message, int charOffset, int length,
       {List<LocatedMessage> context, bool wasHandled});
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 0c4eca9..78e4c89 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -2058,7 +2058,8 @@
       bool isConst: false,
       bool isImplicitExtensionMember: false,
       bool isImplicitCall: false,
-      Member staticTarget}) {
+      Member staticTarget,
+      bool isExtensionMemberInvocation = false}) {
     int extensionTypeParameterCount = getExtensionTypeParameterCount(arguments);
     if (extensionTypeParameterCount != 0) {
       return _inferGenericExtensionMethodInvocation(extensionTypeParameterCount,
@@ -2079,7 +2080,8 @@
         isConst: isConst,
         isImplicitExtensionMember: isImplicitExtensionMember,
         isImplicitCall: isImplicitCall,
-        staticTarget: staticTarget);
+        staticTarget: staticTarget,
+        isExtensionMemberInvocation: isExtensionMemberInvocation);
   }
 
   InvocationInferenceResult _inferGenericExtensionMethodInvocation(
@@ -2114,7 +2116,8 @@
         receiverType: receiverType,
         isImplicitExtensionMember: isImplicitExtensionMember,
         isImplicitCall: isImplicitCall,
-        staticTarget: staticTarget);
+        staticTarget: staticTarget,
+        isExtensionMemberInvocation: true);
     Substitution extensionSubstitution = Substitution.fromPairs(
         extensionFunctionType.typeParameters, extensionArguments.types);
 
@@ -2171,7 +2174,8 @@
       bool isConst: false,
       bool isImplicitExtensionMember: false,
       bool isImplicitCall,
-      Member staticTarget}) {
+      Member staticTarget,
+      bool isExtensionMemberInvocation: false}) {
     List<TypeParameter> calleeTypeParameters = calleeType.typeParameters;
     if (calleeTypeParameters.isNotEmpty) {
       // It's possible that one of the callee type parameters might match a type
@@ -2391,8 +2395,9 @@
     List<DartType> positionalArgumentTypes = [];
     List<NamedType> namedArgumentTypes = [];
     if (typeChecksNeeded && !identical(calleeType, unknownFunction)) {
-      LocatedMessage argMessage =
-          helper.checkArgumentsForType(calleeType, arguments, offset);
+      LocatedMessage argMessage = helper.checkArgumentsForType(
+          calleeType, arguments, offset,
+          isExtensionMemberInvocation: isExtensionMemberInvocation);
       if (argMessage != null) {
         return new WrapInProblemInferenceResult(
             const InvalidType(),
@@ -2860,7 +2865,8 @@
           hoistedExpressions: hoistedExpressions,
           receiverType: receiverType,
           isImplicitExtensionMember: true,
-          isImplicitCall: isImplicitCall);
+          isImplicitCall: isImplicitCall,
+          isExtensionMemberInvocation: true);
       if (!isTopLevel) {
         library.checkBoundsInStaticInvocation(staticInvocation,
             typeSchemaEnvironment, helper.uri, getTypeArgumentsInfo(arguments));
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.expect b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.expect
index 8c0ab7a..3dfc9a6 100644
--- a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.expect
@@ -34,14 +34,14 @@
 //   Extension(c1).foo();
 //                 ^^^
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 2 required, 1 given.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 1 required, 0 given.
 //   Extension(c1).method();
 //                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 2 allowed, but 3 found.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 1 allowed, but 2 found.
 // Try removing the extra positional arguments.
 //   Extension(c1).method(1, 2);
 //                 ^
@@ -49,7 +49,7 @@
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 2 required, 1 given.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 1 required, 0 given.
 //   Extension(c1).method(a: 1);
 //                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
@@ -199,14 +199,14 @@
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:17: Error: Method not found: 'foo'.
   Extension(c1).foo();
                 ^^^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 2 required, 1 given.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 1 required, 0 given.
   Extension(c1).method();
                 ^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 2 allowed, but 3 found.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 1 allowed, but 2 found.
 Try removing the extra positional arguments.
   Extension(c1).method(1, 2);
                 ^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 2 required, 1 given.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 1 required, 0 given.
   Extension(c1).method(a: 1);
                 ^";
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:38:27: Error: No named parameter with the name 'a'.
diff --git a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.transformed.expect
index 8c0ab7a..3dfc9a6 100644
--- a/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/invalid_explicit_access.dart.weak.transformed.expect
@@ -34,14 +34,14 @@
 //   Extension(c1).foo();
 //                 ^^^
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 2 required, 1 given.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 1 required, 0 given.
 //   Extension(c1).method();
 //                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 2 allowed, but 3 found.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 1 allowed, but 2 found.
 // Try removing the extra positional arguments.
 //   Extension(c1).method(1, 2);
 //                 ^
@@ -49,7 +49,7 @@
 //   method(a) {}
 //   ^^^^^^^^^^^^^...
 //
-// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 2 required, 1 given.
+// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 1 required, 0 given.
 //   Extension(c1).method(a: 1);
 //                 ^
 // pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
@@ -199,14 +199,14 @@
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:31:17: Error: Method not found: 'foo'.
   Extension(c1).foo();
                 ^^^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 2 required, 1 given.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:32:17: Error: Too few positional arguments: 1 required, 0 given.
   Extension(c1).method();
                 ^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 2 allowed, but 3 found.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:36:17: Error: Too many positional arguments: 1 allowed, but 2 found.
 Try removing the extra positional arguments.
   Extension(c1).method(1, 2);
                 ^";
-  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 2 required, 1 given.
+  invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:37:17: Error: Too few positional arguments: 1 required, 0 given.
   Extension(c1).method(a: 1);
                 ^";
   invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:38:27: Error: No named parameter with the name 'a'.
diff --git a/pkg/front_end/testcases/general/issue45204.dart b/pkg/front_end/testcases/general/issue45204.dart
new file mode 100644
index 0000000..ee754db
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45204.dart
@@ -0,0 +1,44 @@
+// 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.
+
+extension S on int {
+  void test(int x) {}
+}
+
+extension S2<X> on int {
+  void test2(int x) {}
+  void test3<Y>(Y y) {}
+}
+
+foo() {
+  3.test();
+  4.test(5, 6);
+  5.test<int>(6);
+
+  3.test2();
+  4.test2(5, 6);
+  5.test2<int>(6);
+
+  3.test3();
+  4.test3(5, 6);
+  5.test3<int>(6);
+  6.test3<int, int>(7);
+  7.test3<int, int, int>(8);
+
+  S(3).test();
+  S(4).test(5, 6);
+  S(5).test<int>(6);
+
+  S2(3).test2();
+  S2(4).test2(5, 6);
+  S2(5).test2<int>(6);
+
+  S2(3).test3();
+  S2(4).test3(5, 6);
+  S2(5).test3<int>(6);
+  S2(6).test3<int, int>(7);
+  S2(7).test3<int, int, int>(8);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue45204.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue45204.dart.textual_outline.expect
new file mode 100644
index 0000000..1eac4b0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45204.dart.textual_outline.expect
@@ -0,0 +1,11 @@
+extension S on int {
+  void test(int x) {}
+}
+
+extension S2<X> on int {
+  void test2(int x) {}
+  void test3<Y>(Y y) {}
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue45204.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue45204.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..1eac4b0
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45204.dart.textual_outline_modelled.expect
@@ -0,0 +1,11 @@
+extension S on int {
+  void test(int x) {}
+}
+
+extension S2<X> on int {
+  void test2(int x) {}
+  void test3<Y>(Y y) {}
+}
+
+foo() {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue45204.dart.weak.expect b/pkg/front_end/testcases/general/issue45204.dart.weak.expect
new file mode 100644
index 0000000..6488985
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45204.dart.weak.expect
@@ -0,0 +1,213 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue45204.dart:29:8: Error: Too few positional arguments: 1 required, 0 given.
+//   S(3).test();
+//        ^
+// pkg/front_end/testcases/general/issue45204.dart:6:8: Context: Found this candidate, but the arguments don't match.
+//   void test(int x) {}
+//        ^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:30:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//   S(4).test(5, 6);
+//        ^
+// pkg/front_end/testcases/general/issue45204.dart:6:8: Context: Found this candidate, but the arguments don't match.
+//   void test(int x) {}
+//        ^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:31:8: Error: Expected 0 type arguments.
+//   S(5).test<int>(6);
+//        ^
+// pkg/front_end/testcases/general/issue45204.dart:6:8: Context: Found this candidate, but the arguments don't match.
+//   void test(int x) {}
+//        ^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:33:9: Error: Too few positional arguments: 1 required, 0 given.
+//   S2(3).test2();
+//         ^
+// pkg/front_end/testcases/general/issue45204.dart:10:8: Context: Found this candidate, but the arguments don't match.
+//   void test2(int x) {}
+//        ^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:34:9: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//   S2(4).test2(5, 6);
+//         ^
+// pkg/front_end/testcases/general/issue45204.dart:10:8: Context: Found this candidate, but the arguments don't match.
+//   void test2(int x) {}
+//        ^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:35:9: Error: Expected 1 type arguments.
+//   S2(5).test2<int>(6);
+//         ^
+// pkg/front_end/testcases/general/issue45204.dart:10:8: Context: Found this candidate, but the arguments don't match.
+//   void test2(int x) {}
+//        ^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:37:9: Error: Too few positional arguments: 1 required, 0 given.
+//   S2(3).test3();
+//         ^
+// pkg/front_end/testcases/general/issue45204.dart:11:8: Context: Found this candidate, but the arguments don't match.
+//   void test3<Y>(Y y) {}
+//        ^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:38:9: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//   S2(4).test3(5, 6);
+//         ^
+// pkg/front_end/testcases/general/issue45204.dart:11:8: Context: Found this candidate, but the arguments don't match.
+//   void test3<Y>(Y y) {}
+//        ^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:40:9: Error: Expected 2 type arguments.
+//   S2(6).test3<int, int>(7);
+//         ^
+// pkg/front_end/testcases/general/issue45204.dart:11:8: Context: Found this candidate, but the arguments don't match.
+//   void test3<Y>(Y y) {}
+//        ^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:41:9: Error: Expected 2 type arguments.
+//   S2(7).test3<int, int, int>(8);
+//         ^
+// pkg/front_end/testcases/general/issue45204.dart:11:8: Context: Found this candidate, but the arguments don't match.
+//   void test3<Y>(Y y) {}
+//        ^^^^^^^^
+//
+// pkg/front_end/testcases/general/issue45204.dart:15:9: Error: Too few positional arguments: 1 required, 0 given.
+//   3.test();
+//         ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:16:9: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//   4.test(5, 6);
+//         ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:17:5: Error: Expected 0 type arguments.
+//   5.test<int>(6);
+//     ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:19:10: Error: Too few positional arguments: 1 required, 0 given.
+//   3.test2();
+//          ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:20:10: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//   4.test2(5, 6);
+//          ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:21:5: Error: Expected 0 type arguments.
+//   5.test2<int>(6);
+//     ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:23:10: Error: Too few positional arguments: 1 required, 0 given.
+//   3.test3();
+//          ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:24:10: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//   4.test3(5, 6);
+//          ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:26:5: Error: Expected 1 type arguments.
+//   6.test3<int, int>(7);
+//     ^
+//
+// pkg/front_end/testcases/general/issue45204.dart:27:5: Error: Expected 1 type arguments.
+//   7.test3<int, int, int>(8);
+//     ^
+//
+import self as self;
+import "dart:core" as core;
+
+extension S on core::int {
+  method test = self::S|test;
+  tearoff test = self::S|get#test;
+}
+extension S2<X extends core::Object? = dynamic> on core::int {
+  method test2 = self::S2|test2;
+  tearoff test2 = self::S2|get#test2;
+  method test3 = self::S2|test3;
+  tearoff test3 = self::S2|get#test3;
+}
+static method S|test(lowered final core::int #this, core::int x) → void {}
+static method S|get#test(lowered final core::int #this) → (core::int) → void
+  return (core::int x) → void => self::S|test(#this, x);
+static method S2|test2<X extends core::Object? = dynamic>(lowered final core::int #this, core::int x) → void {}
+static method S2|get#test2<X extends core::Object? = dynamic>(lowered final core::int #this) → (core::int) → void
+  return (core::int x) → void => self::S2|test2<self::S2|get#test2::X%>(#this, x);
+static method S2|test3<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(lowered final core::int #this, self::S2|test3::Y% y) → void {}
+static method S2|get#test3<X extends core::Object? = dynamic>(lowered final core::int #this) → <Y extends core::Object? = dynamic>(Y%) → void
+  return <Y extends core::Object? = dynamic>(Y% y) → void => self::S2|test3<self::S2|get#test3::X%, Y%>(#this, y);
+static method foo() → dynamic {
+  let final Never #t1 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:15:9: Error: Too few positional arguments: 1 required, 0 given.
+  3.test();
+        ^" in self::S|test(3);
+  let final Never #t2 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:16:9: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+  4.test(5, 6);
+        ^" in self::S|test(4, 5, 6);
+  let final Never #t3 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:17:5: Error: Expected 0 type arguments.
+  5.test<int>(6);
+    ^" in self::S|test<core::int>(5, 6);
+  let final Never #t4 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:19:10: Error: Too few positional arguments: 1 required, 0 given.
+  3.test2();
+         ^" in self::S2|test2<dynamic>(3);
+  let final Never #t5 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:20:10: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+  4.test2(5, 6);
+         ^" in self::S2|test2<dynamic>(4, 5, 6);
+  let final Never #t6 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:21:5: Error: Expected 0 type arguments.
+  5.test2<int>(6);
+    ^" in self::S2|test2<dynamic, core::int>(5, 6);
+  let final Never #t7 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:23:10: Error: Too few positional arguments: 1 required, 0 given.
+  3.test3();
+         ^" in self::S2|test3<dynamic, dynamic>(3);
+  let final Never #t8 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:24:10: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+  4.test3(5, 6);
+         ^" in self::S2|test3<dynamic, core::int>(4, 5, 6);
+  self::S2|test3<dynamic, core::int>(5, 6);
+  let final Never #t9 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:26:5: Error: Expected 1 type arguments.
+  6.test3<int, int>(7);
+    ^" in self::S2|test3<dynamic, core::int, core::int>(6, 7);
+  let final Never #t10 = invalid-expression "pkg/front_end/testcases/general/issue45204.dart:27:5: Error: Expected 1 type arguments.
+  7.test3<int, int, int>(8);
+    ^" in self::S2|test3<dynamic, core::int, core::int, core::int>(7, 8);
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:29:8: Error: Too few positional arguments: 1 required, 0 given.
+  S(3).test();
+       ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:30:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+  S(4).test(5, 6);
+       ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:31:8: Error: Expected 0 type arguments.
+  S(5).test<int>(6);
+       ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:33:9: Error: Too few positional arguments: 1 required, 0 given.
+  S2(3).test2();
+        ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:34:9: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+  S2(4).test2(5, 6);
+        ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:35:9: Error: Expected 1 type arguments.
+  S2(5).test2<int>(6);
+        ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:37:9: Error: Too few positional arguments: 1 required, 0 given.
+  S2(3).test3();
+        ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:38:9: Error: Too many positional arguments: 1 allowed, but 2 found.
+Try removing the extra positional arguments.
+  S2(4).test3(5, 6);
+        ^";
+  self::S2|test3<dynamic, core::int>(5, 6);
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:40:9: Error: Expected 2 type arguments.
+  S2(6).test3<int, int>(7);
+        ^";
+  invalid-expression "pkg/front_end/testcases/general/issue45204.dart:41:9: Error: Expected 2 type arguments.
+  S2(7).test3<int, int, int>(8);
+        ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue45204.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue45204.dart.weak.outline.expect
new file mode 100644
index 0000000..2c95328
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45204.dart.weak.outline.expect
@@ -0,0 +1,30 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+extension S on core::int {
+  method test = self::S|test;
+  tearoff test = self::S|get#test;
+}
+extension S2<X extends core::Object? = dynamic> on core::int {
+  method test2 = self::S2|test2;
+  tearoff test2 = self::S2|get#test2;
+  method test3 = self::S2|test3;
+  tearoff test3 = self::S2|get#test3;
+}
+static method S|test(lowered final core::int #this, core::int x) → void
+  ;
+static method S|get#test(lowered final core::int #this) → (core::int) → void
+  return (core::int x) → void => self::S|test(#this, x);
+static method S2|test2<X extends core::Object? = dynamic>(lowered final core::int #this, core::int x) → void
+  ;
+static method S2|get#test2<X extends core::Object? = dynamic>(lowered final core::int #this) → (core::int) → void
+  return (core::int x) → void => self::S2|test2<self::S2|get#test2::X%>(#this, x);
+static method S2|test3<X extends core::Object? = dynamic, Y extends core::Object? = dynamic>(lowered final core::int #this, self::S2|test3::Y% y) → void
+  ;
+static method S2|get#test3<X extends core::Object? = dynamic>(lowered final core::int #this) → <Y extends core::Object? = dynamic>(Y%) → void
+  return <Y extends core::Object? = dynamic>(Y% y) → void => self::S2|test3<self::S2|get#test3::X%, Y%>(#this, y);
+static method foo() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 2538568..0bc79fa 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -77,6 +77,7 @@
 general/issue41210a: TypeCheckError
 general/issue41210b/issue41210.no_link: TypeCheckError
 general/issue41210b/issue41210: TypeCheckError
+general/issue45204: TypeCheckError
 general/micro: RuntimeError
 general/mixin_application_override: TypeCheckError
 general/mixin_constructors_with_default_values: RuntimeError
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index 31f6de1..58f937f 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -81,6 +81,7 @@
 general/issue41210a: TypeCheckError
 general/issue41210b/issue41210.no_link: TypeCheckError
 general/issue41210b/issue41210: TypeCheckError
+general/issue45204: TypeCheckError
 general/micro: RuntimeError
 general/mixin_application_override: ExpectationFileMismatch # Too many errors.
 general/mixin_application_override: TypeCheckError
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index 8cbf77b..4ecf6ce 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -459,6 +459,7 @@
   }
 
   visitLet(Let node) {
+    if (_isCompileTimeErrorEncoding(node)) return;
     visitWithLocalScope(node);
   }
 
@@ -921,6 +922,12 @@
   }
 
   @override
+  void visitLet(Let node) {
+    if (_isCompileTimeErrorEncoding(node)) return;
+    super.visitLet(node);
+  }
+
+  @override
   void defaultExpression(Expression node) {
     try {
       node.getStaticType(_staticTypeContext);
@@ -961,3 +968,7 @@
 void checkInitializers(Constructor constructor) {
   // TODO(ahe): I'll add more here in other CLs.
 }
+
+bool _isCompileTimeErrorEncoding(TreeNode? node) {
+  return node is Let && node.variable.initializer is InvalidExpression;
+}