Migration: fix crash when handling `await null`.
Previously, this wasn't working because the way we were checking
whether the type being awaited was a `Future` was via a subtype check
using the pre-NNBD type system. And the pre-NNBD type system says
that `Null` is a subtype of `Future`. So we were trying to extract a
type argument from the type `Null`, leading to a crash.
The solution is to add a separate case that directly handles the
`Null` type.
Bug: https://b.corp.google.com/issues/203199775
Change-Id: I083ef33e17c83d6a3e49b8fd0804c0de1c91ce84
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/218940
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 030f06f..e2c1264 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -490,7 +490,9 @@
DecoratedType visitAwaitExpression(AwaitExpression node) {
var expressionType = _dispatch(node.expression)!;
var type = expressionType.type!;
- if (_typeSystem.isSubtypeOf(type, typeProvider.futureDynamicType)) {
+ if (type.isDartCoreNull) {
+ // Nothing to do; awaiting `null` produces `null`.
+ } else if (_typeSystem.isSubtypeOf(type, typeProvider.futureDynamicType)) {
expressionType = _decoratedClassHierarchy!
.asInstanceOf(expressionType, typeProvider.futureElement)
.typeArguments[0]!;
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index a13964d..de7d447 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -639,6 +639,20 @@
await _checkSingleFileChanges(content, expected);
}
+ Future<void> test_await_null() async {
+ var content = '''
+Future<int> test() async {
+ return await null;
+}
+''';
+ var expected = '''
+Future<int?> test() async {
+ return await null;
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
Future<void>
test_back_propagation_stops_at_implicitly_typed_variables() async {
var content = '''