Skip to content

Commit 261e283

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[cfe] Handle explicit type parameter type nullability in bounds
Closes #42143 Change-Id: I05f181889481c48b183cef135f96dbf510ca788d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151381 Reviewed-by: Dmitry Stefantsov <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent 21222b6 commit 261e283

10 files changed

+80
-16
lines changed

pkg/front_end/lib/src/fasta/builder/nullability_builder.dart

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class NullabilityBuilder {
3535
const NullabilityBuilder.omitted()
3636
: _syntacticNullability = SyntacticNullability.omitted;
3737

38+
bool get isOmitted => _syntacticNullability == SyntacticNullability.omitted;
39+
3840
factory NullabilityBuilder.fromNullability(Nullability nullability) {
3941
switch (nullability) {
4042
case Nullability.nullable:
@@ -47,13 +49,10 @@ class NullabilityBuilder {
4749
}
4850
}
4951

50-
Nullability build(LibraryBuilder libraryBuilder, {Nullability ifOmitted}) {
51-
// TODO(dmitryas): Ensure that either ifOmitted is set or libraryBuilder is
52-
// provided;
53-
//assert(libraryBuilder != null || ifOmitted != null);
54-
ifOmitted ??= (libraryBuilder == null ? Nullability.legacy : null);
52+
Nullability build(LibraryBuilder libraryBuilder) {
53+
assert(libraryBuilder != null);
5554

56-
ifOmitted ??= libraryBuilder.isNonNullableByDefault
55+
Nullability ifOmitted = libraryBuilder.isNonNullableByDefault
5756
? Nullability.nonNullable
5857
: Nullability.legacy;
5958
switch (_syntacticNullability) {

pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,22 @@ class TypeVariableBuilder extends TypeDeclarationBuilderImpl {
8989
}
9090
// If the bound is not set yet, the actual value is not important yet as it
9191
// will be set later.
92-
Nullability nullabilityIfOmitted = parameter.bound != null &&
93-
library != null &&
94-
library.isNonNullableByDefault
95-
? TypeParameterType.computeNullabilityFromBound(parameter)
96-
: Nullability.legacy;
97-
DartType type = buildTypesWithBuiltArguments(
98-
library,
99-
nullabilityBuilder.build(library, ifOmitted: nullabilityIfOmitted),
100-
null);
101-
if (parameter.bound == null) {
92+
bool needsPostUpdate = false;
93+
Nullability nullability;
94+
if (nullabilityBuilder.isOmitted) {
95+
if (parameter.bound != null) {
96+
nullability = library.isNonNullableByDefault
97+
? TypeParameterType.computeNullabilityFromBound(parameter)
98+
: Nullability.legacy;
99+
} else {
100+
nullability = Nullability.legacy;
101+
needsPostUpdate = true;
102+
}
103+
} else {
104+
nullability = nullabilityBuilder.build(library);
105+
}
106+
DartType type = buildTypesWithBuiltArguments(library, nullability, null);
107+
if (needsPostUpdate) {
102108
if (library is SourceLibraryBuilder) {
103109
library.pendingNullabilities.add(type);
104110
} else {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import 'dart:async';
2+
3+
void h1<T extends FutureOr<T?>?>(T? t) {}
4+
void h2<S extends FutureOr<S?>>(S? s) {}
5+
6+
main() {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
4+
import "dart:async";
5+
6+
static method h1<T extends FutureOr<self::h1::T?>? = FutureOr<dynamic>?>(self::h1::T? t) → void
7+
;
8+
static method h2<S extends FutureOr<self::h2::S?> = FutureOr<dynamic>>(self::h2::S? s) → void
9+
;
10+
static method main() → dynamic
11+
;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
4+
import "dart:async";
5+
6+
static method h1<T extends FutureOr<self::h1::T?>? = FutureOr<dynamic>?>(self::h1::T? t) → void {}
7+
static method h2<S extends FutureOr<self::h2::S?> = FutureOr<dynamic>>(self::h2::S? s) → void {}
8+
static method main() → dynamic {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
4+
import "dart:async";
5+
6+
static method h1<T extends FutureOr<self::h1::T?>? = FutureOr<dynamic>?>(self::h1::T? t) → void {}
7+
static method h2<S extends FutureOr<self::h2::S?> = FutureOr<dynamic>>(self::h2::S? s) → void {}
8+
static method main() → dynamic {}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import 'dart:async';
2+
3+
void h1<T extends FutureOr<T?>?>(T? t) {}
4+
void h2<S extends FutureOr<S?>>(S? s) {}
5+
main() {}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import 'dart:async';
2+
3+
main() {}
4+
void h1<T extends FutureOr<T?>?>(T? t) {}
5+
void h2<S extends FutureOr<S?>>(S? s) {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
4+
import "dart:async";
5+
6+
static method h1<T extends FutureOr<self::h1::T?>? = FutureOr<dynamic>?>(self::h1::T? t) → void {}
7+
static method h2<S extends FutureOr<self::h2::S?> = FutureOr<dynamic>>(self::h2::S? s) → void {}
8+
static method main() → dynamic {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
4+
import "dart:async";
5+
6+
static method h1<T extends FutureOr<self::h1::T?>? = FutureOr<dynamic>?>(self::h1::T? t) → void {}
7+
static method h2<S extends FutureOr<self::h2::S?> = FutureOr<dynamic>>(self::h2::S? s) → void {}
8+
static method main() → dynamic {}

0 commit comments

Comments
 (0)