[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;
+}