Skip to content

Commit cf8887b

Browse files
Dmitry Stefantsovcommit-bot@chromium.org
Dmitry Stefantsov
authored andcommitted
[cfe] Update the conversion algorithm for checking super-bounded types
The update is specified in the following: dart-lang/language#1133 Change-Id: I2850b1acf7c94b8174c21cf899c9b926a03d9cc8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175726 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Dmitry Stefantsov <[email protected]>
1 parent 35e23fb commit cf8887b

9 files changed

+237
-126
lines changed

pkg/front_end/lib/src/fasta/source/source_class_builder.dart

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -427,9 +427,6 @@ class SourceClassBuilder extends ClassBuilderImpl
427427
Supertype supertype, TypeEnvironment typeEnvironment) {
428428
SourceLibraryBuilder libraryBuilder = this.library;
429429
Library library = libraryBuilder.library;
430-
final DartType bottomType = library.isNonNullableByDefault
431-
? const NeverType(Nullability.nonNullable)
432-
: const NullType();
433430

434431
Set<TypeArgumentIssue> issues = {};
435432
issues.addAll(findTypeArgumentIssues(
@@ -438,7 +435,6 @@ class SourceClassBuilder extends ClassBuilderImpl
438435
supertype.typeArguments),
439436
typeEnvironment,
440437
SubtypeCheckMode.ignoringNullabilities,
441-
bottomType,
442438
allowSuperBounded: false) ??
443439
const []);
444440
if (library.isNonNullableByDefault) {
@@ -448,15 +444,14 @@ class SourceClassBuilder extends ClassBuilderImpl
448444
supertype.typeArguments),
449445
typeEnvironment,
450446
SubtypeCheckMode.withNullabilities,
451-
bottomType,
452447
allowSuperBounded: false) ??
453448
const []);
454449
}
455450
for (TypeArgumentIssue issue in issues) {
456451
DartType argument = issue.argument;
457452
TypeParameter typeParameter = issue.typeParameter;
458453
bool inferred = libraryBuilder.inferredTypes.contains(argument);
459-
if (argument is FunctionType && argument.typeParameters.length > 0) {
454+
if (isGenericFunctionTypeOrAlias(argument)) {
460455
if (inferred) {
461456
libraryBuilder.reportTypeArgumentIssue(
462457
templateGenericFunctionTypeInferredAsActualTypeArgument

pkg/front_end/lib/src/fasta/source/source_library_builder.dart

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import 'package:kernel/ast.dart'
2929
Extension,
3030
Field,
3131
FunctionNode,
32-
FunctionType,
3332
InterfaceType,
3433
InvalidType,
3534
Library,
@@ -69,7 +68,8 @@ import 'package:kernel/src/bounds_checks.dart'
6968
TypeArgumentIssue,
7069
findTypeArgumentIssues,
7170
findTypeArgumentIssuesForInvocation,
72-
getGenericTypeName;
71+
getGenericTypeName,
72+
isGenericFunctionTypeOrAlias;
7373

7474
import 'package:kernel/type_algebra.dart' show Substitution, substitute;
7575

@@ -3236,7 +3236,7 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
32363236
inferredTypes.contains(argument);
32373237
offset =
32383238
typeArgumentsInfo?.getOffsetForIndex(issue.index, offset) ?? offset;
3239-
if (argument is FunctionType && argument.typeParameters.length > 0) {
3239+
if (isGenericFunctionTypeOrAlias(argument)) {
32403240
if (issueInferred) {
32413241
message = templateGenericFunctionTypeInferredAsActualTypeArgument
32423242
.withArguments(argument, isNonNullableByDefault);
@@ -3359,24 +3359,16 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
33593359

33603360
void checkBoundsInTypeParameters(TypeEnvironment typeEnvironment,
33613361
List<TypeParameter> typeParameters, Uri fileUri) {
3362-
final DartType bottomType = library.isNonNullableByDefault
3363-
? const NeverType(Nullability.nonNullable)
3364-
: const NullType();
3365-
33663362
// Check in bounds of own type variables.
33673363
for (TypeParameter parameter in typeParameters) {
33683364
Set<TypeArgumentIssue> issues = {};
3369-
issues.addAll(findTypeArgumentIssues(
3370-
library,
3371-
parameter.bound,
3372-
typeEnvironment,
3373-
SubtypeCheckMode.ignoringNullabilities,
3374-
bottomType,
3365+
issues.addAll(findTypeArgumentIssues(library, parameter.bound,
3366+
typeEnvironment, SubtypeCheckMode.ignoringNullabilities,
33753367
allowSuperBounded: true) ??
33763368
const []);
33773369
if (library.isNonNullableByDefault) {
33783370
issues.addAll(findTypeArgumentIssues(library, parameter.bound,
3379-
typeEnvironment, SubtypeCheckMode.withNullabilities, bottomType,
3371+
typeEnvironment, SubtypeCheckMode.withNullabilities,
33803372
allowSuperBounded: true) ??
33813373
const []);
33823374
}
@@ -3392,7 +3384,7 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
33923384
continue;
33933385
}
33943386

3395-
if (argument is FunctionType && argument.typeParameters.length > 0) {
3387+
if (isGenericFunctionTypeOrAlias(argument)) {
33963388
reportTypeArgumentIssue(
33973389
messageGenericFunctionTypeUsedAsActualTypeArgument,
33983390
fileUri,
@@ -3446,17 +3438,14 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
34463438
}
34473439
}
34483440
if (!skipReturnType && returnType != null) {
3449-
final DartType bottomType = isNonNullableByDefault
3450-
? const NeverType(Nullability.nonNullable)
3451-
: const NullType();
34523441
Set<TypeArgumentIssue> issues = {};
34533442
issues.addAll(findTypeArgumentIssues(library, returnType, typeEnvironment,
3454-
SubtypeCheckMode.ignoringNullabilities, bottomType,
3443+
SubtypeCheckMode.ignoringNullabilities,
34553444
allowSuperBounded: true) ??
34563445
const []);
34573446
if (isNonNullableByDefault) {
34583447
issues.addAll(findTypeArgumentIssues(library, returnType,
3459-
typeEnvironment, SubtypeCheckMode.withNullabilities, bottomType,
3448+
typeEnvironment, SubtypeCheckMode.withNullabilities,
34603449
allowSuperBounded: true) ??
34613450
const []);
34623451
}
@@ -3467,7 +3456,7 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
34673456
// We don't need to check if [argument] was inferred or specified
34683457
// here, because inference in return types boils down to instantiate-
34693458
// -to-bound, and it can't provide a type that violates the bound.
3470-
if (argument is FunctionType && argument.typeParameters.length > 0) {
3459+
if (isGenericFunctionTypeOrAlias(argument)) {
34713460
reportTypeArgumentIssue(
34723461
messageGenericFunctionTypeUsedAsActualTypeArgument,
34733462
fileUri,
@@ -3558,17 +3547,14 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
35583547
void checkBoundsInType(
35593548
DartType type, TypeEnvironment typeEnvironment, Uri fileUri, int offset,
35603549
{bool inferred, bool allowSuperBounded = true}) {
3561-
final DartType bottomType = isNonNullableByDefault
3562-
? const NeverType(Nullability.nonNullable)
3563-
: const NullType();
35643550
Set<TypeArgumentIssue> issues = {};
35653551
issues.addAll(findTypeArgumentIssues(library, type, typeEnvironment,
3566-
SubtypeCheckMode.ignoringNullabilities, bottomType,
3552+
SubtypeCheckMode.ignoringNullabilities,
35673553
allowSuperBounded: allowSuperBounded) ??
35683554
const []);
35693555
if (isNonNullableByDefault) {
35703556
issues.addAll(findTypeArgumentIssues(library, type, typeEnvironment,
3571-
SubtypeCheckMode.withNullabilities, bottomType,
3557+
SubtypeCheckMode.withNullabilities,
35723558
allowSuperBounded: allowSuperBounded) ??
35733559
const []);
35743560
}

pkg/front_end/test/spell_checking_list_common.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,6 +1213,7 @@ flatten
12131213
flattened
12141214
flexibility
12151215
flexible
1216+
flip
12161217
float
12171218
flow
12181219
flow's

pkg/front_end/testcases/nnbd/issue42429.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,16 @@ foo() {
3030
FNowhere<num?> fNowhereNumNullable; // Error.
3131
FNowhere<int?> fNowhereIntNullable; // Error.
3232
FNowhere<Null> fNowhereNull; // Error.
33+
FArgument<Object?> fArgumentObjectNullable; // Error.
34+
FArgument<dynamic> fArgumentDynamic; // Error.
35+
FArgument<void> fArgumentVoid; // Error.
3336

3437
A<Object?> aObjectNullable; // Ok.
3538
A<dynamic> aDynamic; // Ok.
3639
A<void> aVoid; // Ok.
3740
A<num> aNum; // Ok.
3841
A<int> aInt; // Ok.
3942
A<Never> aNever; // Ok.
40-
FArgument<Object?> fArgumentObjectNullable; // Ok.
41-
FArgument<dynamic> fArgumentDynamic; // Ok.
42-
FArgument<void> fArgumentVoid; // Ok.
4343
FArgument<num> fArgumentNum; // Ok.
4444
FArgument<int> fArgumentInt; // Ok.
4545
FArgument<Never> fArgumentNever; // Ok.

pkg/front_end/testcases/nnbd/issue42429.dart.strong.expect

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,31 @@ library /*isNonNullableByDefault*/;
167167
// typedef FNowhere<X extends num> = Function();
168168
// ^
169169
//
170+
// pkg/front_end/testcases/nnbd/issue42429.dart:33:22: Error: Type argument 'Object?' doesn't conform to the bound 'num' of the type variable 'X' on 'FArgument'.
171+
// - 'Object' is from 'dart:core'.
172+
// Try changing type arguments so that they conform to the bounds.
173+
// FArgument<Object?> fArgumentObjectNullable; // Error.
174+
// ^
175+
// pkg/front_end/testcases/nnbd/issue42429.dart:7:19: Context: This is the type variable whose bound isn't conformed to.
176+
// typedef FArgument<X extends num> = Function(X);
177+
// ^
178+
//
179+
// pkg/front_end/testcases/nnbd/issue42429.dart:34:22: Error: Type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'X' on 'FArgument'.
180+
// Try changing type arguments so that they conform to the bounds.
181+
// FArgument<dynamic> fArgumentDynamic; // Error.
182+
// ^
183+
// pkg/front_end/testcases/nnbd/issue42429.dart:7:19: Context: This is the type variable whose bound isn't conformed to.
184+
// typedef FArgument<X extends num> = Function(X);
185+
// ^
186+
//
187+
// pkg/front_end/testcases/nnbd/issue42429.dart:35:19: Error: Type argument 'void' doesn't conform to the bound 'num' of the type variable 'X' on 'FArgument'.
188+
// Try changing type arguments so that they conform to the bounds.
189+
// FArgument<void> fArgumentVoid; // Error.
190+
// ^
191+
// pkg/front_end/testcases/nnbd/issue42429.dart:7:19: Context: This is the type variable whose bound isn't conformed to.
192+
// typedef FArgument<X extends num> = Function(X);
193+
// ^
194+
//
170195
import self as self;
171196
import "dart:core" as core;
172197

@@ -200,15 +225,15 @@ static method foo() → dynamic {
200225
() → dynamic fNowhereNumNullable;
201226
() → dynamic fNowhereIntNullable;
202227
() → dynamic fNowhereNull;
228+
(core::Object?) → dynamic fArgumentObjectNullable;
229+
(dynamic) → dynamic fArgumentDynamic;
230+
(void) → dynamic fArgumentVoid;
203231
self::A<core::Object?> aObjectNullable;
204232
self::A<dynamic> aDynamic;
205233
self::A<void> aVoid;
206234
self::A<core::num> aNum;
207235
self::A<core::int> aInt;
208236
self::A<Never> aNever;
209-
(core::Object?) → dynamic fArgumentObjectNullable;
210-
(dynamic) → dynamic fArgumentDynamic;
211-
(void) → dynamic fArgumentVoid;
212237
(core::num) → dynamic fArgumentNum;
213238
(core::int) → dynamic fArgumentInt;
214239
(Never) → dynamic fArgumentNever;

pkg/front_end/testcases/nnbd/issue42429.dart.strong.transformed.expect

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,31 @@ library /*isNonNullableByDefault*/;
167167
// typedef FNowhere<X extends num> = Function();
168168
// ^
169169
//
170+
// pkg/front_end/testcases/nnbd/issue42429.dart:33:22: Error: Type argument 'Object?' doesn't conform to the bound 'num' of the type variable 'X' on 'FArgument'.
171+
// - 'Object' is from 'dart:core'.
172+
// Try changing type arguments so that they conform to the bounds.
173+
// FArgument<Object?> fArgumentObjectNullable; // Error.
174+
// ^
175+
// pkg/front_end/testcases/nnbd/issue42429.dart:7:19: Context: This is the type variable whose bound isn't conformed to.
176+
// typedef FArgument<X extends num> = Function(X);
177+
// ^
178+
//
179+
// pkg/front_end/testcases/nnbd/issue42429.dart:34:22: Error: Type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'X' on 'FArgument'.
180+
// Try changing type arguments so that they conform to the bounds.
181+
// FArgument<dynamic> fArgumentDynamic; // Error.
182+
// ^
183+
// pkg/front_end/testcases/nnbd/issue42429.dart:7:19: Context: This is the type variable whose bound isn't conformed to.
184+
// typedef FArgument<X extends num> = Function(X);
185+
// ^
186+
//
187+
// pkg/front_end/testcases/nnbd/issue42429.dart:35:19: Error: Type argument 'void' doesn't conform to the bound 'num' of the type variable 'X' on 'FArgument'.
188+
// Try changing type arguments so that they conform to the bounds.
189+
// FArgument<void> fArgumentVoid; // Error.
190+
// ^
191+
// pkg/front_end/testcases/nnbd/issue42429.dart:7:19: Context: This is the type variable whose bound isn't conformed to.
192+
// typedef FArgument<X extends num> = Function(X);
193+
// ^
194+
//
170195
import self as self;
171196
import "dart:core" as core;
172197

@@ -200,15 +225,15 @@ static method foo() → dynamic {
200225
() → dynamic fNowhereNumNullable;
201226
() → dynamic fNowhereIntNullable;
202227
() → dynamic fNowhereNull;
228+
(core::Object?) → dynamic fArgumentObjectNullable;
229+
(dynamic) → dynamic fArgumentDynamic;
230+
(void) → dynamic fArgumentVoid;
203231
self::A<core::Object?> aObjectNullable;
204232
self::A<dynamic> aDynamic;
205233
self::A<void> aVoid;
206234
self::A<core::num> aNum;
207235
self::A<core::int> aInt;
208236
self::A<Never> aNever;
209-
(core::Object?) → dynamic fArgumentObjectNullable;
210-
(dynamic) → dynamic fArgumentDynamic;
211-
(void) → dynamic fArgumentVoid;
212237
(core::num) → dynamic fArgumentNum;
213238
(core::int) → dynamic fArgumentInt;
214239
(Never) → dynamic fArgumentNever;

pkg/front_end/testcases/nnbd/issue42429.dart.weak.expect

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,31 @@ library /*isNonNullableByDefault*/;
167167
// typedef FNowhere<X extends num> = Function();
168168
// ^
169169
//
170+
// pkg/front_end/testcases/nnbd/issue42429.dart:33:22: Error: Type argument 'Object?' doesn't conform to the bound 'num' of the type variable 'X' on 'FArgument'.
171+
// - 'Object' is from 'dart:core'.
172+
// Try changing type arguments so that they conform to the bounds.
173+
// FArgument<Object?> fArgumentObjectNullable; // Error.
174+
// ^
175+
// pkg/front_end/testcases/nnbd/issue42429.dart:7:19: Context: This is the type variable whose bound isn't conformed to.
176+
// typedef FArgument<X extends num> = Function(X);
177+
// ^
178+
//
179+
// pkg/front_end/testcases/nnbd/issue42429.dart:34:22: Error: Type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'X' on 'FArgument'.
180+
// Try changing type arguments so that they conform to the bounds.
181+
// FArgument<dynamic> fArgumentDynamic; // Error.
182+
// ^
183+
// pkg/front_end/testcases/nnbd/issue42429.dart:7:19: Context: This is the type variable whose bound isn't conformed to.
184+
// typedef FArgument<X extends num> = Function(X);
185+
// ^
186+
//
187+
// pkg/front_end/testcases/nnbd/issue42429.dart:35:19: Error: Type argument 'void' doesn't conform to the bound 'num' of the type variable 'X' on 'FArgument'.
188+
// Try changing type arguments so that they conform to the bounds.
189+
// FArgument<void> fArgumentVoid; // Error.
190+
// ^
191+
// pkg/front_end/testcases/nnbd/issue42429.dart:7:19: Context: This is the type variable whose bound isn't conformed to.
192+
// typedef FArgument<X extends num> = Function(X);
193+
// ^
194+
//
170195
import self as self;
171196
import "dart:core" as core;
172197

@@ -200,15 +225,15 @@ static method foo() → dynamic {
200225
() → dynamic fNowhereNumNullable;
201226
() → dynamic fNowhereIntNullable;
202227
() → dynamic fNowhereNull;
228+
(core::Object?) → dynamic fArgumentObjectNullable;
229+
(dynamic) → dynamic fArgumentDynamic;
230+
(void) → dynamic fArgumentVoid;
203231
self::A<core::Object?> aObjectNullable;
204232
self::A<dynamic> aDynamic;
205233
self::A<void> aVoid;
206234
self::A<core::num> aNum;
207235
self::A<core::int> aInt;
208236
self::A<Never> aNever;
209-
(core::Object?) → dynamic fArgumentObjectNullable;
210-
(dynamic) → dynamic fArgumentDynamic;
211-
(void) → dynamic fArgumentVoid;
212237
(core::num) → dynamic fArgumentNum;
213238
(core::int) → dynamic fArgumentInt;
214239
(Never) → dynamic fArgumentNever;

pkg/front_end/testcases/nnbd/issue42429.dart.weak.transformed.expect

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,31 @@ library /*isNonNullableByDefault*/;
167167
// typedef FNowhere<X extends num> = Function();
168168
// ^
169169
//
170+
// pkg/front_end/testcases/nnbd/issue42429.dart:33:22: Error: Type argument 'Object?' doesn't conform to the bound 'num' of the type variable 'X' on 'FArgument'.
171+
// - 'Object' is from 'dart:core'.
172+
// Try changing type arguments so that they conform to the bounds.
173+
// FArgument<Object?> fArgumentObjectNullable; // Error.
174+
// ^
175+
// pkg/front_end/testcases/nnbd/issue42429.dart:7:19: Context: This is the type variable whose bound isn't conformed to.
176+
// typedef FArgument<X extends num> = Function(X);
177+
// ^
178+
//
179+
// pkg/front_end/testcases/nnbd/issue42429.dart:34:22: Error: Type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'X' on 'FArgument'.
180+
// Try changing type arguments so that they conform to the bounds.
181+
// FArgument<dynamic> fArgumentDynamic; // Error.
182+
// ^
183+
// pkg/front_end/testcases/nnbd/issue42429.dart:7:19: Context: This is the type variable whose bound isn't conformed to.
184+
// typedef FArgument<X extends num> = Function(X);
185+
// ^
186+
//
187+
// pkg/front_end/testcases/nnbd/issue42429.dart:35:19: Error: Type argument 'void' doesn't conform to the bound 'num' of the type variable 'X' on 'FArgument'.
188+
// Try changing type arguments so that they conform to the bounds.
189+
// FArgument<void> fArgumentVoid; // Error.
190+
// ^
191+
// pkg/front_end/testcases/nnbd/issue42429.dart:7:19: Context: This is the type variable whose bound isn't conformed to.
192+
// typedef FArgument<X extends num> = Function(X);
193+
// ^
194+
//
170195
import self as self;
171196
import "dart:core" as core;
172197

@@ -200,15 +225,15 @@ static method foo() → dynamic {
200225
() → dynamic fNowhereNumNullable;
201226
() → dynamic fNowhereIntNullable;
202227
() → dynamic fNowhereNull;
228+
(core::Object?) → dynamic fArgumentObjectNullable;
229+
(dynamic) → dynamic fArgumentDynamic;
230+
(void) → dynamic fArgumentVoid;
203231
self::A<core::Object?> aObjectNullable;
204232
self::A<dynamic> aDynamic;
205233
self::A<void> aVoid;
206234
self::A<core::num> aNum;
207235
self::A<core::int> aInt;
208236
self::A<Never> aNever;
209-
(core::Object?) → dynamic fArgumentObjectNullable;
210-
(dynamic) → dynamic fArgumentDynamic;
211-
(void) → dynamic fArgumentVoid;
212237
(core::num) → dynamic fArgumentNum;
213238
(core::int) → dynamic fArgumentInt;
214239
(Never) → dynamic fArgumentNever;

0 commit comments

Comments
 (0)