[cfe] Check for misplaced type arguments on implicit creation expression
Change-Id: Ic3436f2bce0369d0efad9946cbbdae7c6bf334b9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/218400
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
index 82f970c..042507d 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/forwarding_listener.dart
@@ -810,8 +810,8 @@
}
@override
- void endImplicitCreationExpression(Token token) {
- listener?.endImplicitCreationExpression(token);
+ void endImplicitCreationExpression(Token token, Token openAngleBracket) {
+ listener?.endImplicitCreationExpression(token, openAngleBracket);
}
@override
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
index cd83709..63a247f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/listener.dart
@@ -743,7 +743,7 @@
void beginImplicitCreationExpression(Token token) {}
- void endImplicitCreationExpression(Token token) {
+ void endImplicitCreationExpression(Token token, Token openAngleBracket) {
logEvent("ImplicitCreationExpression");
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index 0f466bf..cb1ef21 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -5404,7 +5404,8 @@
Token afterPeriod = afterTypeArguments.next!;
if (_isNewOrIdentifier(afterPeriod) &&
optional('(', afterPeriod.next!)) {
- return parseImplicitCreationExpression(token, typeArg);
+ return parseImplicitCreationExpression(
+ token, identifier.next!, typeArg);
}
}
}
@@ -6057,13 +6058,13 @@
}
Token parseImplicitCreationExpression(
- Token token, TypeParamOrArgInfo typeArg) {
- Token begin = token;
- listener.beginImplicitCreationExpression(token);
+ Token token, Token openAngleBracket, TypeParamOrArgInfo typeArg) {
+ Token begin = token.next!; // This is the class name.
+ listener.beginImplicitCreationExpression(begin);
token = parseConstructorReference(
token, ConstructorReferenceContext.Implicit, typeArg);
token = parseConstructorInvocationArguments(token);
- listener.endImplicitCreationExpression(begin);
+ listener.endImplicitCreationExpression(begin, openAngleBracket);
return token;
}
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index e88c858..4a50a3c 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -1664,7 +1664,7 @@
}
@override
- void endImplicitCreationExpression(Token token) {
+ void endImplicitCreationExpression(Token token, Token openAngleBracket) {
debugEvent("ImplicitCreationExpression");
_handleInstanceCreation(null);
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 6f08b8b..c19ef88 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -4948,6 +4948,14 @@
if (enableConstructorTearOffsInLibrary && inImplicitCreationContext) {
Expression receiver = receiverFunction();
if (typeArguments != null) {
+ if (receiver is StaticTearOff &&
+ (receiver.target.isFactory ||
+ isTearOffLowering(receiver.target)) ||
+ receiver is ConstructorTearOff ||
+ receiver is RedirectingFactoryTearOff) {
+ return buildProblem(fasta.messageConstructorTearOffWithTypeArguments,
+ instantiationOffset, noLength);
+ }
receiver = forest.createInstantiation(
instantiationOffset,
receiver,
@@ -4974,10 +4982,10 @@
}
@override
- void endImplicitCreationExpression(Token token) {
+ void endImplicitCreationExpression(Token token, Token openAngleBracket) {
debugEvent("ImplicitCreationExpression");
_buildConstructorReferenceInvocation(
- token.next!, token.offset, Constness.implicit,
+ token, openAngleBracket.offset, Constness.implicit,
inMetadata: false, inImplicitCreationContext: true);
}
diff --git a/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart b/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart
index ffb7439..4fedb0b 100644
--- a/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart
+++ b/pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart
@@ -1172,11 +1172,12 @@
}
@override
- void endImplicitCreationExpression(Token token) {
+ void endImplicitCreationExpression(Token token, Token openAngleBracket) {
DirectParserASTContentImplicitCreationExpressionEnd data =
new DirectParserASTContentImplicitCreationExpressionEnd(
DirectParserASTType.END,
- token: token);
+ token: token,
+ openAngleBracket: openAngleBracket);
seen(data);
}
@@ -4782,14 +4783,16 @@
class DirectParserASTContentImplicitCreationExpressionEnd
extends DirectParserASTContent {
final Token token;
+ final Token openAngleBracket;
DirectParserASTContentImplicitCreationExpressionEnd(DirectParserASTType type,
- {required this.token})
+ {required this.token, required this.openAngleBracket})
: super("ImplicitCreationExpression", type);
@override
Map<String, Object?> get deprecatedArguments => {
"token": token,
+ "openAngleBracket": openAngleBracket,
};
}
diff --git a/pkg/front_end/parser_testcases/general/function_reference_following_token.dart.expect b/pkg/front_end/parser_testcases/general/function_reference_following_token.dart.expect
index 2fca01a..8b8e356 100644
--- a/pkg/front_end/parser_testcases/general/function_reference_following_token.dart.expect
+++ b/pkg/front_end/parser_testcases/general/function_reference_following_token.dart.expect
@@ -293,7 +293,7 @@
handleNoType(var)
handleIdentifier(typeArgs_period_methodInvocation, topLevelVariableDeclaration)
beginFieldInitializer(=)
- beginImplicitCreationExpression(=)
+ beginImplicitCreationExpression(f)
handleIdentifier(f, constructorReference)
beginConstructorReference(f)
beginTypeArguments(<)
@@ -308,7 +308,7 @@
endConstructorReference(f, ., (, ConstructorReferenceContext.Implicit)
beginArguments(()
endArguments(0, (, ))
- endImplicitCreationExpression(=)
+ endImplicitCreationExpression(f, <)
endFieldInitializer(=, ;)
endTopLevelFields(null, null, null, null, var, 1, var, ;)
endTopLevelDeclaration(var)
diff --git a/pkg/front_end/parser_testcases/general/function_reference_following_token.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/function_reference_following_token.dart.intertwined.expect
index 32d6f7d..11e6ef5 100644
--- a/pkg/front_end/parser_testcases/general/function_reference_following_token.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/function_reference_following_token.dart.intertwined.expect
@@ -396,8 +396,8 @@
parseExpression(=)
parsePrecedenceExpression(=, 1, true)
parseUnaryExpression(=, true)
- parseImplicitCreationExpression(=, Instance of 'ComplexTypeParamOrArgInfo')
- listener: beginImplicitCreationExpression(=)
+ parseImplicitCreationExpression(=, <, Instance of 'ComplexTypeParamOrArgInfo')
+ listener: beginImplicitCreationExpression(f)
parseConstructorReference(=, ConstructorReferenceContext.Implicit, Instance of 'ComplexTypeParamOrArgInfo')
ensureIdentifier(=, constructorReference)
listener: handleIdentifier(f, constructorReference)
@@ -418,7 +418,7 @@
parseArgumentsRest(()
listener: beginArguments(()
listener: endArguments(0, (, ))
- listener: endImplicitCreationExpression(=)
+ listener: endImplicitCreationExpression(f, <)
listener: endFieldInitializer(=, ;)
listener: endTopLevelFields(null, null, null, null, var, 1, var, ;)
listener: endTopLevelDeclaration(var)
diff --git a/pkg/front_end/parser_testcases/general/new_as_identifier.dart.expect b/pkg/front_end/parser_testcases/general/new_as_identifier.dart.expect
index 89b9611..97bcac4 100644
--- a/pkg/front_end/parser_testcases/general/new_as_identifier.dart.expect
+++ b/pkg/front_end/parser_testcases/general/new_as_identifier.dart.expect
@@ -545,7 +545,7 @@
handleNoType(var)
handleIdentifier(constructor_invocation_implicit_generic, topLevelVariableDeclaration)
beginFieldInitializer(=)
- beginImplicitCreationExpression(=)
+ beginImplicitCreationExpression(C)
handleIdentifier(C, constructorReference)
beginConstructorReference(C)
beginTypeArguments(<)
@@ -558,7 +558,7 @@
endConstructorReference(C, ., (, ConstructorReferenceContext.Implicit)
beginArguments(()
endArguments(0, (, ))
- endImplicitCreationExpression(=)
+ endImplicitCreationExpression(C, <)
endFieldInitializer(=, ;)
endTopLevelFields(null, null, null, null, var, 1, var, ;)
endTopLevelDeclaration(var)
@@ -595,7 +595,7 @@
handleNoType(var)
handleIdentifier(constructor_invocation_implicit_prefixed_generic, topLevelVariableDeclaration)
beginFieldInitializer(=)
- beginImplicitCreationExpression(=)
+ beginImplicitCreationExpression(prefix)
handleIdentifier(prefix, constructorReference)
beginConstructorReference(prefix)
handleIdentifier(C, constructorReferenceContinuation)
@@ -610,7 +610,7 @@
endConstructorReference(prefix, ., (, ConstructorReferenceContext.Implicit)
beginArguments(()
endArguments(0, (, ))
- endImplicitCreationExpression(=)
+ endImplicitCreationExpression(prefix, <)
endFieldInitializer(=, ;)
endTopLevelFields(null, null, null, null, var, 1, var, ;)
endTopLevelDeclaration(var)
diff --git a/pkg/front_end/parser_testcases/general/new_as_identifier.dart.intertwined.expect b/pkg/front_end/parser_testcases/general/new_as_identifier.dart.intertwined.expect
index f1c6c1c..7af61b0 100644
--- a/pkg/front_end/parser_testcases/general/new_as_identifier.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/general/new_as_identifier.dart.intertwined.expect
@@ -1028,8 +1028,8 @@
parseExpression(=)
parsePrecedenceExpression(=, 1, true)
parseUnaryExpression(=, true)
- parseImplicitCreationExpression(=, Instance of 'SimpleTypeArgument1')
- listener: beginImplicitCreationExpression(=)
+ parseImplicitCreationExpression(=, <, Instance of 'SimpleTypeArgument1')
+ listener: beginImplicitCreationExpression(C)
parseConstructorReference(=, ConstructorReferenceContext.Implicit, Instance of 'SimpleTypeArgument1')
ensureIdentifier(=, constructorReference)
listener: handleIdentifier(C, constructorReference)
@@ -1049,7 +1049,7 @@
parseArgumentsRest(()
listener: beginArguments(()
listener: endArguments(0, (, ))
- listener: endImplicitCreationExpression(=)
+ listener: endImplicitCreationExpression(C, <)
listener: endFieldInitializer(=, ;)
listener: endTopLevelFields(null, null, null, null, var, 1, var, ;)
listener: endTopLevelDeclaration(var)
@@ -1126,8 +1126,8 @@
parseExpression(=)
parsePrecedenceExpression(=, 1, true)
parseUnaryExpression(=, true)
- parseImplicitCreationExpression(=, Instance of 'SimpleTypeArgument1')
- listener: beginImplicitCreationExpression(=)
+ parseImplicitCreationExpression(=, <, Instance of 'SimpleTypeArgument1')
+ listener: beginImplicitCreationExpression(prefix)
parseConstructorReference(=, ConstructorReferenceContext.Implicit, Instance of 'SimpleTypeArgument1')
ensureIdentifier(=, constructorReference)
listener: handleIdentifier(prefix, constructorReference)
@@ -1151,7 +1151,7 @@
parseArgumentsRest(()
listener: beginArguments(()
listener: endArguments(0, (, ))
- listener: endImplicitCreationExpression(=)
+ listener: endImplicitCreationExpression(prefix, <)
listener: endFieldInitializer(=, ;)
listener: endTopLevelFields(null, null, null, null, var, 1, var, ;)
listener: endTopLevelDeclaration(var)
diff --git a/pkg/front_end/test/parser_test_listener.dart b/pkg/front_end/test/parser_test_listener.dart
index 7fcb1c2..f82cd95 100644
--- a/pkg/front_end/test/parser_test_listener.dart
+++ b/pkg/front_end/test/parser_test_listener.dart
@@ -1086,10 +1086,11 @@
}
@override
- void endImplicitCreationExpression(Token token) {
+ void endImplicitCreationExpression(Token token, Token openAngleBracket) {
indent--;
seen(token);
- doPrint('endImplicitCreationExpression(' '$token)');
+ seen(openAngleBracket);
+ doPrint('endImplicitCreationExpression(' '$token, ' '$openAngleBracket)');
}
@override
diff --git a/pkg/front_end/test/parser_test_parser.dart b/pkg/front_end/test/parser_test_parser.dart
index 3ea2b0c..a6ba2ca 100644
--- a/pkg/front_end/test/parser_test_parser.dart
+++ b/pkg/front_end/test/parser_test_parser.dart
@@ -1651,10 +1651,14 @@
@override
Token parseImplicitCreationExpression(
- Token token, TypeParamOrArgInfo typeArg) {
- doPrint('parseImplicitCreationExpression(' '$token, ' '$typeArg)');
+ Token token, Token openAngleBracket, TypeParamOrArgInfo typeArg) {
+ doPrint('parseImplicitCreationExpression('
+ '$token, '
+ '$openAngleBracket, '
+ '$typeArg)');
indent++;
- var result = super.parseImplicitCreationExpression(token, typeArg);
+ var result =
+ super.parseImplicitCreationExpression(token, openAngleBracket, typeArg);
indent--;
return result;
}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart b/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart
index efe748f..4232eea 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart
@@ -21,7 +21,7 @@
}
test() {
- A.named<int>.toString();
+ A.named<int>.toString(); // error
}
void main() {
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.strong.expect b/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.strong.expect
index 99500cc..a62bd0c 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.strong.expect
@@ -1,4 +1,12 @@
library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/issue46719.dart:24:10: Error: A constructor tear-off can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// A.named<int>.toString(); // error
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -27,30 +35,33 @@
static method FunctionApplier|get#applyAndPrint(lowered final core::Function #this) → (core::List<core::Object?>) → void
return (core::List<core::Object?> positionalArguments) → void => self::FunctionApplier|applyAndPrint(#this, positionalArguments);
static method test() → dynamic {
- #C3.{core::Object::toString}(){() → core::String};
+ invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue46719.dart:24:10: Error: A constructor tear-off can't have type arguments after the constructor name.
+Try removing the type arguments or placing them after the class name.
+ A.named<int>.toString(); // error
+ ^";
}
static method main() → void {
self::A<dynamic> a = new self::A::•<dynamic>();
self::FunctionApplier|applyAndPrint(a.{self::A::m}{<X extends core::Object? = dynamic>(X%) → core::List<X%>}<core::int>, <core::Object?>[2]);
self::FunctionApplier|applyAndPrint(a.{self::A::m}{<X extends core::Object? = dynamic>(X%) → core::List<X%>}<core::String>, <core::Object?>["three"]);
- self::FunctionApplier|applyAndPrint(#C5, <core::Object?>[2]);
- self::FunctionApplier|applyAndPrint(#C6, <core::Object?>["three"]);
- self::FunctionApplier|applyAndPrint(#C8, <core::Object?>[2]);
- self::FunctionApplier|applyAndPrint(#C9, <core::Object?>["three"]);
- self::FunctionApplier|applyAndPrint(#C5, <core::Object?>[2]);
- self::FunctionApplier|applyAndPrint(#C6, <core::Object?>["three"]);
- #C2.{core::Object::toString}(){() → core::String};
- #C3.{core::Object::toString}(){() → core::String};
+ self::FunctionApplier|applyAndPrint(#C3, <core::Object?>[2]);
+ self::FunctionApplier|applyAndPrint(#C4, <core::Object?>["three"]);
+ self::FunctionApplier|applyAndPrint(#C6, <core::Object?>[2]);
+ self::FunctionApplier|applyAndPrint(#C7, <core::Object?>["three"]);
+ self::FunctionApplier|applyAndPrint(#C3, <core::Object?>[2]);
+ self::FunctionApplier|applyAndPrint(#C4, <core::Object?>["three"]);
+ #C8.{core::Object::toString}(){() → core::String};
+ #C9.{core::Object::toString}(){() → core::String};
}
constants {
#C1 = <core::Symbol, dynamic>{)
- #C2 = constructor-tearoff self::A::named
+ #C2 = static-tearoff self::A::n
#C3 = instantiation #C2 <core::int>
- #C4 = static-tearoff self::A::n
- #C5 = instantiation #C4 <core::int>
- #C6 = instantiation #C4 <core::String>
- #C7 = static-tearoff self::m
- #C8 = instantiation #C7 <core::int>
- #C9 = instantiation #C7 <core::String>
+ #C4 = instantiation #C2 <core::String>
+ #C5 = static-tearoff self::m
+ #C6 = instantiation #C5 <core::int>
+ #C7 = instantiation #C5 <core::String>
+ #C8 = constructor-tearoff self::A::named
+ #C9 = instantiation #C8 <core::int>
}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.strong.transformed.expect
index 4e41cb6..7124a3a 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/issue46719.dart:24:10: Error: A constructor tear-off can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// A.named<int>.toString(); // error
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -27,30 +35,33 @@
static method FunctionApplier|get#applyAndPrint(lowered final core::Function #this) → (core::List<core::Object?>) → void
return (core::List<core::Object?> positionalArguments) → void => self::FunctionApplier|applyAndPrint(#this, positionalArguments);
static method test() → dynamic {
- #C3.{core::Object::toString}(){() → core::String};
+ invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue46719.dart:24:10: Error: A constructor tear-off can't have type arguments after the constructor name.
+Try removing the type arguments or placing them after the class name.
+ A.named<int>.toString(); // error
+ ^";
}
static method main() → void {
self::A<dynamic> a = new self::A::•<dynamic>();
self::FunctionApplier|applyAndPrint(a.{self::A::m}{<X extends core::Object? = dynamic>(X%) → core::List<X%>}<core::int>, core::_GrowableList::_literal1<core::Object?>(2));
self::FunctionApplier|applyAndPrint(a.{self::A::m}{<X extends core::Object? = dynamic>(X%) → core::List<X%>}<core::String>, core::_GrowableList::_literal1<core::Object?>("three"));
- self::FunctionApplier|applyAndPrint(#C5, core::_GrowableList::_literal1<core::Object?>(2));
- self::FunctionApplier|applyAndPrint(#C6, core::_GrowableList::_literal1<core::Object?>("three"));
- self::FunctionApplier|applyAndPrint(#C8, core::_GrowableList::_literal1<core::Object?>(2));
- self::FunctionApplier|applyAndPrint(#C9, core::_GrowableList::_literal1<core::Object?>("three"));
- self::FunctionApplier|applyAndPrint(#C5, core::_GrowableList::_literal1<core::Object?>(2));
- self::FunctionApplier|applyAndPrint(#C6, core::_GrowableList::_literal1<core::Object?>("three"));
- #C2.{core::Object::toString}(){() → core::String};
- #C3.{core::Object::toString}(){() → core::String};
+ self::FunctionApplier|applyAndPrint(#C3, core::_GrowableList::_literal1<core::Object?>(2));
+ self::FunctionApplier|applyAndPrint(#C4, core::_GrowableList::_literal1<core::Object?>("three"));
+ self::FunctionApplier|applyAndPrint(#C6, core::_GrowableList::_literal1<core::Object?>(2));
+ self::FunctionApplier|applyAndPrint(#C7, core::_GrowableList::_literal1<core::Object?>("three"));
+ self::FunctionApplier|applyAndPrint(#C3, core::_GrowableList::_literal1<core::Object?>(2));
+ self::FunctionApplier|applyAndPrint(#C4, core::_GrowableList::_literal1<core::Object?>("three"));
+ #C8.{core::Object::toString}(){() → core::String};
+ #C9.{core::Object::toString}(){() → core::String};
}
constants {
#C1 = <core::Symbol, dynamic>{)
- #C2 = constructor-tearoff self::A::named
+ #C2 = static-tearoff self::A::n
#C3 = instantiation #C2 <core::int>
- #C4 = static-tearoff self::A::n
- #C5 = instantiation #C4 <core::int>
- #C6 = instantiation #C4 <core::String>
- #C7 = static-tearoff self::m
- #C8 = instantiation #C7 <core::int>
- #C9 = instantiation #C7 <core::String>
+ #C4 = instantiation #C2 <core::String>
+ #C5 = static-tearoff self::m
+ #C6 = instantiation #C5 <core::int>
+ #C7 = instantiation #C5 <core::String>
+ #C8 = constructor-tearoff self::A::named
+ #C9 = instantiation #C8 <core::int>
}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.weak.expect b/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.weak.expect
index ce83852..6add537 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.weak.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.weak.expect
@@ -1,4 +1,12 @@
library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/issue46719.dart:24:10: Error: A constructor tear-off can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// A.named<int>.toString(); // error
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -27,30 +35,33 @@
static method FunctionApplier|get#applyAndPrint(lowered final core::Function #this) → (core::List<core::Object?>) → void
return (core::List<core::Object?> positionalArguments) → void => self::FunctionApplier|applyAndPrint(#this, positionalArguments);
static method test() → dynamic {
- #C3.{core::Object::toString}(){() → core::String};
+ invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue46719.dart:24:10: Error: A constructor tear-off can't have type arguments after the constructor name.
+Try removing the type arguments or placing them after the class name.
+ A.named<int>.toString(); // error
+ ^";
}
static method main() → void {
self::A<dynamic> a = new self::A::•<dynamic>();
self::FunctionApplier|applyAndPrint(a.{self::A::m}{<X extends core::Object? = dynamic>(X%) → core::List<X%>}<core::int>, <core::Object?>[2]);
self::FunctionApplier|applyAndPrint(a.{self::A::m}{<X extends core::Object? = dynamic>(X%) → core::List<X%>}<core::String>, <core::Object?>["three"]);
- self::FunctionApplier|applyAndPrint(#C5, <core::Object?>[2]);
- self::FunctionApplier|applyAndPrint(#C6, <core::Object?>["three"]);
- self::FunctionApplier|applyAndPrint(#C8, <core::Object?>[2]);
- self::FunctionApplier|applyAndPrint(#C9, <core::Object?>["three"]);
- self::FunctionApplier|applyAndPrint(#C5, <core::Object?>[2]);
- self::FunctionApplier|applyAndPrint(#C6, <core::Object?>["three"]);
- #C2.{core::Object::toString}(){() → core::String};
- #C3.{core::Object::toString}(){() → core::String};
+ self::FunctionApplier|applyAndPrint(#C3, <core::Object?>[2]);
+ self::FunctionApplier|applyAndPrint(#C4, <core::Object?>["three"]);
+ self::FunctionApplier|applyAndPrint(#C6, <core::Object?>[2]);
+ self::FunctionApplier|applyAndPrint(#C7, <core::Object?>["three"]);
+ self::FunctionApplier|applyAndPrint(#C3, <core::Object?>[2]);
+ self::FunctionApplier|applyAndPrint(#C4, <core::Object?>["three"]);
+ #C8.{core::Object::toString}(){() → core::String};
+ #C9.{core::Object::toString}(){() → core::String};
}
constants {
#C1 = <core::Symbol*, dynamic>{)
- #C2 = constructor-tearoff self::A::named
+ #C2 = static-tearoff self::A::n
#C3 = instantiation #C2 <core::int*>
- #C4 = static-tearoff self::A::n
- #C5 = instantiation #C4 <core::int*>
- #C6 = instantiation #C4 <core::String*>
- #C7 = static-tearoff self::m
- #C8 = instantiation #C7 <core::int*>
- #C9 = instantiation #C7 <core::String*>
+ #C4 = instantiation #C2 <core::String*>
+ #C5 = static-tearoff self::m
+ #C6 = instantiation #C5 <core::int*>
+ #C7 = instantiation #C5 <core::String*>
+ #C8 = constructor-tearoff self::A::named
+ #C9 = instantiation #C8 <core::int*>
}
diff --git a/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.weak.transformed.expect b/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.weak.transformed.expect
index cd0afe2..328de14 100644
--- a/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/constructor_tearoffs/issue46719.dart.weak.transformed.expect
@@ -1,4 +1,12 @@
library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_tearoffs/issue46719.dart:24:10: Error: A constructor tear-off can't have type arguments after the constructor name.
+// Try removing the type arguments or placing them after the class name.
+// A.named<int>.toString(); // error
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -27,30 +35,33 @@
static method FunctionApplier|get#applyAndPrint(lowered final core::Function #this) → (core::List<core::Object?>) → void
return (core::List<core::Object?> positionalArguments) → void => self::FunctionApplier|applyAndPrint(#this, positionalArguments);
static method test() → dynamic {
- #C3.{core::Object::toString}(){() → core::String};
+ invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue46719.dart:24:10: Error: A constructor tear-off can't have type arguments after the constructor name.
+Try removing the type arguments or placing them after the class name.
+ A.named<int>.toString(); // error
+ ^";
}
static method main() → void {
self::A<dynamic> a = new self::A::•<dynamic>();
self::FunctionApplier|applyAndPrint(a.{self::A::m}{<X extends core::Object? = dynamic>(X%) → core::List<X%>}<core::int>, core::_GrowableList::_literal1<core::Object?>(2));
self::FunctionApplier|applyAndPrint(a.{self::A::m}{<X extends core::Object? = dynamic>(X%) → core::List<X%>}<core::String>, core::_GrowableList::_literal1<core::Object?>("three"));
- self::FunctionApplier|applyAndPrint(#C5, core::_GrowableList::_literal1<core::Object?>(2));
- self::FunctionApplier|applyAndPrint(#C6, core::_GrowableList::_literal1<core::Object?>("three"));
- self::FunctionApplier|applyAndPrint(#C8, core::_GrowableList::_literal1<core::Object?>(2));
- self::FunctionApplier|applyAndPrint(#C9, core::_GrowableList::_literal1<core::Object?>("three"));
- self::FunctionApplier|applyAndPrint(#C5, core::_GrowableList::_literal1<core::Object?>(2));
- self::FunctionApplier|applyAndPrint(#C6, core::_GrowableList::_literal1<core::Object?>("three"));
- #C2.{core::Object::toString}(){() → core::String};
- #C3.{core::Object::toString}(){() → core::String};
+ self::FunctionApplier|applyAndPrint(#C3, core::_GrowableList::_literal1<core::Object?>(2));
+ self::FunctionApplier|applyAndPrint(#C4, core::_GrowableList::_literal1<core::Object?>("three"));
+ self::FunctionApplier|applyAndPrint(#C6, core::_GrowableList::_literal1<core::Object?>(2));
+ self::FunctionApplier|applyAndPrint(#C7, core::_GrowableList::_literal1<core::Object?>("three"));
+ self::FunctionApplier|applyAndPrint(#C3, core::_GrowableList::_literal1<core::Object?>(2));
+ self::FunctionApplier|applyAndPrint(#C4, core::_GrowableList::_literal1<core::Object?>("three"));
+ #C8.{core::Object::toString}(){() → core::String};
+ #C9.{core::Object::toString}(){() → core::String};
}
constants {
#C1 = <core::Symbol*, dynamic>{)
- #C2 = constructor-tearoff self::A::named
+ #C2 = static-tearoff self::A::n
#C3 = instantiation #C2 <core::int*>
- #C4 = static-tearoff self::A::n
- #C5 = instantiation #C4 <core::int*>
- #C6 = instantiation #C4 <core::String*>
- #C7 = static-tearoff self::m
- #C8 = instantiation #C7 <core::int*>
- #C9 = instantiation #C7 <core::String*>
+ #C4 = instantiation #C2 <core::String*>
+ #C5 = static-tearoff self::m
+ #C6 = instantiation #C5 <core::int*>
+ #C7 = instantiation #C5 <core::String*>
+ #C8 = constructor-tearoff self::A::named
+ #C9 = instantiation #C8 <core::int*>
}
diff --git a/tests/language/constructor/reference_test.dart b/tests/language/constructor/reference_test.dart
index 6828160..06755d1 100644
--- a/tests/language/constructor/reference_test.dart
+++ b/tests/language/constructor/reference_test.dart
@@ -97,8 +97,7 @@
Foo.bar<int>.baz();
// ^^^^^
// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR
-// ^
-// [cfe] The method 'baz' isn't defined for the class 'Foo<int> Function()'.
+// [cfe] A constructor tear-off can't have type arguments after the constructor name.
Foo.bar.baz<int>();
// ^^^
// [analyzer] COMPILE_TIME_ERROR.UNDEFINED_METHOD