[cfe] Generate TypedefTearOff nodes on the output

Change-Id: I4b4a25137bffb0fa284a94908b05fef9b9e5c5da
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/206370
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Dmitry Stefantsov 2021-07-13 09:13:15 +00:00 committed by commit-bot@chromium.org
parent 298777c07d
commit ff2be51b1f
14 changed files with 239 additions and 123 deletions

View file

@ -11,6 +11,7 @@ import 'package:_fe_analyzer_shared/src/parser/parser.dart'
import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
import 'package:kernel/ast.dart';
import 'package:kernel/type_algebra.dart';
import '../builder/builder.dart';
import '../builder/class_builder.dart';
@ -24,6 +25,7 @@ import '../builder/prefix_builder.dart';
import '../builder/type_alias_builder.dart';
import '../builder/type_builder.dart';
import '../builder/type_declaration_builder.dart';
import '../builder/type_variable_builder.dart';
import '../builder/unresolved_type.dart';
import '../constant_context.dart' show ConstantContext;
@ -3099,6 +3101,7 @@ class TypeUseGenerator extends AbstractReadOnlyAccessGenerator {
TypeDeclarationBuilder? declarationBuilder = declaration;
TypeAliasBuilder? aliasBuilder;
List<TypeBuilder>? unaliasedTypeArguments;
bool isGenericTypedefTearOff = false;
if (declarationBuilder is TypeAliasBuilder) {
aliasBuilder = declarationBuilder;
declarationBuilder = aliasBuilder.unaliasDeclaration(null,
@ -3129,6 +3132,19 @@ class TypeUseGenerator extends AbstractReadOnlyAccessGenerator {
..fileUri = _uri
..offset = fileOffset);
}
if (aliasedTypeArguments == null &&
aliasBuilder.typeVariablesCount != 0) {
isGenericTypedefTearOff = true;
aliasedTypeArguments = <TypeBuilder>[];
for (TypeVariableBuilder typeVariable
in aliasBuilder.typeVariables!) {
aliasedTypeArguments.add(new NamedTypeBuilder(typeVariable.name,
const NullabilityBuilder.omitted(), null, _uri, fileOffset)
..bind(typeVariable));
}
}
unaliasedTypeArguments =
aliasBuilder.unaliasTypeArguments(aliasedTypeArguments);
}
}
}
@ -3177,10 +3193,31 @@ class TypeUseGenerator extends AbstractReadOnlyAccessGenerator {
builtTypeArguments =
_helper.buildDartTypeArguments(typeArguments);
}
return builtTypeArguments != null && builtTypeArguments.isNotEmpty
? _helper.forest.createInstantiation(
token.charOffset, tearOffExpression, builtTypeArguments)
: tearOffExpression;
if (isGenericTypedefTearOff) {
FreshTypeParameters freshTypeParameters =
getFreshTypeParameters(
aliasBuilder!.typedef.typeParameters);
List<DartType>? substitutedTypeArguments;
if (builtTypeArguments != null) {
substitutedTypeArguments = <DartType>[];
for (DartType builtTypeArgument in builtTypeArguments) {
substitutedTypeArguments
.add(freshTypeParameters.substitute(builtTypeArgument));
}
}
tearOffExpression = _helper.forest.createTypedefTearOff(
token.charOffset,
freshTypeParameters.freshTypeParameters,
tearOffExpression,
substitutedTypeArguments ?? const <DartType>[]);
} else {
if (builtTypeArguments != null &&
builtTypeArguments.isNotEmpty) {
tearOffExpression = _helper.forest.createInstantiation(
token.charOffset, tearOffExpression, builtTypeArguments);
}
}
return tearOffExpression;
}
}
generator = new UnresolvedNameGenerator(_helper, send.token, name);

View file

@ -846,6 +846,17 @@ class Forest {
return new Instantiation(expression, typeArguments)
..fileOffset = fileOffset;
}
TypedefTearOff createTypedefTearOff(
int fileOffset,
List<TypeParameter> typeParameters,
Expression expression,
List<DartType> typeArguments) {
// ignore: unnecessary_null_comparison
assert(fileOffset != null);
return new TypedefTearOff(typeParameters, expression, typeArguments)
..fileOffset = fileOffset;
}
}
class _VariablesDeclaration extends Statement {

View file

@ -7,7 +7,7 @@ import 'package:_fe_analyzer_shared/src/util/link.dart';
import 'package:front_end/src/api_prototype/lowering_predicates.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/src/legacy_erasure.dart';
import 'package:kernel/type_algebra.dart' show Substitution;
import 'package:kernel/type_algebra.dart';
import 'package:kernel/type_environment.dart';
import '../../base/instrumentation.dart'
@ -225,7 +225,37 @@ class InferenceVisitor
@override
ExpressionInferenceResult visitTypedefTearOff(
TypedefTearOff node, DartType typeContext) {
return _unhandledExpression(node, typeContext);
ExpressionInferenceResult expressionResult = inferrer.inferExpression(
node.expression, const UnknownType(), true,
isVoidAllowed: true);
node.expression = expressionResult.expression..parent = node;
assert(
expressionResult.inferredType is FunctionType,
"Expected a FunctionType from tearing off a constructor from "
"a typedef, but got '${expressionResult.inferredType.runtimeType}'.");
FunctionType expressionType = expressionResult.inferredType as FunctionType;
assert(expressionType.typeParameters.length == node.typeArguments.length);
Substitution substitution = Substitution.fromPairs(
expressionType.typeParameters, node.typeArguments);
FunctionType resultType = substitution
.substituteType(expressionType.withoutTypeParameters) as FunctionType;
FreshTypeParameters freshTypeParameters =
getFreshTypeParameters(node.typeParameters);
resultType = freshTypeParameters.substitute(resultType) as FunctionType;
resultType = new FunctionType(resultType.positionalParameters,
resultType.returnType, resultType.declaredNullability,
namedParameters: resultType.namedParameters,
typeParameters: freshTypeParameters.freshTypeParameters,
requiredParameterCount: resultType.requiredParameterCount,
typedefType: null);
ExpressionInferenceResult inferredResult =
inferrer.instantiateTearOff(resultType, typeContext, node);
Expression ensuredResultExpression =
inferrer.ensureAssignableResult(typeContext, inferredResult);
return new ExpressionInferenceResult(
inferredResult.inferredType, ensuredResultExpression);
}
@override

View file

@ -45,7 +45,9 @@ B<num> Function() test18() => DB3<num, String>.new; // Ok.
B<num> Function() test19() => DB3<num, String>.foo; // Ok.
B<num> Function() test20() => DB3<num, String>.bar; // Ok.
B<num> Function() test21() => DB3.new; // Ok.
B<Y> Function<Y extends num, Z extends String>() test22() => DB2.new; // Ok.
B<Y> Function<Y, Z>() test23() => DB2.new; // Error.
B<Y> Function<Y extends num, Z extends String>() test22() => DB3.new; // Ok.
B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
B<String> Function() test24() => DB2.new; // Ok.
main() {}

View file

@ -15,24 +15,24 @@ library /*isNonNullableByDefault*/;
// B<num> Function() test9() => DB1.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:41:44: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y extends num>() test16() => DB2.new; // Ok.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y>() test17() => DB2.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:48:62: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num, Z extends String>()'.
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y extends num, Z extends String>() test22() => DB2.new; // Ok.
// ^
// B<Y> Function<Y>() test17() => DB2.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y, Z>() test23() => DB2.new; // Error.
// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
// ^
//
import self as self;
@ -63,9 +63,9 @@ static method test1() → () → self::A
static method test2() → () → self::A
return self::A::•;
static method test3() → () → self::A
return self::A::•;
return <unrelated X extends core::num>.(self::A::•)<core::num>;
static method test4() → () → self::A
return self::A::•;
return <unrelated X extends core::num>.(self::A::•)<core::num>;
static method test5() → () → self::A
return self::A::•;
static method test6() → () → self::A
@ -90,17 +90,17 @@ static method test13() → () → self::B<core::num>
static method test14() → () → self::B<core::num>
return self::B::bar<core::num>;
static method test15() → () → self::B<core::num>
return self::B::•<core::num>;
return <X extends core::num>.(self::B::•<X>)<core::num>;
static method test16() → <Y extends core::num = dynamic>() → self::B<Y>
return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:41:44: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y extends num>() test16() => DB2.new; // Ok.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::num = dynamic>() → self::B<Y>;
return <X extends core::num>.(self::B::•<X>);
static method test17() → <Y extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y>() test17() => DB2.new; // Error.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
^" in (let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y>() test17() => DB2.new; // Error.
^" in (<X extends core::num>.(self::B::•<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
static method test18() → () → self::B<core::num>
return self::B::•<core::num>;
static method test19() → () → self::B<core::num>
@ -108,15 +108,17 @@ static method test19() → () → self::B<core::num>
static method test20() → () → self::B<core::num>
return self::B::bar<core::num>;
static method test21() → () → self::B<core::num>
return self::B::•<core::num>;
return <X extends core::num, unrelated Y extends core::String>.(self::B::•<X>)<core::num, core::String>;
static method test22() → <Y extends core::num = dynamic, Z extends core::String = dynamic>() → self::B<Y>
return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:48:62: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num, Z extends String>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y extends num, Z extends String>() test22() => DB2.new; // Ok.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::num = dynamic, Z extends core::String = dynamic>() → self::B<Y>;
return <X extends core::num, unrelated Y extends core::String>.(self::B::•<X>);
static method test23() → <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y, Z>() test23() => DB2.new; // Error.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
^" in (let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
^" in (<X extends core::num, unrelated Y extends core::String>.(self::B::•<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
static method test24() → () → self::B<core::String>
return <X extends core::num>.(self::B::•<X>)<Never>;
static method main() → dynamic {}

View file

@ -15,24 +15,24 @@ library /*isNonNullableByDefault*/;
// B<num> Function() test9() => DB1.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:41:44: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y extends num>() test16() => DB2.new; // Ok.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y>() test17() => DB2.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:48:62: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num, Z extends String>()'.
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y extends num, Z extends String>() test22() => DB2.new; // Ok.
// ^
// B<Y> Function<Y>() test17() => DB2.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y, Z>() test23() => DB2.new; // Error.
// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
// ^
//
import self as self;
@ -63,9 +63,9 @@ static method test1() → () → self::A
static method test2() → () → self::A
return self::A::•;
static method test3() → () → self::A
return self::A::•;
return <unrelated X extends core::num>.(self::A::•)<core::num>;
static method test4() → () → self::A
return self::A::•;
return <unrelated X extends core::num>.(self::A::•)<core::num>;
static method test5() → () → self::A
return self::A::•;
static method test6() → () → self::A
@ -90,17 +90,17 @@ static method test13() → () → self::B<core::num>
static method test14() → () → self::B<core::num>
return self::B::bar<core::num>;
static method test15() → () → self::B<core::num>
return self::B::•<core::num>;
return <X extends core::num>.(self::B::•<X>)<core::num>;
static method test16() → <Y extends core::num = dynamic>() → self::B<Y>
return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:41:44: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y extends num>() test16() => DB2.new; // Ok.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::num = dynamic>() → self::B<Y>;
return <X extends core::num>.(self::B::•<X>);
static method test17() → <Y extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y>() test17() => DB2.new; // Error.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
^" in let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y>() test17() => DB2.new; // Error.
^" in (<X extends core::num>.(self::B::•<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
static method test18() → () → self::B<core::num>
return self::B::•<core::num>;
static method test19() → () → self::B<core::num>
@ -108,15 +108,17 @@ static method test19() → () → self::B<core::num>
static method test20() → () → self::B<core::num>
return self::B::bar<core::num>;
static method test21() → () → self::B<core::num>
return self::B::•<core::num>;
return <X extends core::num, unrelated Y extends core::String>.(self::B::•<X>)<core::num, core::String>;
static method test22() → <Y extends core::num = dynamic, Z extends core::String = dynamic>() → self::B<Y>
return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:48:62: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num, Z extends String>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y extends num, Z extends String>() test22() => DB2.new; // Ok.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::num = dynamic, Z extends core::String = dynamic>() → self::B<Y>;
return <X extends core::num, unrelated Y extends core::String>.(self::B::•<X>);
static method test23() → <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y, Z>() test23() => DB2.new; // Error.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
^" in let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
^" in (<X extends core::num, unrelated Y extends core::String>.(self::B::•<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
static method test24() → () → self::B<core::String>
return <X extends core::num>.(self::B::•<X>)<Never>;
static method main() → dynamic {}

View file

@ -30,6 +30,7 @@ B<num> Function() test18() => DB3<num, String>.new;
B<num> Function() test19() => DB3<num, String>.foo;
B<num> Function() test20() => DB3<num, String>.bar;
B<num> Function() test21() => DB3.new;
B<Y> Function<Y extends num, Z extends String>() test22() => DB2.new;
B<Y> Function<Y, Z>() test23() => DB2.new;
B<Y> Function<Y extends num, Z extends String>() test22() => DB3.new;
B<Y> Function<Y, Z>() test23() => DB3.new;
B<String> Function() test24() => DB2.new;
main() {}

View file

@ -15,24 +15,24 @@ library /*isNonNullableByDefault*/;
// B<num> Function() test9() => DB1.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:41:44: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y extends num>() test16() => DB2.new; // Ok.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y>() test17() => DB2.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:48:62: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num, Z extends String>()'.
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y extends num, Z extends String>() test22() => DB2.new; // Ok.
// ^
// B<Y> Function<Y>() test17() => DB2.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y, Z>() test23() => DB2.new; // Error.
// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
// ^
//
import self as self;
@ -63,9 +63,9 @@ static method test1() → () → self::A
static method test2() → () → self::A
return self::A::•;
static method test3() → () → self::A
return self::A::•;
return <unrelated X extends core::num>.(self::A::•)<core::num>;
static method test4() → () → self::A
return self::A::•;
return <unrelated X extends core::num>.(self::A::•)<core::num>;
static method test5() → () → self::A
return self::A::•;
static method test6() → () → self::A
@ -90,17 +90,17 @@ static method test13() → () → self::B<core::num>
static method test14() → () → self::B<core::num>
return self::B::bar<core::num>;
static method test15() → () → self::B<core::num>
return self::B::•<core::num>;
return <X extends core::num>.(self::B::•<X>)<core::num>;
static method test16() → <Y extends core::num = dynamic>() → self::B<Y>
return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:41:44: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y extends num>() test16() => DB2.new; // Ok.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::num = dynamic>() → self::B<Y>;
return <X extends core::num>.(self::B::•<X>);
static method test17() → <Y extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y>() test17() => DB2.new; // Error.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
^" in (let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y>() test17() => DB2.new; // Error.
^" in (<X extends core::num>.(self::B::•<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
static method test18() → () → self::B<core::num>
return self::B::•<core::num>;
static method test19() → () → self::B<core::num>
@ -108,15 +108,17 @@ static method test19() → () → self::B<core::num>
static method test20() → () → self::B<core::num>
return self::B::bar<core::num>;
static method test21() → () → self::B<core::num>
return self::B::•<core::num>;
return <X extends core::num, unrelated Y extends core::String>.(self::B::•<X>)<core::num, core::String>;
static method test22() → <Y extends core::num = dynamic, Z extends core::String = dynamic>() → self::B<Y>
return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:48:62: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num, Z extends String>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y extends num, Z extends String>() test22() => DB2.new; // Ok.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::num = dynamic, Z extends core::String = dynamic>() → self::B<Y>;
return <X extends core::num, unrelated Y extends core::String>.(self::B::•<X>);
static method test23() → <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y, Z>() test23() => DB2.new; // Error.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
^" in (let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
^" in (<X extends core::num, unrelated Y extends core::String>.(self::B::•<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
static method test24() → () → self::B<core::String>
return <X extends core::num>.(self::B::•<X>)<Never>;
static method main() → dynamic {}

View file

@ -65,5 +65,7 @@ static method test22() → <Y extends core::num = dynamic, Z extends core::Strin
;
static method test23() → <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>
;
static method test24() → () → self::B<core::String>
;
static method main() → dynamic
;

View file

@ -15,24 +15,24 @@ library /*isNonNullableByDefault*/;
// B<num> Function() test9() => DB1.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:41:44: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y extends num>() test16() => DB2.new; // Ok.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y>() test17() => DB2.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:48:62: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num, Z extends String>()'.
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y extends num, Z extends String>() test22() => DB2.new; // Ok.
// ^
// B<Y> Function<Y>() test17() => DB2.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y, Z>() test23() => DB2.new; // Error.
// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
// ^
//
// pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
// - 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
// B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
// ^
//
import self as self;
@ -63,9 +63,9 @@ static method test1() → () → self::A
static method test2() → () → self::A
return self::A::•;
static method test3() → () → self::A
return self::A::•;
return <unrelated X extends core::num>.(self::A::•)<core::num>;
static method test4() → () → self::A
return self::A::•;
return <unrelated X extends core::num>.(self::A::•)<core::num>;
static method test5() → () → self::A
return self::A::•;
static method test6() → () → self::A
@ -90,17 +90,17 @@ static method test13() → () → self::B<core::num>
static method test14() → () → self::B<core::num>
return self::B::bar<core::num>;
static method test15() → () → self::B<core::num>
return self::B::•<core::num>;
return <X extends core::num>.(self::B::•<X>)<core::num>;
static method test16() → <Y extends core::num = dynamic>() → self::B<Y>
return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:41:44: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y extends num>() test16() => DB2.new; // Ok.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::num = dynamic>() → self::B<Y>;
return <X extends core::num>.(self::B::•<X>);
static method test17() → <Y extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
return let final Never #t2 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be returned from a function with return type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y>() test17() => DB2.new; // Error.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
^" in let final Never #t3 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:42:32: Error: A value of type 'B<X> Function<X extends num>()' can't be assigned to a variable of type 'B<Y> Function<Y>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y>() test17() => DB2.new; // Error.
^" in (<X extends core::num>.(self::B::•<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic>() → self::B<Y%>;
static method test18() → () → self::B<core::num>
return self::B::•<core::num>;
static method test19() → () → self::B<core::num>
@ -108,15 +108,17 @@ static method test19() → () → self::B<core::num>
static method test20() → () → self::B<core::num>
return self::B::bar<core::num>;
static method test21() → () → self::B<core::num>
return self::B::•<core::num>;
return <X extends core::num, unrelated Y extends core::String>.(self::B::•<X>)<core::num, core::String>;
static method test22() → <Y extends core::num = dynamic, Z extends core::String = dynamic>() → self::B<Y>
return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:48:62: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y extends num, Z extends String>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y extends num, Z extends String>() test22() => DB2.new; // Ok.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::num = dynamic, Z extends core::String = dynamic>() → self::B<Y>;
return <X extends core::num, unrelated Y extends core::String>.(self::B::•<X>);
static method test23() → <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>
return let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<num> Function()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
return let final Never #t4 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be returned from a function with return type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y, Z>() test23() => DB2.new; // Error.
^" in (self::B::•<core::num>) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
^" in let final Never #t5 = invalid-expression "pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart:49:35: Error: A value of type 'B<X> Function<X extends num, Y extends String>()' can't be assigned to a variable of type 'B<Y> Function<Y, Z>()'.
- 'B' is from 'pkg/front_end/testcases/constructor_tearoffs/typedef_tearoffs.dart'.
B<Y> Function<Y, Z>() test23() => DB3.new; // Error.
^" in (<X extends core::num, unrelated Y extends core::String>.(self::B::•<X>)) as{TypeError,ForNonNullableByDefault} <Y extends core::Object? = dynamic, Z extends core::Object? = dynamic>() → self::B<Y%>;
static method test24() → () → self::B<core::String>
return <X extends core::num>.(self::B::•<X>)<Never>;
static method main() → dynamic {}

View file

@ -8729,9 +8729,11 @@ class TypedefTearOff extends Expression {
@override
void toTextInternal(AstPrinter printer) {
printer.writeExpression(expression);
printer.writeTypeParameters(typeParameters);
printer.write(".(");
printer.writeExpression(expression);
printer.writeTypeArguments(typeArguments);
printer.write(")");
}
}

View file

@ -1615,9 +1615,11 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
@override
void visitTypedefTearOff(TypedefTearOff node) {
writeByte(Tag.TypedefTearOff);
enterScope(typeParameters: node.typeParameters);
writeNodeList(node.typeParameters);
writeNode(node.expression);
writeNodeList(node.typeArguments);
leaveScope(typeParameters: node.typeParameters);
}
@override

View file

@ -2055,6 +2055,20 @@ class Printer extends Visitor<void> with VisitorVoidMixin {
writeMemberReferenceFromReference(node.constructorReference);
}
visitTypedefTearOff(TypedefTearOff node) {
writeTypeParameterList(node.typeParameters);
state = SYMBOL;
writeSymbol('.(');
writeNode(node.expression);
if (node.typeArguments.isNotEmpty) {
writeSymbol('<');
writeList(node.typeArguments, writeType);
writeSymbol('>');
}
writeSymbol(')');
state = WORD;
}
visitExpressionStatement(ExpressionStatement node) {
writeIndentation();
writeExpression(node.expression);

View file

@ -635,6 +635,13 @@ class VerifyingVisitor extends RecursiveResultVisitor<void> {
}
}
@override
void visitTypedefTearOff(TypedefTearOff node) {
declareTypeParameters(node.typeParameters);
super.visitTypedefTearOff(node);
undeclareTypeParameters(node.typeParameters);
}
void checkTargetedInvocation(Member target, InvocationExpression node) {
visitChildren(node);
// ignore: unnecessary_null_comparison