[cfe] Implement the update of "incompatible with await"

This CL implements the udpate to the notion of a type being
"incompatible with await" as found here:
https://github.com/dart-lang/language/pull/3598

Change-Id: I7792564c1854468709d0da3238c02e912df52369
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/349882
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
index c7dd71c..436922c 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
@@ -807,70 +807,6 @@
     return const StatementInferenceResult();
   }
 
-  bool _derivesFutureType(DartType type) {
-    // TODO(cstefantsova): Update this method when
-    // https://github.com/dart-lang/language/pull/3574 is merged.
-    if (isNullableTypeConstructorApplication(type)) {
-      return false;
-    } else {
-      switch (type) {
-        case InterfaceType():
-          return typeSchemaEnvironment.hierarchy
-                  .getInterfaceTypeAsInstanceOfClass(
-                      type, coreTypes.futureClass,
-                      isNonNullableByDefault: isNonNullableByDefault) !=
-              null;
-        case ExtensionType():
-          return typeSchemaEnvironment.hierarchy
-                  .getExtensionTypeAsInstanceOfClass(
-                      type, coreTypes.futureClass,
-                      isNonNullableByDefault: isNonNullableByDefault) !=
-              null;
-        case TypeParameterType():
-          DartType boundedBy = type;
-          while (boundedBy is TypeParameterType &&
-              !isNullableTypeConstructorApplication(boundedBy)) {
-            boundedBy = boundedBy.parameter.bound;
-          }
-          return boundedBy is FutureOrType ||
-              boundedBy is InterfaceType &&
-                  boundedBy.classNode == coreTypes.futureClass &&
-                  boundedBy.nullability == Nullability.nullable;
-        case StructuralParameterType():
-          DartType boundedBy = type;
-          while (boundedBy is TypeParameterType &&
-              !isNullableTypeConstructorApplication(boundedBy)) {
-            boundedBy = boundedBy.parameter.bound;
-          }
-          return boundedBy is FutureOrType ||
-              boundedBy is InterfaceType &&
-                  boundedBy.classNode == coreTypes.futureClass &&
-                  boundedBy.nullability == Nullability.nullable;
-        case IntersectionType():
-          DartType boundedBy = type.right;
-          while (boundedBy is TypeParameterType &&
-              !isNullableTypeConstructorApplication(boundedBy)) {
-            boundedBy = boundedBy.parameter.bound;
-          }
-          return boundedBy is FutureOrType ||
-              boundedBy is InterfaceType &&
-                  boundedBy.classNode == coreTypes.futureClass &&
-                  boundedBy.nullability == Nullability.nullable;
-        case DynamicType():
-        case VoidType():
-        case FutureOrType():
-        case TypedefType():
-        case FunctionType():
-        case RecordType():
-        case NullType():
-        case NeverType():
-        case AuxiliaryType():
-        case InvalidType():
-          return false;
-      }
-    }
-  }
-
   bool _isIncompatibleWithAwait(DartType type) {
     if (isNullableTypeConstructorApplication(type)) {
       return _isIncompatibleWithAwait(computeTypeWithoutNullabilityMarker(
@@ -890,9 +826,7 @@
         case StructuralParameterType():
           return _isIncompatibleWithAwait(type.parameter.bound);
         case IntersectionType():
-          return _isIncompatibleWithAwait(type.right) ||
-              !_derivesFutureType(type.right) &&
-                  _isIncompatibleWithAwait(type.left);
+          return _isIncompatibleWithAwait(type.right);
         case DynamicType():
         case VoidType():
         case FutureOrType():
diff --git a/pkg/front_end/testcases/extension_types/issue54649_2.dart b/pkg/front_end/testcases/extension_types/issue54649_2.dart
index 375c4d0..d4450d3 100644
--- a/pkg/front_end/testcases/extension_types/issue54649_2.dart
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart
@@ -2,6 +2,8 @@
 // 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';
+
 extension type E1(Future<int> it) {}
 
 extension type E2(Future<int> it) implements E1, Future<int> {}
@@ -10,26 +12,23 @@
 
 test1<X extends E1, Y extends E2>(X x) async {
   // `X` is incompatible with await.
-  // `Y` derives a future type.
-  if (x is Y) {
-    // The following line should stop being a compile-time error and be marked
-    // as "Ok." when the following PR is merged:
-    // https://github.com/dart-lang/language/pull/3574.
-    await x; // Error.
-  }
-}
-
-test2<X extends E3?, Y extends Null>(X x) async {
-  // `X` is compatible with await.
-  // `Y` does not derive a future type.
+  // `Y` isn't incompatible with await.
   if (x is Y) {
     await x; // Ok.
   }
 }
 
+test2<X extends FutureOr<E1>, Y extends E1>(X x) async {
+  // `X` isn't incompatible with await.
+  // `Y` is incompatible with await.
+  if (x is Y) {
+    await x; // Error.
+  }
+}
+
 test3<X extends E3?, Y extends E3>(X x) async {
-  // `X` is compatible with await.
-  // `Y` derives a future type.
+  // `X` isn't incompatible with await.
+  // `Y` isn't incompatible with await.
   if (x is Y) {
     await x; // Ok.
   }
@@ -37,7 +36,7 @@
 
 test4<X extends E1, Y extends X>(X x) async {
   // `X` is incompatible with await.
-  // `Y` does not derive a future type.
+  // `Y` is incompatible with await.
   if (x is Y) {
     await x; // Error.
   }
diff --git a/pkg/front_end/testcases/extension_types/issue54649_2.dart.strong.expect b/pkg/front_end/testcases/extension_types/issue54649_2.dart.strong.expect
index 344b074..deabe44 100644
--- a/pkg/front_end/testcases/extension_types/issue54649_2.dart.strong.expect
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.strong.expect
@@ -2,11 +2,11 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/extension_types/issue54649_2.dart:18:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+// pkg/front_end/testcases/extension_types/issue54649_2.dart:25:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
 //     await x; // Error.
 //           ^
 //
-// pkg/front_end/testcases/extension_types/issue54649_2.dart:42:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+// pkg/front_end/testcases/extension_types/issue54649_2.dart:41:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
 //     await x; // Error.
 //           ^
 //
@@ -14,6 +14,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 extension type E1(asy::Future<core::int> it) {
   abstract extension-type-member representation-field get it() → asy::Future<core::int>;
   constructor • = self::E1|constructor#;
@@ -49,14 +51,14 @@
   return self::E3|constructor#(it);
 static method test1<X extends self::E1 /* = asy::Future<core::int> */, Y extends self::E2 /* = asy::Future<core::int> */>(self::test1::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test1::Y) {
-    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:18:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
-    await x; // Error.
-          ^" in x{self::test1::X% & self::test1::Y /* '%' & '!' = '!' */};
+    await x{self::test1::X% & self::test1::Y /* '%' & '!' = '!' */};
   }
 }
-static method test2<X extends self::E3? /* = asy::Future<core::int>? */, Y extends Null>(self::test2::X% x) → dynamic async /* emittedValueType= dynamic */ {
+static method test2<X extends FutureOr<self::E1 /* = asy::Future<core::int> */>, Y extends self::E1 /* = asy::Future<core::int> */>(self::test2::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test2::Y%) {
-    await x{self::test2::X% & self::test2::Y% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:25:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+    await x; // Error.
+          ^" in x{self::test2::X% & self::test2::Y% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::E1% /* = asy::Future<core::int> */> */ ;
   }
 }
 static method test3<X extends self::E3? /* = asy::Future<core::int>? */, Y extends self::E3 /* = asy::Future<core::int> */>(self::test3::X% x) → dynamic async /* emittedValueType= dynamic */ {
@@ -66,7 +68,7 @@
 }
 static method test4<X extends self::E1 /* = asy::Future<core::int> */, Y extends self::test4::X% = self::E1 /* = asy::Future<core::int> */>(self::test4::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test4::Y%) {
-    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:42:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:41:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
     await x; // Error.
           ^" in x{self::test4::Y%} /* runtimeCheckType= asy::Future<self::test4::Y%> */ ;
   }
diff --git a/pkg/front_end/testcases/extension_types/issue54649_2.dart.strong.transformed.expect b/pkg/front_end/testcases/extension_types/issue54649_2.dart.strong.transformed.expect
index 344b074..deabe44 100644
--- a/pkg/front_end/testcases/extension_types/issue54649_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.strong.transformed.expect
@@ -2,11 +2,11 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/extension_types/issue54649_2.dart:18:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+// pkg/front_end/testcases/extension_types/issue54649_2.dart:25:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
 //     await x; // Error.
 //           ^
 //
-// pkg/front_end/testcases/extension_types/issue54649_2.dart:42:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+// pkg/front_end/testcases/extension_types/issue54649_2.dart:41:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
 //     await x; // Error.
 //           ^
 //
@@ -14,6 +14,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 extension type E1(asy::Future<core::int> it) {
   abstract extension-type-member representation-field get it() → asy::Future<core::int>;
   constructor • = self::E1|constructor#;
@@ -49,14 +51,14 @@
   return self::E3|constructor#(it);
 static method test1<X extends self::E1 /* = asy::Future<core::int> */, Y extends self::E2 /* = asy::Future<core::int> */>(self::test1::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test1::Y) {
-    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:18:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
-    await x; // Error.
-          ^" in x{self::test1::X% & self::test1::Y /* '%' & '!' = '!' */};
+    await x{self::test1::X% & self::test1::Y /* '%' & '!' = '!' */};
   }
 }
-static method test2<X extends self::E3? /* = asy::Future<core::int>? */, Y extends Null>(self::test2::X% x) → dynamic async /* emittedValueType= dynamic */ {
+static method test2<X extends FutureOr<self::E1 /* = asy::Future<core::int> */>, Y extends self::E1 /* = asy::Future<core::int> */>(self::test2::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test2::Y%) {
-    await x{self::test2::X% & self::test2::Y% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:25:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+    await x; // Error.
+          ^" in x{self::test2::X% & self::test2::Y% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::E1% /* = asy::Future<core::int> */> */ ;
   }
 }
 static method test3<X extends self::E3? /* = asy::Future<core::int>? */, Y extends self::E3 /* = asy::Future<core::int> */>(self::test3::X% x) → dynamic async /* emittedValueType= dynamic */ {
@@ -66,7 +68,7 @@
 }
 static method test4<X extends self::E1 /* = asy::Future<core::int> */, Y extends self::test4::X% = self::E1 /* = asy::Future<core::int> */>(self::test4::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test4::Y%) {
-    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:42:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:41:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
     await x; // Error.
           ^" in x{self::test4::Y%} /* runtimeCheckType= asy::Future<self::test4::Y%> */ ;
   }
diff --git a/pkg/front_end/testcases/extension_types/issue54649_2.dart.textual_outline.expect b/pkg/front_end/testcases/extension_types/issue54649_2.dart.textual_outline.expect
index c866879..5b1fb7e 100644
--- a/pkg/front_end/testcases/extension_types/issue54649_2.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.textual_outline.expect
@@ -1,3 +1,5 @@
+import 'dart:async';
+
 extension type E1(Future<int> it) {}
 
 extension type E2(Future<int> it) implements E1, Future<int> {}
@@ -6,7 +8,7 @@
 
 test1<X extends E1, Y extends E2>(X x) async {}
 
-test2<X extends E3?, Y extends Null>(X x) async {}
+test2<X extends FutureOr<E1>, Y extends E1>(X x) async {}
 
 test3<X extends E3?, Y extends E3>(X x) async {}
 
diff --git a/pkg/front_end/testcases/extension_types/issue54649_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extension_types/issue54649_2.dart.textual_outline_modelled.expect
index c866879..5b1fb7e 100644
--- a/pkg/front_end/testcases/extension_types/issue54649_2.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.textual_outline_modelled.expect
@@ -1,3 +1,5 @@
+import 'dart:async';
+
 extension type E1(Future<int> it) {}
 
 extension type E2(Future<int> it) implements E1, Future<int> {}
@@ -6,7 +8,7 @@
 
 test1<X extends E1, Y extends E2>(X x) async {}
 
-test2<X extends E3?, Y extends Null>(X x) async {}
+test2<X extends FutureOr<E1>, Y extends E1>(X x) async {}
 
 test3<X extends E3?, Y extends E3>(X x) async {}
 
diff --git a/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.expect b/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.expect
index 344b074..deabe44 100644
--- a/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.expect
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.expect
@@ -2,11 +2,11 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/extension_types/issue54649_2.dart:18:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+// pkg/front_end/testcases/extension_types/issue54649_2.dart:25:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
 //     await x; // Error.
 //           ^
 //
-// pkg/front_end/testcases/extension_types/issue54649_2.dart:42:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+// pkg/front_end/testcases/extension_types/issue54649_2.dart:41:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
 //     await x; // Error.
 //           ^
 //
@@ -14,6 +14,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 extension type E1(asy::Future<core::int> it) {
   abstract extension-type-member representation-field get it() → asy::Future<core::int>;
   constructor • = self::E1|constructor#;
@@ -49,14 +51,14 @@
   return self::E3|constructor#(it);
 static method test1<X extends self::E1 /* = asy::Future<core::int> */, Y extends self::E2 /* = asy::Future<core::int> */>(self::test1::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test1::Y) {
-    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:18:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
-    await x; // Error.
-          ^" in x{self::test1::X% & self::test1::Y /* '%' & '!' = '!' */};
+    await x{self::test1::X% & self::test1::Y /* '%' & '!' = '!' */};
   }
 }
-static method test2<X extends self::E3? /* = asy::Future<core::int>? */, Y extends Null>(self::test2::X% x) → dynamic async /* emittedValueType= dynamic */ {
+static method test2<X extends FutureOr<self::E1 /* = asy::Future<core::int> */>, Y extends self::E1 /* = asy::Future<core::int> */>(self::test2::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test2::Y%) {
-    await x{self::test2::X% & self::test2::Y% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:25:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+    await x; // Error.
+          ^" in x{self::test2::X% & self::test2::Y% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::E1% /* = asy::Future<core::int> */> */ ;
   }
 }
 static method test3<X extends self::E3? /* = asy::Future<core::int>? */, Y extends self::E3 /* = asy::Future<core::int> */>(self::test3::X% x) → dynamic async /* emittedValueType= dynamic */ {
@@ -66,7 +68,7 @@
 }
 static method test4<X extends self::E1 /* = asy::Future<core::int> */, Y extends self::test4::X% = self::E1 /* = asy::Future<core::int> */>(self::test4::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test4::Y%) {
-    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:42:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:41:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
     await x; // Error.
           ^" in x{self::test4::Y%} /* runtimeCheckType= asy::Future<self::test4::Y%> */ ;
   }
diff --git a/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.modular.expect b/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.modular.expect
index 344b074..deabe44 100644
--- a/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.modular.expect
@@ -2,11 +2,11 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/extension_types/issue54649_2.dart:18:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+// pkg/front_end/testcases/extension_types/issue54649_2.dart:25:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
 //     await x; // Error.
 //           ^
 //
-// pkg/front_end/testcases/extension_types/issue54649_2.dart:42:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+// pkg/front_end/testcases/extension_types/issue54649_2.dart:41:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
 //     await x; // Error.
 //           ^
 //
@@ -14,6 +14,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 extension type E1(asy::Future<core::int> it) {
   abstract extension-type-member representation-field get it() → asy::Future<core::int>;
   constructor • = self::E1|constructor#;
@@ -49,14 +51,14 @@
   return self::E3|constructor#(it);
 static method test1<X extends self::E1 /* = asy::Future<core::int> */, Y extends self::E2 /* = asy::Future<core::int> */>(self::test1::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test1::Y) {
-    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:18:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
-    await x; // Error.
-          ^" in x{self::test1::X% & self::test1::Y /* '%' & '!' = '!' */};
+    await x{self::test1::X% & self::test1::Y /* '%' & '!' = '!' */};
   }
 }
-static method test2<X extends self::E3? /* = asy::Future<core::int>? */, Y extends Null>(self::test2::X% x) → dynamic async /* emittedValueType= dynamic */ {
+static method test2<X extends FutureOr<self::E1 /* = asy::Future<core::int> */>, Y extends self::E1 /* = asy::Future<core::int> */>(self::test2::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test2::Y%) {
-    await x{self::test2::X% & self::test2::Y% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:25:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+    await x; // Error.
+          ^" in x{self::test2::X% & self::test2::Y% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::E1% /* = asy::Future<core::int> */> */ ;
   }
 }
 static method test3<X extends self::E3? /* = asy::Future<core::int>? */, Y extends self::E3 /* = asy::Future<core::int> */>(self::test3::X% x) → dynamic async /* emittedValueType= dynamic */ {
@@ -66,7 +68,7 @@
 }
 static method test4<X extends self::E1 /* = asy::Future<core::int> */, Y extends self::test4::X% = self::E1 /* = asy::Future<core::int> */>(self::test4::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test4::Y%) {
-    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:42:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:41:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
     await x; // Error.
           ^" in x{self::test4::Y%} /* runtimeCheckType= asy::Future<self::test4::Y%> */ ;
   }
diff --git a/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.outline.expect b/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.outline.expect
index 73f7135..e624577 100644
--- a/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.outline.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 extension type E1(asy::Future<core::int> it) {
   abstract extension-type-member representation-field get it() → asy::Future<core::int>;
   constructor • = self::E1|constructor#;
@@ -32,7 +34,7 @@
   return self::E3|constructor#(it);
 static method test1<X extends self::E1 /* = asy::Future<core::int> */, Y extends self::E2 /* = asy::Future<core::int> */>(self::test1::X% x) → dynamic async 
   ;
-static method test2<X extends self::E3? /* = asy::Future<core::int>? */, Y extends Null>(self::test2::X% x) → dynamic async 
+static method test2<X extends FutureOr<self::E1 /* = asy::Future<core::int> */>, Y extends self::E1 /* = asy::Future<core::int> */>(self::test2::X% x) → dynamic async 
   ;
 static method test3<X extends self::E3? /* = asy::Future<core::int>? */, Y extends self::E3 /* = asy::Future<core::int> */>(self::test3::X% x) → dynamic async 
   ;
diff --git a/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.transformed.expect b/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.transformed.expect
index 344b074..deabe44 100644
--- a/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.transformed.expect
@@ -2,11 +2,11 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/extension_types/issue54649_2.dart:18:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+// pkg/front_end/testcases/extension_types/issue54649_2.dart:25:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
 //     await x; // Error.
 //           ^
 //
-// pkg/front_end/testcases/extension_types/issue54649_2.dart:42:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+// pkg/front_end/testcases/extension_types/issue54649_2.dart:41:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
 //     await x; // Error.
 //           ^
 //
@@ -14,6 +14,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 extension type E1(asy::Future<core::int> it) {
   abstract extension-type-member representation-field get it() → asy::Future<core::int>;
   constructor • = self::E1|constructor#;
@@ -49,14 +51,14 @@
   return self::E3|constructor#(it);
 static method test1<X extends self::E1 /* = asy::Future<core::int> */, Y extends self::E2 /* = asy::Future<core::int> */>(self::test1::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test1::Y) {
-    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:18:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
-    await x; // Error.
-          ^" in x{self::test1::X% & self::test1::Y /* '%' & '!' = '!' */};
+    await x{self::test1::X% & self::test1::Y /* '%' & '!' = '!' */};
   }
 }
-static method test2<X extends self::E3? /* = asy::Future<core::int>? */, Y extends Null>(self::test2::X% x) → dynamic async /* emittedValueType= dynamic */ {
+static method test2<X extends FutureOr<self::E1 /* = asy::Future<core::int> */>, Y extends self::E1 /* = asy::Future<core::int> */>(self::test2::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test2::Y%) {
-    await x{self::test2::X% & self::test2::Y% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:25:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+    await x; // Error.
+          ^" in x{self::test2::X% & self::test2::Y% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::E1% /* = asy::Future<core::int> */> */ ;
   }
 }
 static method test3<X extends self::E3? /* = asy::Future<core::int>? */, Y extends self::E3 /* = asy::Future<core::int> */>(self::test3::X% x) → dynamic async /* emittedValueType= dynamic */ {
@@ -66,7 +68,7 @@
 }
 static method test4<X extends self::E1 /* = asy::Future<core::int> */, Y extends self::test4::X% = self::E1 /* = asy::Future<core::int> */>(self::test4::X% x) → dynamic async /* emittedValueType= dynamic */ {
   if(x is self::test4::Y%) {
-    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:42:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649_2.dart:41:11: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
     await x; // Error.
           ^" in x{self::test4::Y%} /* runtimeCheckType= asy::Future<self::test4::Y%> */ ;
   }