Skip to content

Commit

Permalink
[cfe] Apply explicit type arguments in constructor tear-offs
Browse files Browse the repository at this point in the history
Change-Id: I9a8e73d26e320d64f899c7799ad001369db918d6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/206242
Commit-Queue: Dmitry Stefantsov <[email protected]>
Reviewed-by: Johnni Winther <[email protected]>
  • Loading branch information
Dmitry Stefantsov authored and [email protected] committed Jul 9, 2021
1 parent 0f94869 commit a8d78be
Show file tree
Hide file tree
Showing 14 changed files with 444 additions and 180 deletions.
24 changes: 20 additions & 4 deletions pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3112,26 +3112,42 @@ class TypeUseGenerator extends AbstractReadOnlyAccessGenerator {
if (member == null) {
// If we find a setter, [member] is an [AccessErrorBuilder], not null.
if (send is IncompletePropertyAccessGenerator) {
assert(
send.typeArguments == null,
"Unexpected non-null typeArguments of "
"an IncompletePropertyAccessGenerator object: "
"'${send.typeArguments.runtimeType}'.");
if (_helper.enableConstructorTearOffsInLibrary &&
declarationBuilder is ClassBuilder) {
MemberBuilder? constructor =
declarationBuilder.findConstructorOrFactory(
name.text, nameOffset, _uri, _helper.libraryBuilder);
Member? tearOff = constructor?.readTarget;
Expression? tearOffExpression;
if (tearOff is Constructor) {
if (declarationBuilder.isAbstract) {
return _helper.buildProblem(
messageAbstractClassConstructorTearOff,
nameOffset,
name.text.length);
}
return _helper.forest
tearOffExpression = _helper.forest
.createConstructorTearOff(token.charOffset, tearOff);
} else if (tearOff is Procedure) {
return _helper.forest
.createStaticTearOff(token.charOffset, tearOff);
tearOffExpression =
_helper.forest.createStaticTearOff(token.charOffset, tearOff);
} else if (tearOff != null) {
unhandled("${tearOff.runtimeType}", "buildPropertyAccess",
operatorOffset, _helper.uri);
}
if (tearOffExpression != null) {
return typeArguments != null
? _helper.forest.createInstantiation(
token.charOffset,
tearOffExpression,
_helper.buildDartTypeArguments(typeArguments))
: tearOffExpression;
}
// TODO(dmitryas): Add support for factories.
}
generator = new UnresolvedNameGenerator(_helper, send.token, name);
} else {
Expand Down
8 changes: 8 additions & 0 deletions pkg/front_end/lib/src/fasta/kernel/forest.dart
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,14 @@ class Forest {
assert(fileOffset != null);
return new StaticTearOff(procedure)..fileOffset = fileOffset;
}

Instantiation createInstantiation(
int fileOffset, Expression expression, List<DartType> typeArguments) {
// ignore: unnecessary_null_comparison
assert(fileOffset != null);
return new Instantiation(expression, typeArguments)
..fileOffset = fileOffset;
}
}

class _VariablesDeclaration extends Statement {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,33 @@ library /*isNonNullableByDefault*/;
// A<X> Function<X>(X) test3() => A.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:32: Error: A value of type 'A<int> Function()' can't be returned from a function with return type 'A<X> Function<X>(X)'.
// - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
// - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
// - 'X/*2*/' is from 'unknown'.
// A<X> Function<X>(X) test4() => A<int>.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:16:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
// - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
// - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
// - 'X/*2*/' is from 'unknown'.
// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:16:32: Error: Too many type arguments: 1 allowed, but 2 found.
// Try removing the extra type arguments.
// A<X> Function<X>(X) test5() => A<int, String>.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:19:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:17:32: Error: A value of type 'A<int> Function(int)' can't be returned from a function with return type 'A<X> Function<X>(X)'.
// - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
// - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
// - 'X/*2*/' is from 'unknown'.
// A<X> Function<X>(X) test8() => A<int>.foo2; // Error.
// A<X> Function<X>(X) test6() => A<int>.foo1; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:20:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:18:32: Error: Too many type arguments: 1 allowed, but 2 found.
// Try removing the extra type arguments.
// A<X> Function<X>(X) test7() => A<int, String>.foo1; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:19:32: Error: A value of type 'A<int> Function(int, int)' can't be returned from a function with return type 'A<X> Function<X>(X)'.
// - 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
// - 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
// - 'X/*2*/' is from 'unknown'.
// A<X> Function<X>(X) test8() => A<int>.foo2; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:20:32: Error: Too many type arguments: 1 allowed, but 2 found.
// Try removing the extra type arguments.
// A<X> Function<X>(X) test9() => A<int, String>.foo2; // Error.
// ^
//
Expand Down Expand Up @@ -82,41 +84,39 @@ static method test3() → <X extends core::Object? = dynamic>(X%) → self::A<X%
A<X> Function<X>(X) test3() => A.new; // Error.
^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
static method test4() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
return let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
return let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:15:32: Error: A value of type 'A<int> Function()' can't be returned from a function with return type 'A<X> Function<X>(X)'.
- 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
- 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
- 'X/*2*/' is from 'unknown'.
A<X> Function<X>(X) test4() => A<int>.new; // Error.
^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
^" in (self::A::•<core::int>) as{TypeError,ForNonNullableByDefault} Never;
static method test5() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:16:32: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
- 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
- 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
- 'X/*2*/' is from 'unknown'.
return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:16:32: Error: Too many type arguments: 1 allowed, but 2 found.
Try removing the extra type arguments.
A<X> Function<X>(X) test5() => A<int, String>.new; // Error.
^" in self::A::• as{TypeError,ForNonNullableByDefault} Never;
^";
static method test6() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
return self::A::foo1;
return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:17:32: Error: A value of type 'A<int> Function(int)' can't be returned from a function with return type 'A<X> Function<X>(X)'.
- 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
A<X> Function<X>(X) test6() => A<int>.foo1; // Error.
^" in (self::A::foo1<core::int>) as{TypeError,ForNonNullableByDefault} Never;
static method test7() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
return self::A::foo1;
return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:18:32: Error: Too many type arguments: 1 allowed, but 2 found.
Try removing the extra type arguments.
A<X> Function<X>(X) test7() => A<int, String>.foo1; // Error.
^";
static method test8() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
return let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:19:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
return let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:19:32: Error: A value of type 'A<int> Function(int, int)' can't be returned from a function with return type 'A<X> Function<X>(X)'.
- 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
- 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
- 'X/*2*/' is from 'unknown'.
A<X> Function<X>(X) test8() => A<int>.foo2; // Error.
^" in self::A::foo2 as{TypeError,ForNonNullableByDefault} Never;
^" in (self::A::foo2<core::int>) as{TypeError,ForNonNullableByDefault} Never;
static method test9() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
return let final Never #t6 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:20:32: Error: A value of type 'A<X/*1*/> Function<X>(X/*1*/, int)' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
- 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
- 'X/*1*/' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
- 'X/*2*/' is from 'unknown'.
return invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:20:32: Error: Too many type arguments: 1 allowed, but 2 found.
Try removing the extra type arguments.
A<X> Function<X>(X) test9() => A<int, String>.foo2; // Error.
^" in self::A::foo2 as{TypeError,ForNonNullableByDefault} Never;
^";
static method test10() → <X extends core::Object? = dynamic>() → self::A<X%>
return self::A::bar1;
static method test11() → <X extends core::Object? = dynamic>(X%) → self::A<X%>
return let final Never #t7 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:22:33: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
return let final Never #t6 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart:22:33: Error: A value of type 'A<X/*1*/> Function<X>()' can't be returned from a function with return type 'A<X/*2*/> Function<X>(X/*2*/)'.
- 'A' is from 'pkg/front_end/testcases/constructor_tearoffs/generic_tearoff_with_context.dart'.
- 'X/*1*/' is from 'unknown'.
- 'X/*2*/' is from 'unknown'.
Expand Down
Loading

0 comments on commit a8d78be

Please sign in to comment.