Version 2.17.0-266.7.beta
* Cherry-pick 557089ea5d784b9664b3e896795e81e8c580912e to beta
* Cherry-pick 7d8d3bb8078a3f0ce9a2a41f2120ff7db75ce0df to beta
diff --git a/DEPS b/DEPS
index 7256708..5471a60 100644
--- a/DEPS
+++ b/DEPS
@@ -141,7 +141,7 @@
"pool_rev": "7abe634002a1ba8a0928eded086062f1307ccfae",
"process_rev": "56ece43b53b64c63ae51ec184b76bd5360c28d0b",
"protobuf_rev": "c1eb6cb51af39ccbaa1a8e19349546586a5c8e31",
- "pub_rev": "a3a102a549388a6dbfecc9252fabb618f9a2f5f7",
+ "pub_rev": "a949b329b1b51f5f3973a790e0a0a45897d837de",
"pub_semver_rev": "ea6c54019948dc03042c595ce9413e17aaf7aa38",
"root_certificates_rev": "692f6d6488af68e0121317a9c2c9eb393eb0ee50",
"rust_revision": "b7856f695d65a8ebc846754f97d15814bcb1c244",
diff --git a/pkg/front_end/testcases/nnbd/issue48631_1.dart b/pkg/front_end/testcases/nnbd/issue48631_1.dart
new file mode 100644
index 0000000..f995c3e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_1.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+FutureOr<T?> foo<T>(T t) {}
+
+bar<S>(bool t, S s) {
+ var x = [foo(s), s];
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue48631_1.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue48631_1.dart.strong.expect
new file mode 100644
index 0000000..a26757b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_1.dart.strong.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "dart:async";
+
+static method foo<T extends core::Object? = dynamic>(self::foo::T% t) → FutureOr<self::foo::T?> {}
+static method bar<S extends core::Object? = dynamic>(core::bool t, self::bar::S% s) → dynamic {
+ core::List<FutureOr<self::bar::S?>?> x = <FutureOr<self::bar::S?>?>[self::foo<self::bar::S%>(s), s];
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue48631_1.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue48631_1.dart.strong.transformed.expect
new file mode 100644
index 0000000..b425585
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_1.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "dart:async";
+
+static method foo<T extends core::Object? = dynamic>(self::foo::T% t) → FutureOr<self::foo::T?> {}
+static method bar<S extends core::Object? = dynamic>(core::bool t, self::bar::S% s) → dynamic {
+ core::List<FutureOr<self::bar::S?>?> x = core::_GrowableList::_literal2<FutureOr<self::bar::S?>?>(self::foo<self::bar::S%>(s), s);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue48631_1.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue48631_1.dart.textual_outline.expect
new file mode 100644
index 0000000..65faadd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_1.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'dart:async';
+
+FutureOr<T?> foo<T>(T t) {}
+bar<S>(bool t, S s) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue48631_1.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue48631_1.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..65faadd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_1.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'dart:async';
+
+FutureOr<T?> foo<T>(T t) {}
+bar<S>(bool t, S s) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue48631_1.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue48631_1.dart.weak.expect
new file mode 100644
index 0000000..a26757b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_1.dart.weak.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "dart:async";
+
+static method foo<T extends core::Object? = dynamic>(self::foo::T% t) → FutureOr<self::foo::T?> {}
+static method bar<S extends core::Object? = dynamic>(core::bool t, self::bar::S% s) → dynamic {
+ core::List<FutureOr<self::bar::S?>?> x = <FutureOr<self::bar::S?>?>[self::foo<self::bar::S%>(s), s];
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue48631_1.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue48631_1.dart.weak.modular.expect
new file mode 100644
index 0000000..a26757b
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_1.dart.weak.modular.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "dart:async";
+
+static method foo<T extends core::Object? = dynamic>(self::foo::T% t) → FutureOr<self::foo::T?> {}
+static method bar<S extends core::Object? = dynamic>(core::bool t, self::bar::S% s) → dynamic {
+ core::List<FutureOr<self::bar::S?>?> x = <FutureOr<self::bar::S?>?>[self::foo<self::bar::S%>(s), s];
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue48631_1.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/issue48631_1.dart.weak.outline.expect
new file mode 100644
index 0000000..f366279
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_1.dart.weak.outline.expect
@@ -0,0 +1,12 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "dart:async";
+
+static method foo<T extends core::Object? = dynamic>(self::foo::T% t) → FutureOr<self::foo::T?>
+ ;
+static method bar<S extends core::Object? = dynamic>(core::bool t, self::bar::S% s) → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/issue48631_1.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue48631_1.dart.weak.transformed.expect
new file mode 100644
index 0000000..b425585
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_1.dart.weak.transformed.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "dart:async";
+
+static method foo<T extends core::Object? = dynamic>(self::foo::T% t) → FutureOr<self::foo::T?> {}
+static method bar<S extends core::Object? = dynamic>(core::bool t, self::bar::S% s) → dynamic {
+ core::List<FutureOr<self::bar::S?>?> x = core::_GrowableList::_literal2<FutureOr<self::bar::S?>?>(self::foo<self::bar::S%>(s), s);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue48631_2.dart b/pkg/front_end/testcases/nnbd/issue48631_2.dart
new file mode 100644
index 0000000..2cf30ba
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_2.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+abstract class A {
+ T foo<T>(B<T> b);
+}
+
+class B<X> {
+ B(X x);
+}
+
+class C<Y> {
+ final Bar<FutureOr<Y>, D<Y>> bar;
+
+ C(this.bar);
+}
+
+abstract class D<W> implements A {}
+
+typedef Bar<V, U extends A> = V Function(U);
+
+final baz = C<int>((a) {
+ return a.foo(B(Future.value(0)));
+});
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue48631_2.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue48631_2.dart.strong.expect
new file mode 100644
index 0000000..e842794
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_2.dart.strong.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+typedef Bar<V extends core::Object? = dynamic, contravariant U extends self::A> = (U) → V%;
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ abstract method foo<T extends core::Object? = dynamic>(self::B<self::A::foo::T%> b) → self::A::foo::T%;
+}
+class B<X extends core::Object? = dynamic> extends core::Object {
+ constructor •(self::B::X% x) → self::B<self::B::X%>
+ : super core::Object::•()
+ ;
+}
+class C<Y extends core::Object? = dynamic> extends core::Object {
+ final field (self::D<self::C::Y%>) → FutureOr<self::C::Y%>% bar;
+ constructor •((self::D<self::C::Y%>) → FutureOr<self::C::Y%>% bar) → self::C<self::C::Y%>
+ : self::C::bar = bar, super core::Object::•()
+ ;
+}
+abstract class D<W extends core::Object? = dynamic> extends core::Object implements self::A {
+ synthetic constructor •() → self::D<self::D::W%>
+ : super core::Object::•()
+ ;
+}
+static final field self::C<core::int> baz = new self::C::•<core::int>((self::D<core::int> a) → FutureOr<core::int> {
+ return a.{self::A::foo}<FutureOr<core::int>>(new self::B::•<FutureOr<core::int>>(asy::Future::value<core::int>(0))){(self::B<FutureOr<core::int>>) → FutureOr<core::int>};
+});
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue48631_2.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue48631_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..e842794
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_2.dart.strong.transformed.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+typedef Bar<V extends core::Object? = dynamic, contravariant U extends self::A> = (U) → V%;
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ abstract method foo<T extends core::Object? = dynamic>(self::B<self::A::foo::T%> b) → self::A::foo::T%;
+}
+class B<X extends core::Object? = dynamic> extends core::Object {
+ constructor •(self::B::X% x) → self::B<self::B::X%>
+ : super core::Object::•()
+ ;
+}
+class C<Y extends core::Object? = dynamic> extends core::Object {
+ final field (self::D<self::C::Y%>) → FutureOr<self::C::Y%>% bar;
+ constructor •((self::D<self::C::Y%>) → FutureOr<self::C::Y%>% bar) → self::C<self::C::Y%>
+ : self::C::bar = bar, super core::Object::•()
+ ;
+}
+abstract class D<W extends core::Object? = dynamic> extends core::Object implements self::A {
+ synthetic constructor •() → self::D<self::D::W%>
+ : super core::Object::•()
+ ;
+}
+static final field self::C<core::int> baz = new self::C::•<core::int>((self::D<core::int> a) → FutureOr<core::int> {
+ return a.{self::A::foo}<FutureOr<core::int>>(new self::B::•<FutureOr<core::int>>(asy::Future::value<core::int>(0))){(self::B<FutureOr<core::int>>) → FutureOr<core::int>};
+});
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue48631_2.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue48631_2.dart.textual_outline.expect
new file mode 100644
index 0000000..a409162
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_2.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+import 'dart:async';
+
+abstract class A {
+ T foo<T>(B<T> b);
+}
+
+class B<X> {
+ B(X x);
+}
+
+class C<Y> {
+ final Bar<FutureOr<Y>, D<Y>> bar;
+ C(this.bar);
+}
+
+abstract class D<W> implements A {}
+
+typedef Bar<V, U extends A> = V Function(U);
+final baz = C<int>((a) {
+ return a.foo(B(Future.value(0)));
+});
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue48631_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue48631_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..bee82dc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+import 'dart:async';
+
+abstract class A {
+ T foo<T>(B<T> b);
+}
+
+abstract class D<W> implements A {}
+
+class B<X> {
+ B(X x);
+}
+
+class C<Y> {
+ C(this.bar);
+ final Bar<FutureOr<Y>, D<Y>> bar;
+}
+
+final baz = C<int>((a) {
+ return a.foo(B(Future.value(0)));
+});
+main() {}
+typedef Bar<V, U extends A> = V Function(U);
diff --git a/pkg/front_end/testcases/nnbd/issue48631_2.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue48631_2.dart.weak.expect
new file mode 100644
index 0000000..e842794
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_2.dart.weak.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+typedef Bar<V extends core::Object? = dynamic, contravariant U extends self::A> = (U) → V%;
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ abstract method foo<T extends core::Object? = dynamic>(self::B<self::A::foo::T%> b) → self::A::foo::T%;
+}
+class B<X extends core::Object? = dynamic> extends core::Object {
+ constructor •(self::B::X% x) → self::B<self::B::X%>
+ : super core::Object::•()
+ ;
+}
+class C<Y extends core::Object? = dynamic> extends core::Object {
+ final field (self::D<self::C::Y%>) → FutureOr<self::C::Y%>% bar;
+ constructor •((self::D<self::C::Y%>) → FutureOr<self::C::Y%>% bar) → self::C<self::C::Y%>
+ : self::C::bar = bar, super core::Object::•()
+ ;
+}
+abstract class D<W extends core::Object? = dynamic> extends core::Object implements self::A {
+ synthetic constructor •() → self::D<self::D::W%>
+ : super core::Object::•()
+ ;
+}
+static final field self::C<core::int> baz = new self::C::•<core::int>((self::D<core::int> a) → FutureOr<core::int> {
+ return a.{self::A::foo}<FutureOr<core::int>>(new self::B::•<FutureOr<core::int>>(asy::Future::value<core::int>(0))){(self::B<FutureOr<core::int>>) → FutureOr<core::int>};
+});
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue48631_2.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue48631_2.dart.weak.modular.expect
new file mode 100644
index 0000000..e842794
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_2.dart.weak.modular.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+typedef Bar<V extends core::Object? = dynamic, contravariant U extends self::A> = (U) → V%;
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ abstract method foo<T extends core::Object? = dynamic>(self::B<self::A::foo::T%> b) → self::A::foo::T%;
+}
+class B<X extends core::Object? = dynamic> extends core::Object {
+ constructor •(self::B::X% x) → self::B<self::B::X%>
+ : super core::Object::•()
+ ;
+}
+class C<Y extends core::Object? = dynamic> extends core::Object {
+ final field (self::D<self::C::Y%>) → FutureOr<self::C::Y%>% bar;
+ constructor •((self::D<self::C::Y%>) → FutureOr<self::C::Y%>% bar) → self::C<self::C::Y%>
+ : self::C::bar = bar, super core::Object::•()
+ ;
+}
+abstract class D<W extends core::Object? = dynamic> extends core::Object implements self::A {
+ synthetic constructor •() → self::D<self::D::W%>
+ : super core::Object::•()
+ ;
+}
+static final field self::C<core::int> baz = new self::C::•<core::int>((self::D<core::int> a) → FutureOr<core::int> {
+ return a.{self::A::foo}<FutureOr<core::int>>(new self::B::•<FutureOr<core::int>>(asy::Future::value<core::int>(0))){(self::B<FutureOr<core::int>>) → FutureOr<core::int>};
+});
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue48631_2.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/issue48631_2.dart.weak.outline.expect
new file mode 100644
index 0000000..4eff2cf
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_2.dart.weak.outline.expect
@@ -0,0 +1,28 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "dart:async";
+
+typedef Bar<V extends core::Object? = dynamic, contravariant U extends self::A> = (U) → V%;
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+ abstract method foo<T extends core::Object? = dynamic>(self::B<self::A::foo::T%> b) → self::A::foo::T%;
+}
+class B<X extends core::Object? = dynamic> extends core::Object {
+ constructor •(self::B::X% x) → self::B<self::B::X%>
+ ;
+}
+class C<Y extends core::Object? = dynamic> extends core::Object {
+ final field (self::D<self::C::Y%>) → FutureOr<self::C::Y%>% bar;
+ constructor •((self::D<self::C::Y%>) → FutureOr<self::C::Y%>% bar) → self::C<self::C::Y%>
+ ;
+}
+abstract class D<W extends core::Object? = dynamic> extends core::Object implements self::A {
+ synthetic constructor •() → self::D<self::D::W%>
+ ;
+}
+static final field self::C<core::int> baz;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/issue48631_2.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue48631_2.dart.weak.transformed.expect
new file mode 100644
index 0000000..e842794
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48631_2.dart.weak.transformed.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+typedef Bar<V extends core::Object? = dynamic, contravariant U extends self::A> = (U) → V%;
+abstract class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ abstract method foo<T extends core::Object? = dynamic>(self::B<self::A::foo::T%> b) → self::A::foo::T%;
+}
+class B<X extends core::Object? = dynamic> extends core::Object {
+ constructor •(self::B::X% x) → self::B<self::B::X%>
+ : super core::Object::•()
+ ;
+}
+class C<Y extends core::Object? = dynamic> extends core::Object {
+ final field (self::D<self::C::Y%>) → FutureOr<self::C::Y%>% bar;
+ constructor •((self::D<self::C::Y%>) → FutureOr<self::C::Y%>% bar) → self::C<self::C::Y%>
+ : self::C::bar = bar, super core::Object::•()
+ ;
+}
+abstract class D<W extends core::Object? = dynamic> extends core::Object implements self::A {
+ synthetic constructor •() → self::D<self::D::W%>
+ : super core::Object::•()
+ ;
+}
+static final field self::C<core::int> baz = new self::C::•<core::int>((self::D<core::int> a) → FutureOr<core::int> {
+ return a.{self::A::foo}<FutureOr<core::int>>(new self::B::•<FutureOr<core::int>>(asy::Future::value<core::int>(0))){(self::B<FutureOr<core::int>>) → FutureOr<core::int>};
+});
+static method main() → dynamic {}
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index af4b1d0..4cfb5cd 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -614,7 +614,22 @@
int before = useCounter;
DartType typeArgument = node.typeArgument.accept(this);
if (useCounter == before) return node;
- return new FutureOrType(typeArgument, node.declaredNullability);
+
+ // The top-level nullability of a FutureOr should remain the same, with the
+ // exception of the case of [Nullability.undetermined]. In that case it
+ // remains undetermined if the nullability of [typeArgument] is
+ // undetermined, and otherwise it should become [Nullability.nonNullable].
+ Nullability nullability;
+ if (node.declaredNullability == Nullability.undetermined) {
+ if (typeArgument.nullability == Nullability.undetermined) {
+ nullability = Nullability.undetermined;
+ } else {
+ nullability = Nullability.nonNullable;
+ }
+ } else {
+ nullability = node.declaredNullability;
+ }
+ return new FutureOrType(typeArgument, nullability);
}
@override
diff --git a/tools/VERSION b/tools/VERSION
index caf2558..b1736d8 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
MINOR 17
PATCH 0
PRERELEASE 266
-PRERELEASE_PATCH 5
\ No newline at end of file
+PRERELEASE_PATCH 7
\ No newline at end of file