[cfe] Adjust computation of nullability in flatten
Closes #47057.
Bug: https://github.com/dart-lang/sdk/issues/47057
Change-Id: Iad719192d0ecbe97461bfed868899072a6dd52e2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/212467
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
diff --git a/pkg/front_end/testcases/general/issue47057.dart b/pkg/front_end/testcases/general/issue47057.dart
new file mode 100644
index 0000000..8d5b88d
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47057.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2021, 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';
+
+Future<int> foo<X extends Object?>(X x) async {
+ if (x is Future<int>) {
+ return x;
+ } else {
+ throw 42;
+ }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue47057.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue47057.dart.textual_outline.expect
new file mode 100644
index 0000000..af27955
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47057.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'dart:async';
+
+Future<int> foo<X extends Object?>(X x) async {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue47057.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue47057.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..af27955
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47057.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'dart:async';
+
+Future<int> foo<X extends Object?>(X x) async {}
+main() {}
diff --git a/pkg/front_end/testcases/general/issue47057.dart.weak.expect b/pkg/front_end/testcases/general/issue47057.dart.weak.expect
new file mode 100644
index 0000000..abd22ad
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47057.dart.weak.expect
@@ -0,0 +1,16 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+static method foo<X extends core::Object?>(self::foo::X% x) → asy::Future<core::int> async {
+ if(x is{ForNonNullableByDefault} asy::Future<core::int>) {
+ return x{self::foo::X% & asy::Future<core::int> /* '%' & '!' = '!' */};
+ }
+ else {
+ throw 42;
+ }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue47057.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue47057.dart.weak.outline.expect
new file mode 100644
index 0000000..e803dbe
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47057.dart.weak.outline.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+static method foo<X extends core::Object?>(self::foo::X% x) → asy::Future<core::int> async
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/issue47057.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue47057.dart.weak.transformed.expect
new file mode 100644
index 0000000..e2413bc
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue47057.dart.weak.transformed.expect
@@ -0,0 +1,40 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+static method foo<X extends core::Object?>(self::foo::X% x) → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :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;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L1:
+ {
+ if(x is{ForNonNullableByDefault} asy::Future<core::int>) {
+ :return_value = x{self::foo::X% & asy::Future<core::int> /* '%' & '!' = '!' */};
+ break #L1;
+ }
+ else {
+ throw 42;
+ }
+ }
+ asy::_completeOnAsyncReturn(: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(){() → dynamic};
+ :is_sync = true;
+ return :async_future;
+}
+static method main() → dynamic {}
diff --git a/pkg/kernel/lib/type_environment.dart b/pkg/kernel/lib/type_environment.dart
index 6b22016..5320daf 100644
--- a/pkg/kernel/lib/type_environment.dart
+++ b/pkg/kernel/lib/type_environment.dart
@@ -102,8 +102,7 @@
List<DartType>? futureArguments =
getTypeArgumentsAsInstanceOf(resolved, coreTypes.futureClass);
if (futureArguments != null) {
- return _withDeclaredNullability(
- futureArguments.single, t.declaredNullability);
+ return _withDeclaredNullability(futureArguments.single, t.nullability);
}
}