diff --git a/pkg/front_end/lib/src/fasta/builder/nullability_builder.dart b/pkg/front_end/lib/src/fasta/builder/nullability_builder.dart index 54a2786e653..4d7b983d819 100644 --- a/pkg/front_end/lib/src/fasta/builder/nullability_builder.dart +++ b/pkg/front_end/lib/src/fasta/builder/nullability_builder.dart @@ -35,6 +35,8 @@ class NullabilityBuilder { const NullabilityBuilder.omitted() : _syntacticNullability = SyntacticNullability.omitted; + bool get isOmitted => _syntacticNullability == SyntacticNullability.omitted; + factory NullabilityBuilder.fromNullability(Nullability nullability) { switch (nullability) { case Nullability.nullable: @@ -47,13 +49,10 @@ class NullabilityBuilder { } } - Nullability build(LibraryBuilder libraryBuilder, {Nullability ifOmitted}) { - // TODO(dmitryas): Ensure that either ifOmitted is set or libraryBuilder is - // provided; - //assert(libraryBuilder != null || ifOmitted != null); - ifOmitted ??= (libraryBuilder == null ? Nullability.legacy : null); + Nullability build(LibraryBuilder libraryBuilder) { + assert(libraryBuilder != null); - ifOmitted ??= libraryBuilder.isNonNullableByDefault + Nullability ifOmitted = libraryBuilder.isNonNullableByDefault ? Nullability.nonNullable : Nullability.legacy; switch (_syntacticNullability) { diff --git a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart index 8ec76cbce8b..b73ea200f26 100644 --- a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart +++ b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart @@ -89,16 +89,22 @@ class TypeVariableBuilder extends TypeDeclarationBuilderImpl { } // If the bound is not set yet, the actual value is not important yet as it // will be set later. - Nullability nullabilityIfOmitted = parameter.bound != null && - library != null && - library.isNonNullableByDefault - ? TypeParameterType.computeNullabilityFromBound(parameter) - : Nullability.legacy; - DartType type = buildTypesWithBuiltArguments( - library, - nullabilityBuilder.build(library, ifOmitted: nullabilityIfOmitted), - null); - if (parameter.bound == null) { + bool needsPostUpdate = false; + Nullability nullability; + if (nullabilityBuilder.isOmitted) { + if (parameter.bound != null) { + nullability = library.isNonNullableByDefault + ? TypeParameterType.computeNullabilityFromBound(parameter) + : Nullability.legacy; + } else { + nullability = Nullability.legacy; + needsPostUpdate = true; + } + } else { + nullability = nullabilityBuilder.build(library); + } + DartType type = buildTypesWithBuiltArguments(library, nullability, null); + if (needsPostUpdate) { if (library is SourceLibraryBuilder) { library.pendingNullabilities.add(type); } else { diff --git a/pkg/front_end/testcases/nnbd/issue42143.dart b/pkg/front_end/testcases/nnbd/issue42143.dart new file mode 100644 index 00000000000..a711b13e8cc --- /dev/null +++ b/pkg/front_end/testcases/nnbd/issue42143.dart @@ -0,0 +1,6 @@ +import 'dart:async'; + +void h1?>(T? t) {} +void h2>(S? s) {} + +main() {} diff --git a/pkg/front_end/testcases/nnbd/issue42143.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue42143.dart.outline.expect new file mode 100644 index 00000000000..a3735a10ef5 --- /dev/null +++ b/pkg/front_end/testcases/nnbd/issue42143.dart.outline.expect @@ -0,0 +1,11 @@ +library /*isNonNullableByDefault*/; +import self as self; + +import "dart:async"; + +static method h1? = FutureOr?>(self::h1::T? t) → void + ; +static method h2 = FutureOr>(self::h2::S? s) → void + ; +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/nnbd/issue42143.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42143.dart.strong.expect new file mode 100644 index 00000000000..dd9388c37d7 --- /dev/null +++ b/pkg/front_end/testcases/nnbd/issue42143.dart.strong.expect @@ -0,0 +1,8 @@ +library /*isNonNullableByDefault*/; +import self as self; + +import "dart:async"; + +static method h1? = FutureOr?>(self::h1::T? t) → void {} +static method h2 = FutureOr>(self::h2::S? s) → void {} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/issue42143.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42143.dart.strong.transformed.expect new file mode 100644 index 00000000000..dd9388c37d7 --- /dev/null +++ b/pkg/front_end/testcases/nnbd/issue42143.dart.strong.transformed.expect @@ -0,0 +1,8 @@ +library /*isNonNullableByDefault*/; +import self as self; + +import "dart:async"; + +static method h1? = FutureOr?>(self::h1::T? t) → void {} +static method h2 = FutureOr>(self::h2::S? s) → void {} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/issue42143.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue42143.dart.textual_outline.expect new file mode 100644 index 00000000000..ea78e4726a5 --- /dev/null +++ b/pkg/front_end/testcases/nnbd/issue42143.dart.textual_outline.expect @@ -0,0 +1,5 @@ +import 'dart:async'; + +void h1?>(T? t) {} +void h2>(S? s) {} +main() {} diff --git a/pkg/front_end/testcases/nnbd/issue42143.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue42143.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..993350a05b7 --- /dev/null +++ b/pkg/front_end/testcases/nnbd/issue42143.dart.textual_outline_modelled.expect @@ -0,0 +1,5 @@ +import 'dart:async'; + +main() {} +void h1?>(T? t) {} +void h2>(S? s) {} diff --git a/pkg/front_end/testcases/nnbd/issue42143.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42143.dart.weak.expect new file mode 100644 index 00000000000..dd9388c37d7 --- /dev/null +++ b/pkg/front_end/testcases/nnbd/issue42143.dart.weak.expect @@ -0,0 +1,8 @@ +library /*isNonNullableByDefault*/; +import self as self; + +import "dart:async"; + +static method h1? = FutureOr?>(self::h1::T? t) → void {} +static method h2 = FutureOr>(self::h2::S? s) → void {} +static method main() → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/issue42143.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42143.dart.weak.transformed.expect new file mode 100644 index 00000000000..dd9388c37d7 --- /dev/null +++ b/pkg/front_end/testcases/nnbd/issue42143.dart.weak.transformed.expect @@ -0,0 +1,8 @@ +library /*isNonNullableByDefault*/; +import self as self; + +import "dart:async"; + +static method h1? = FutureOr?>(self::h1::T? t) → void {} +static method h2 = FutureOr>(self::h2::S? s) → void {} +static method main() → dynamic {}