Version 2.18.0-10.0.dev
Merge commit '3d27f5cb79245720363d1b1c44d467b99e8f1d49' into 'dev'
diff --git a/pkg/front_end/testcases/nnbd/issue48768.dart b/pkg/front_end/testcases/nnbd/issue48768.dart
new file mode 100644
index 0000000..7b8493f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48768.dart
@@ -0,0 +1,9 @@
+// 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.
+
+foo(dynamic y) async {
+ var a = await (<X>(List<X> Function() x, X x2) => x2)(() => y, throw 0);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue48768.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue48768.dart.strong.expect
new file mode 100644
index 0000000..e54e3bd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48768.dart.strong.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method foo(dynamic y) → dynamic async /* futureValueType= dynamic */ {
+ dynamic a = await(<X extends core::Object? = dynamic>(() → core::List<X%> x, X% x2) → X% => x2)<FutureOr<dynamic>>(() → core::List<FutureOr<dynamic>> => y as{TypeError,ForDynamic,ForNonNullableByDefault} core::List<FutureOr<dynamic>>, throw 0){(() → core::List<FutureOr<dynamic>?>, FutureOr<dynamic>?) → FutureOr<dynamic>?};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue48768.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue48768.dart.strong.transformed.expect
new file mode 100644
index 0000000..c6295ee
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48768.dart.strong.transformed.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method foo(dynamic y) → dynamic /* futureValueType= dynamic */ /* originally async */ {
+ final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+ core::bool* :is_sync = false;
+ dynamic :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding
+ try {
+ #L1:
+ {
+ [yield] let dynamic #t1 = asy::_awaitHelper((<X extends core::Object? = dynamic>(() → core::List<X%> x, X% x2) → X% => x2)<FutureOr<dynamic>>(() → core::List<FutureOr<dynamic>> => y as{TypeError,ForDynamic,ForNonNullableByDefault} core::List<FutureOr<dynamic>>, throw 0){(() → core::List<FutureOr<dynamic>?>, FutureOr<dynamic>?) → FutureOr<dynamic>?}, :async_op_then, :async_op_error) in null;
+ dynamic a = :result_or_exception;
+ }
+ asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op(null, null){() → dynamic};
+ :is_sync = true;
+ return :async_future;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue48768.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/issue48768.dart.textual_outline.expect
new file mode 100644
index 0000000..f83e8ee
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48768.dart.textual_outline.expect
@@ -0,0 +1,2 @@
+foo(dynamic y) async {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue48768.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/issue48768.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..f83e8ee
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48768.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@
+foo(dynamic y) async {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/issue48768.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue48768.dart.weak.expect
new file mode 100644
index 0000000..e54e3bd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48768.dart.weak.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method foo(dynamic y) → dynamic async /* futureValueType= dynamic */ {
+ dynamic a = await(<X extends core::Object? = dynamic>(() → core::List<X%> x, X% x2) → X% => x2)<FutureOr<dynamic>>(() → core::List<FutureOr<dynamic>> => y as{TypeError,ForDynamic,ForNonNullableByDefault} core::List<FutureOr<dynamic>>, throw 0){(() → core::List<FutureOr<dynamic>?>, FutureOr<dynamic>?) → FutureOr<dynamic>?};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue48768.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue48768.dart.weak.modular.expect
new file mode 100644
index 0000000..e54e3bd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48768.dart.weak.modular.expect
@@ -0,0 +1,8 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method foo(dynamic y) → dynamic async /* futureValueType= dynamic */ {
+ dynamic a = await(<X extends core::Object? = dynamic>(() → core::List<X%> x, X% x2) → X% => x2)<FutureOr<dynamic>>(() → core::List<FutureOr<dynamic>> => y as{TypeError,ForDynamic,ForNonNullableByDefault} core::List<FutureOr<dynamic>>, throw 0){(() → core::List<FutureOr<dynamic>?>, FutureOr<dynamic>?) → FutureOr<dynamic>?};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue48768.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/issue48768.dart.weak.outline.expect
new file mode 100644
index 0000000..0539b7f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48768.dart.weak.outline.expect
@@ -0,0 +1,7 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method foo(dynamic y) → dynamic async
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/issue48768.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue48768.dart.weak.transformed.expect
new file mode 100644
index 0000000..c6295ee
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue48768.dart.weak.transformed.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method foo(dynamic y) → dynamic /* futureValueType= dynamic */ /* originally async */ {
+ final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+ core::bool* :is_sync = false;
+ dynamic :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding
+ try {
+ #L1:
+ {
+ [yield] let dynamic #t1 = asy::_awaitHelper((<X extends core::Object? = dynamic>(() → core::List<X%> x, X% x2) → X% => x2)<FutureOr<dynamic>>(() → core::List<FutureOr<dynamic>> => y as{TypeError,ForDynamic,ForNonNullableByDefault} core::List<FutureOr<dynamic>>, throw 0){(() → core::List<FutureOr<dynamic>?>, FutureOr<dynamic>?) → FutureOr<dynamic>?}, :async_op_then, :async_op_error) in null;
+ dynamic a = :result_or_exception;
+ }
+ asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op(null, null){() → dynamic};
+ :is_sync = true;
+ return :async_future;
+}
+static method main() → dynamic {}
diff --git a/pkg/kernel/lib/src/replacement_visitor.dart b/pkg/kernel/lib/src/replacement_visitor.dart
index b37a704..2f625b4 100644
--- a/pkg/kernel/lib/src/replacement_visitor.dart
+++ b/pkg/kernel/lib/src/replacement_visitor.dart
@@ -171,8 +171,26 @@
// No nullability or type arguments needed to be substituted.
return null;
} else {
- return new FutureOrType(newTypeArgument ?? node.typeArgument,
- newNullability ?? node.declaredNullability);
+ newTypeArgument ??= node.typeArgument;
+ newNullability ??= 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 adjustedNullability;
+ if (newNullability == Nullability.undetermined) {
+ if (newTypeArgument.nullability == Nullability.undetermined) {
+ adjustedNullability = Nullability.undetermined;
+ } else {
+ adjustedNullability = Nullability.nonNullable;
+ }
+ } else {
+ adjustedNullability = newNullability;
+ }
+
+ return new FutureOrType(newTypeArgument, adjustedNullability);
}
}
diff --git a/tools/VERSION b/tools/VERSION
index 8a50ded..d85812f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 9
+PRERELEASE 10
PRERELEASE_PATCH 0
\ No newline at end of file