[cfe] Report errors on awaiting types incompatible with await

Closes https://github.com/dart-lang/sdk/issues/54649

Change-Id: I66497f9251710723b983b9f29f3f22eff2c83d96
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/348640
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 aa230ba..c7dd71c 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,6 +807,108 @@
     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(
+          (type),
+          isNonNullableByDefault: isNonNullableByDefault));
+    } else {
+      switch (type) {
+        case ExtensionType():
+          return typeSchemaEnvironment.hierarchy
+                  .getExtensionTypeAsInstanceOfClass(
+                      type, coreTypes.futureClass,
+                      isNonNullableByDefault:
+                          libraryBuilder.isNonNullableByDefault) ==
+              null;
+        case TypeParameterType():
+          return _isIncompatibleWithAwait(type.parameter.bound);
+        case StructuralParameterType():
+          return _isIncompatibleWithAwait(type.parameter.bound);
+        case IntersectionType():
+          return _isIncompatibleWithAwait(type.right) ||
+              !_derivesFutureType(type.right) &&
+                  _isIncompatibleWithAwait(type.left);
+        case DynamicType():
+        case VoidType():
+        case FutureOrType():
+        case InterfaceType():
+        case TypedefType():
+        case FunctionType():
+        case RecordType():
+        case NullType():
+        case NeverType():
+        case AuxiliaryType():
+        case InvalidType():
+          return false;
+      }
+    }
+  }
+
   @override
   ExpressionInferenceResult visitAwaitExpression(
       AwaitExpression node, DartType typeContext) {
@@ -818,12 +920,7 @@
         isVoidAllowed: !isNonNullableByDefault);
     DartType operandType = operandResult.inferredType;
     DartType flattenType = typeSchemaEnvironment.flatten(operandType);
-    if (operandType is ExtensionType &&
-        typeSchemaEnvironment.hierarchy.getExtensionTypeAsInstanceOfClass(
-                operandType, coreTypes.futureClass,
-                isNonNullableByDefault:
-                    libraryBuilder.isNonNullableByDefault) ==
-            null) {
+    if (_isIncompatibleWithAwait(operandType)) {
       Expression wrapped = operandResult.expression;
       node.operand = helper.wrapInProblem(
           wrapped, messageAwaitOfExtensionTypeNotFuture, wrapped.fileOffset, 1);
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 81ef47e..80ca452 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -833,6 +833,7 @@
 derivation
 derive
 derived
+derives
 descendant
 descendants
 describe
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index ab0b23d..5957206 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -336,6 +336,7 @@
 fortytwo
 foundation
 fox
+fq
 frequency
 frozen
 fruits
@@ -525,6 +526,7 @@
 noo
 noted
 nottest
+nq
 null'ed
 numerator
 nums
@@ -584,6 +586,7 @@
 population
 portions
 pp
+pr
 preliminary
 prematurely
 prerequisite
@@ -836,7 +839,9 @@
 ws
 x's
 xf
+xfq
 xlate
+xnq
 xrequired
 xxx
 xxxxxxxx
diff --git a/pkg/front_end/testcases/extension_types/issue54649.dart b/pkg/front_end/testcases/extension_types/issue54649.dart
new file mode 100644
index 0000000..02f7031
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2024, 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.
+
+extension type N(Future<int> _) {}
+extension type F(Future<int> _) implements Future<int> {}
+
+void test<X, XN extends N, XF extends F>(
+    N n, F f, X x, XN xn, XF xf, N? nq, F? fq, XN? xnq, XF? xfq) async {
+  await n; // Error.
+  await f; // OK, type `int`.
+  await x; // OK, type `X`.
+  await xn; // Error.
+  await xf; // OK, type `int`.
+  await nq; // Error.
+  await fq; // OK, type `int?`.
+  await xnq; // Error.
+  await xfq; // OK, type `int?`.
+  if (x is N) await x; // Error.
+  if (x is N?) await x; // Error.
+  if (x is XN) await x; // Error.
+  if (x is XN?) await x; // Error.
+  if (x is F) await x; // OK, type `int`.
+  if (x is F?) await x; // OK, type `int?`.
+  if (x is XF) await x; // OK, type `int`.
+  if (x is XF?) await x; // OK, type `int?`.
+}
diff --git a/pkg/front_end/testcases/extension_types/issue54649.dart.strong.expect b/pkg/front_end/testcases/extension_types/issue54649.dart.strong.expect
new file mode 100644
index 0000000..0767237
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649.dart.strong.expect
@@ -0,0 +1,105 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:10:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await n; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:13:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await xn; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:15:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await nq; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:17:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await xnq; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:19:21: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is N) await x; // Error.
+//                     ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:20:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is N?) await x; // Error.
+//                      ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:21:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is XN) await x; // Error.
+//                      ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:22:23: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is XN?) await x; // Error.
+//                       ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+extension type N(asy::Future<core::int> _) {
+  abstract extension-type-member representation-field get _() → asy::Future<core::int>;
+  constructor • = self::N|constructor#;
+  constructor tearoff • = self::N|constructor#_#new#tearOff;
+}
+extension type F(asy::Future<core::int> _) implements asy::Future<core::int> {
+  abstract extension-type-member representation-field get _() → asy::Future<core::int>;
+  constructor • = self::F|constructor#;
+  constructor tearoff • = self::F|constructor#_#new#tearOff;
+}
+static extension-type-member method N|constructor#(asy::Future<core::int> _) → self::N /* = asy::Future<core::int> */ {
+  lowered final self::N /* = asy::Future<core::int> */ #this = _;
+  return #this;
+}
+static extension-type-member method N|constructor#_#new#tearOff(asy::Future<core::int> _) → self::N /* = asy::Future<core::int> */
+  return self::N|constructor#(_);
+static extension-type-member method F|constructor#(asy::Future<core::int> _) → self::F /* = asy::Future<core::int> */ {
+  lowered final self::F /* = asy::Future<core::int> */ #this = _;
+  return #this;
+}
+static extension-type-member method F|constructor#_#new#tearOff(asy::Future<core::int> _) → self::F /* = asy::Future<core::int> */
+  return self::F|constructor#(_);
+static method test<X extends core::Object? = dynamic, XN extends self::N /* = asy::Future<core::int> */, XF extends self::F /* = asy::Future<core::int> */>(self::N /* = asy::Future<core::int> */ n, self::F /* = asy::Future<core::int> */ f, self::test::X% x, self::test::XN% xn, self::test::XF xf, self::N? /* = asy::Future<core::int>? */ nq, self::F? /* = asy::Future<core::int>? */ fq, self::test::XN? xnq, self::test::XF? xfq) → void async /* emittedValueType= void */ {
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:10:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await n; // Error.
+        ^" in n /* runtimeCheckType= asy::Future<self::N /* = asy::Future<core::int> */> */ ;
+  await f;
+  await x /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:13:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await xn; // Error.
+        ^" in xn /* runtimeCheckType= asy::Future<self::test::XN%> */ ;
+  await xf;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:15:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await nq; // Error.
+        ^" in nq /* runtimeCheckType= asy::Future<self::N? /* = asy::Future<core::int>? */> */ ;
+  await fq /* runtimeCheckType= asy::Future<core::int?> */ ;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:17:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await xnq; // Error.
+        ^" in xnq /* runtimeCheckType= asy::Future<self::test::XN?> */ ;
+  await xfq /* runtimeCheckType= asy::Future<core::int?> */ ;
+  if(x is self::N /* = asy::Future<core::int> */)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:19:21: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is N) await x; // Error.
+                    ^" in x{self::test::X% & self::N /* = asy::Future<core::int> */ /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::N? /* = asy::Future<core::int>? */)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:20:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is N?) await x; // Error.
+                     ^" in x{self::test::X% & self::N? /* = asy::Future<core::int>? */ /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::test::XN%)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:21:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is XN) await x; // Error.
+                     ^" in x{self::test::X% & self::test::XN% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::test::XN?)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:22:23: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is XN?) await x; // Error.
+                      ^" in x{self::test::X% & self::test::XN? /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::F /* = asy::Future<core::int> */)
+    await x{self::test::X% & self::F /* = asy::Future<core::int> */ /* '%' & '!' = '!' */};
+  if(x is self::F? /* = asy::Future<core::int>? */)
+    await x{self::test::X% & self::F? /* = asy::Future<core::int>? */ /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+  if(x is self::test::XF)
+    await x{self::test::X% & self::test::XF /* '%' & '!' = '!' */};
+  if(x is self::test::XF?)
+    await x{self::test::X% & self::test::XF? /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+}
diff --git a/pkg/front_end/testcases/extension_types/issue54649.dart.strong.transformed.expect b/pkg/front_end/testcases/extension_types/issue54649.dart.strong.transformed.expect
new file mode 100644
index 0000000..0767237
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649.dart.strong.transformed.expect
@@ -0,0 +1,105 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:10:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await n; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:13:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await xn; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:15:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await nq; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:17:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await xnq; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:19:21: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is N) await x; // Error.
+//                     ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:20:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is N?) await x; // Error.
+//                      ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:21:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is XN) await x; // Error.
+//                      ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:22:23: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is XN?) await x; // Error.
+//                       ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+extension type N(asy::Future<core::int> _) {
+  abstract extension-type-member representation-field get _() → asy::Future<core::int>;
+  constructor • = self::N|constructor#;
+  constructor tearoff • = self::N|constructor#_#new#tearOff;
+}
+extension type F(asy::Future<core::int> _) implements asy::Future<core::int> {
+  abstract extension-type-member representation-field get _() → asy::Future<core::int>;
+  constructor • = self::F|constructor#;
+  constructor tearoff • = self::F|constructor#_#new#tearOff;
+}
+static extension-type-member method N|constructor#(asy::Future<core::int> _) → self::N /* = asy::Future<core::int> */ {
+  lowered final self::N /* = asy::Future<core::int> */ #this = _;
+  return #this;
+}
+static extension-type-member method N|constructor#_#new#tearOff(asy::Future<core::int> _) → self::N /* = asy::Future<core::int> */
+  return self::N|constructor#(_);
+static extension-type-member method F|constructor#(asy::Future<core::int> _) → self::F /* = asy::Future<core::int> */ {
+  lowered final self::F /* = asy::Future<core::int> */ #this = _;
+  return #this;
+}
+static extension-type-member method F|constructor#_#new#tearOff(asy::Future<core::int> _) → self::F /* = asy::Future<core::int> */
+  return self::F|constructor#(_);
+static method test<X extends core::Object? = dynamic, XN extends self::N /* = asy::Future<core::int> */, XF extends self::F /* = asy::Future<core::int> */>(self::N /* = asy::Future<core::int> */ n, self::F /* = asy::Future<core::int> */ f, self::test::X% x, self::test::XN% xn, self::test::XF xf, self::N? /* = asy::Future<core::int>? */ nq, self::F? /* = asy::Future<core::int>? */ fq, self::test::XN? xnq, self::test::XF? xfq) → void async /* emittedValueType= void */ {
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:10:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await n; // Error.
+        ^" in n /* runtimeCheckType= asy::Future<self::N /* = asy::Future<core::int> */> */ ;
+  await f;
+  await x /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:13:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await xn; // Error.
+        ^" in xn /* runtimeCheckType= asy::Future<self::test::XN%> */ ;
+  await xf;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:15:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await nq; // Error.
+        ^" in nq /* runtimeCheckType= asy::Future<self::N? /* = asy::Future<core::int>? */> */ ;
+  await fq /* runtimeCheckType= asy::Future<core::int?> */ ;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:17:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await xnq; // Error.
+        ^" in xnq /* runtimeCheckType= asy::Future<self::test::XN?> */ ;
+  await xfq /* runtimeCheckType= asy::Future<core::int?> */ ;
+  if(x is self::N /* = asy::Future<core::int> */)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:19:21: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is N) await x; // Error.
+                    ^" in x{self::test::X% & self::N /* = asy::Future<core::int> */ /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::N? /* = asy::Future<core::int>? */)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:20:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is N?) await x; // Error.
+                     ^" in x{self::test::X% & self::N? /* = asy::Future<core::int>? */ /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::test::XN%)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:21:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is XN) await x; // Error.
+                     ^" in x{self::test::X% & self::test::XN% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::test::XN?)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:22:23: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is XN?) await x; // Error.
+                      ^" in x{self::test::X% & self::test::XN? /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::F /* = asy::Future<core::int> */)
+    await x{self::test::X% & self::F /* = asy::Future<core::int> */ /* '%' & '!' = '!' */};
+  if(x is self::F? /* = asy::Future<core::int>? */)
+    await x{self::test::X% & self::F? /* = asy::Future<core::int>? */ /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+  if(x is self::test::XF)
+    await x{self::test::X% & self::test::XF /* '%' & '!' = '!' */};
+  if(x is self::test::XF?)
+    await x{self::test::X% & self::test::XF? /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+}
diff --git a/pkg/front_end/testcases/extension_types/issue54649.dart.textual_outline.expect b/pkg/front_end/testcases/extension_types/issue54649.dart.textual_outline.expect
new file mode 100644
index 0000000..4860e3b
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+extension type N(Future<int> _) {}
+
+extension type F(Future<int> _) implements Future<int> {}
+
+void test<X, XN extends N, XF extends F>(
+    N n, F f, X x, XN xn, XF xf, N? nq, F? fq, XN? xnq, XF? xfq) async {}
diff --git a/pkg/front_end/testcases/extension_types/issue54649.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extension_types/issue54649.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..e08eb87
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+extension type F(Future<int> _) implements Future<int> {}
+
+extension type N(Future<int> _) {}
+
+void test<X, XN extends N, XF extends F>(
+    N n, F f, X x, XN xn, XF xf, N? nq, F? fq, XN? xnq, XF? xfq) async {}
diff --git a/pkg/front_end/testcases/extension_types/issue54649.dart.weak.expect b/pkg/front_end/testcases/extension_types/issue54649.dart.weak.expect
new file mode 100644
index 0000000..0767237
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649.dart.weak.expect
@@ -0,0 +1,105 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:10:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await n; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:13:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await xn; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:15:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await nq; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:17:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await xnq; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:19:21: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is N) await x; // Error.
+//                     ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:20:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is N?) await x; // Error.
+//                      ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:21:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is XN) await x; // Error.
+//                      ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:22:23: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is XN?) await x; // Error.
+//                       ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+extension type N(asy::Future<core::int> _) {
+  abstract extension-type-member representation-field get _() → asy::Future<core::int>;
+  constructor • = self::N|constructor#;
+  constructor tearoff • = self::N|constructor#_#new#tearOff;
+}
+extension type F(asy::Future<core::int> _) implements asy::Future<core::int> {
+  abstract extension-type-member representation-field get _() → asy::Future<core::int>;
+  constructor • = self::F|constructor#;
+  constructor tearoff • = self::F|constructor#_#new#tearOff;
+}
+static extension-type-member method N|constructor#(asy::Future<core::int> _) → self::N /* = asy::Future<core::int> */ {
+  lowered final self::N /* = asy::Future<core::int> */ #this = _;
+  return #this;
+}
+static extension-type-member method N|constructor#_#new#tearOff(asy::Future<core::int> _) → self::N /* = asy::Future<core::int> */
+  return self::N|constructor#(_);
+static extension-type-member method F|constructor#(asy::Future<core::int> _) → self::F /* = asy::Future<core::int> */ {
+  lowered final self::F /* = asy::Future<core::int> */ #this = _;
+  return #this;
+}
+static extension-type-member method F|constructor#_#new#tearOff(asy::Future<core::int> _) → self::F /* = asy::Future<core::int> */
+  return self::F|constructor#(_);
+static method test<X extends core::Object? = dynamic, XN extends self::N /* = asy::Future<core::int> */, XF extends self::F /* = asy::Future<core::int> */>(self::N /* = asy::Future<core::int> */ n, self::F /* = asy::Future<core::int> */ f, self::test::X% x, self::test::XN% xn, self::test::XF xf, self::N? /* = asy::Future<core::int>? */ nq, self::F? /* = asy::Future<core::int>? */ fq, self::test::XN? xnq, self::test::XF? xfq) → void async /* emittedValueType= void */ {
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:10:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await n; // Error.
+        ^" in n /* runtimeCheckType= asy::Future<self::N /* = asy::Future<core::int> */> */ ;
+  await f;
+  await x /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:13:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await xn; // Error.
+        ^" in xn /* runtimeCheckType= asy::Future<self::test::XN%> */ ;
+  await xf;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:15:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await nq; // Error.
+        ^" in nq /* runtimeCheckType= asy::Future<self::N? /* = asy::Future<core::int>? */> */ ;
+  await fq /* runtimeCheckType= asy::Future<core::int?> */ ;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:17:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await xnq; // Error.
+        ^" in xnq /* runtimeCheckType= asy::Future<self::test::XN?> */ ;
+  await xfq /* runtimeCheckType= asy::Future<core::int?> */ ;
+  if(x is self::N /* = asy::Future<core::int> */)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:19:21: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is N) await x; // Error.
+                    ^" in x{self::test::X% & self::N /* = asy::Future<core::int> */ /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::N? /* = asy::Future<core::int>? */)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:20:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is N?) await x; // Error.
+                     ^" in x{self::test::X% & self::N? /* = asy::Future<core::int>? */ /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::test::XN%)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:21:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is XN) await x; // Error.
+                     ^" in x{self::test::X% & self::test::XN% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::test::XN?)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:22:23: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is XN?) await x; // Error.
+                      ^" in x{self::test::X% & self::test::XN? /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::F /* = asy::Future<core::int> */)
+    await x{self::test::X% & self::F /* = asy::Future<core::int> */ /* '%' & '!' = '!' */};
+  if(x is self::F? /* = asy::Future<core::int>? */)
+    await x{self::test::X% & self::F? /* = asy::Future<core::int>? */ /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+  if(x is self::test::XF)
+    await x{self::test::X% & self::test::XF /* '%' & '!' = '!' */};
+  if(x is self::test::XF?)
+    await x{self::test::X% & self::test::XF? /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+}
diff --git a/pkg/front_end/testcases/extension_types/issue54649.dart.weak.modular.expect b/pkg/front_end/testcases/extension_types/issue54649.dart.weak.modular.expect
new file mode 100644
index 0000000..0767237
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649.dart.weak.modular.expect
@@ -0,0 +1,105 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:10:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await n; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:13:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await xn; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:15:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await nq; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:17:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await xnq; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:19:21: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is N) await x; // Error.
+//                     ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:20:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is N?) await x; // Error.
+//                      ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:21:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is XN) await x; // Error.
+//                      ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:22:23: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is XN?) await x; // Error.
+//                       ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+extension type N(asy::Future<core::int> _) {
+  abstract extension-type-member representation-field get _() → asy::Future<core::int>;
+  constructor • = self::N|constructor#;
+  constructor tearoff • = self::N|constructor#_#new#tearOff;
+}
+extension type F(asy::Future<core::int> _) implements asy::Future<core::int> {
+  abstract extension-type-member representation-field get _() → asy::Future<core::int>;
+  constructor • = self::F|constructor#;
+  constructor tearoff • = self::F|constructor#_#new#tearOff;
+}
+static extension-type-member method N|constructor#(asy::Future<core::int> _) → self::N /* = asy::Future<core::int> */ {
+  lowered final self::N /* = asy::Future<core::int> */ #this = _;
+  return #this;
+}
+static extension-type-member method N|constructor#_#new#tearOff(asy::Future<core::int> _) → self::N /* = asy::Future<core::int> */
+  return self::N|constructor#(_);
+static extension-type-member method F|constructor#(asy::Future<core::int> _) → self::F /* = asy::Future<core::int> */ {
+  lowered final self::F /* = asy::Future<core::int> */ #this = _;
+  return #this;
+}
+static extension-type-member method F|constructor#_#new#tearOff(asy::Future<core::int> _) → self::F /* = asy::Future<core::int> */
+  return self::F|constructor#(_);
+static method test<X extends core::Object? = dynamic, XN extends self::N /* = asy::Future<core::int> */, XF extends self::F /* = asy::Future<core::int> */>(self::N /* = asy::Future<core::int> */ n, self::F /* = asy::Future<core::int> */ f, self::test::X% x, self::test::XN% xn, self::test::XF xf, self::N? /* = asy::Future<core::int>? */ nq, self::F? /* = asy::Future<core::int>? */ fq, self::test::XN? xnq, self::test::XF? xfq) → void async /* emittedValueType= void */ {
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:10:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await n; // Error.
+        ^" in n /* runtimeCheckType= asy::Future<self::N /* = asy::Future<core::int> */> */ ;
+  await f;
+  await x /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:13:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await xn; // Error.
+        ^" in xn /* runtimeCheckType= asy::Future<self::test::XN%> */ ;
+  await xf;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:15:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await nq; // Error.
+        ^" in nq /* runtimeCheckType= asy::Future<self::N? /* = asy::Future<core::int>? */> */ ;
+  await fq /* runtimeCheckType= asy::Future<core::int?> */ ;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:17:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await xnq; // Error.
+        ^" in xnq /* runtimeCheckType= asy::Future<self::test::XN?> */ ;
+  await xfq /* runtimeCheckType= asy::Future<core::int?> */ ;
+  if(x is self::N /* = asy::Future<core::int> */)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:19:21: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is N) await x; // Error.
+                    ^" in x{self::test::X% & self::N /* = asy::Future<core::int> */ /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::N? /* = asy::Future<core::int>? */)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:20:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is N?) await x; // Error.
+                     ^" in x{self::test::X% & self::N? /* = asy::Future<core::int>? */ /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::test::XN%)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:21:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is XN) await x; // Error.
+                     ^" in x{self::test::X% & self::test::XN% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::test::XN?)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:22:23: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is XN?) await x; // Error.
+                      ^" in x{self::test::X% & self::test::XN? /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::F /* = asy::Future<core::int> */)
+    await x{self::test::X% & self::F /* = asy::Future<core::int> */ /* '%' & '!' = '!' */};
+  if(x is self::F? /* = asy::Future<core::int>? */)
+    await x{self::test::X% & self::F? /* = asy::Future<core::int>? */ /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+  if(x is self::test::XF)
+    await x{self::test::X% & self::test::XF /* '%' & '!' = '!' */};
+  if(x is self::test::XF?)
+    await x{self::test::X% & self::test::XF? /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+}
diff --git a/pkg/front_end/testcases/extension_types/issue54649.dart.weak.outline.expect b/pkg/front_end/testcases/extension_types/issue54649.dart.weak.outline.expect
new file mode 100644
index 0000000..49a3fbf
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649.dart.weak.outline.expect
@@ -0,0 +1,25 @@
+library;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+extension type N(asy::Future<core::int> _) {
+  abstract extension-type-member representation-field get _() → asy::Future<core::int>;
+  constructor • = self::N|constructor#;
+  constructor tearoff • = self::N|constructor#_#new#tearOff;
+}
+extension type F(asy::Future<core::int> _) implements asy::Future<core::int> {
+  abstract extension-type-member representation-field get _() → asy::Future<core::int>;
+  constructor • = self::F|constructor#;
+  constructor tearoff • = self::F|constructor#_#new#tearOff;
+}
+static extension-type-member method N|constructor#(asy::Future<core::int> _) → self::N /* = asy::Future<core::int> */
+  ;
+static extension-type-member method N|constructor#_#new#tearOff(asy::Future<core::int> _) → self::N /* = asy::Future<core::int> */
+  return self::N|constructor#(_);
+static extension-type-member method F|constructor#(asy::Future<core::int> _) → self::F /* = asy::Future<core::int> */
+  ;
+static extension-type-member method F|constructor#_#new#tearOff(asy::Future<core::int> _) → self::F /* = asy::Future<core::int> */
+  return self::F|constructor#(_);
+static method test<X extends core::Object? = dynamic, XN extends self::N /* = asy::Future<core::int> */, XF extends self::F /* = asy::Future<core::int> */>(self::N /* = asy::Future<core::int> */ n, self::F /* = asy::Future<core::int> */ f, self::test::X% x, self::test::XN% xn, self::test::XF xf, self::N? /* = asy::Future<core::int>? */ nq, self::F? /* = asy::Future<core::int>? */ fq, self::test::XN? xnq, self::test::XF? xfq) → void async 
+  ;
diff --git a/pkg/front_end/testcases/extension_types/issue54649.dart.weak.transformed.expect b/pkg/front_end/testcases/extension_types/issue54649.dart.weak.transformed.expect
new file mode 100644
index 0000000..0767237
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649.dart.weak.transformed.expect
@@ -0,0 +1,105 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:10:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await n; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:13:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await xn; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:15:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await nq; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:17:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   await xnq; // Error.
+//         ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:19:21: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is N) await x; // Error.
+//                     ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:20:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is N?) await x; // Error.
+//                      ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:21:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is XN) await x; // Error.
+//                      ^
+//
+// pkg/front_end/testcases/extension_types/issue54649.dart:22:23: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+//   if (x is XN?) await x; // Error.
+//                       ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+extension type N(asy::Future<core::int> _) {
+  abstract extension-type-member representation-field get _() → asy::Future<core::int>;
+  constructor • = self::N|constructor#;
+  constructor tearoff • = self::N|constructor#_#new#tearOff;
+}
+extension type F(asy::Future<core::int> _) implements asy::Future<core::int> {
+  abstract extension-type-member representation-field get _() → asy::Future<core::int>;
+  constructor • = self::F|constructor#;
+  constructor tearoff • = self::F|constructor#_#new#tearOff;
+}
+static extension-type-member method N|constructor#(asy::Future<core::int> _) → self::N /* = asy::Future<core::int> */ {
+  lowered final self::N /* = asy::Future<core::int> */ #this = _;
+  return #this;
+}
+static extension-type-member method N|constructor#_#new#tearOff(asy::Future<core::int> _) → self::N /* = asy::Future<core::int> */
+  return self::N|constructor#(_);
+static extension-type-member method F|constructor#(asy::Future<core::int> _) → self::F /* = asy::Future<core::int> */ {
+  lowered final self::F /* = asy::Future<core::int> */ #this = _;
+  return #this;
+}
+static extension-type-member method F|constructor#_#new#tearOff(asy::Future<core::int> _) → self::F /* = asy::Future<core::int> */
+  return self::F|constructor#(_);
+static method test<X extends core::Object? = dynamic, XN extends self::N /* = asy::Future<core::int> */, XF extends self::F /* = asy::Future<core::int> */>(self::N /* = asy::Future<core::int> */ n, self::F /* = asy::Future<core::int> */ f, self::test::X% x, self::test::XN% xn, self::test::XF xf, self::N? /* = asy::Future<core::int>? */ nq, self::F? /* = asy::Future<core::int>? */ fq, self::test::XN? xnq, self::test::XF? xfq) → void async /* emittedValueType= void */ {
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:10:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await n; // Error.
+        ^" in n /* runtimeCheckType= asy::Future<self::N /* = asy::Future<core::int> */> */ ;
+  await f;
+  await x /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:13:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await xn; // Error.
+        ^" in xn /* runtimeCheckType= asy::Future<self::test::XN%> */ ;
+  await xf;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:15:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await nq; // Error.
+        ^" in nq /* runtimeCheckType= asy::Future<self::N? /* = asy::Future<core::int>? */> */ ;
+  await fq /* runtimeCheckType= asy::Future<core::int?> */ ;
+  await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:17:9: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  await xnq; // Error.
+        ^" in xnq /* runtimeCheckType= asy::Future<self::test::XN?> */ ;
+  await xfq /* runtimeCheckType= asy::Future<core::int?> */ ;
+  if(x is self::N /* = asy::Future<core::int> */)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:19:21: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is N) await x; // Error.
+                    ^" in x{self::test::X% & self::N /* = asy::Future<core::int> */ /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::N? /* = asy::Future<core::int>? */)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:20:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is N?) await x; // Error.
+                     ^" in x{self::test::X% & self::N? /* = asy::Future<core::int>? */ /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::test::XN%)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:21:22: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is XN) await x; // Error.
+                     ^" in x{self::test::X% & self::test::XN% /* '%' & '%' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::test::XN?)
+    await invalid-expression "pkg/front_end/testcases/extension_types/issue54649.dart:22:23: Error: The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'.
+  if (x is XN?) await x; // Error.
+                      ^" in x{self::test::X% & self::test::XN? /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<self::test::X%> */ ;
+  if(x is self::F /* = asy::Future<core::int> */)
+    await x{self::test::X% & self::F /* = asy::Future<core::int> */ /* '%' & '!' = '!' */};
+  if(x is self::F? /* = asy::Future<core::int>? */)
+    await x{self::test::X% & self::F? /* = asy::Future<core::int>? */ /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+  if(x is self::test::XF)
+    await x{self::test::X% & self::test::XF /* '%' & '!' = '!' */};
+  if(x is self::test::XF?)
+    await x{self::test::X% & self::test::XF? /* '%' & '?' = '%' */} /* runtimeCheckType= asy::Future<core::int?> */ ;
+}
diff --git a/pkg/front_end/testcases/extension_types/issue54649_2.dart b/pkg/front_end/testcases/extension_types/issue54649_2.dart
new file mode 100644
index 0000000..375c4d0
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2024, 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.
+
+extension type E1(Future<int> it) {}
+
+extension type E2(Future<int> it) implements E1, Future<int> {}
+
+extension type E3(Future<int> it) implements Future<int> {}
+
+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.
+  if (x is Y) {
+    await x; // Ok.
+  }
+}
+
+test3<X extends E3?, Y extends E3>(X x) async {
+  // `X` is compatible with await.
+  // `Y` derives a future type.
+  if (x is Y) {
+    await x; // Ok.
+  }
+}
+
+test4<X extends E1, Y extends X>(X x) async {
+  // `X` is incompatible with await.
+  // `Y` does not derive a future type.
+  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
new file mode 100644
index 0000000..344b074
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.strong.expect
@@ -0,0 +1,73 @@
+library;
+//
+// 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'.
+//     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'.
+//     await x; // Error.
+//           ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+extension type E1(asy::Future<core::int> it) {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E1|constructor#;
+  constructor tearoff • = self::E1|constructor#_#new#tearOff;
+}
+extension type E2(asy::Future<core::int> it) implements self::E1 /* = asy::Future<core::int> */, asy::Future<core::int> {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E2|constructor#;
+  constructor tearoff • = self::E2|constructor#_#new#tearOff;
+}
+extension type E3(asy::Future<core::int> it) implements asy::Future<core::int> {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E3|constructor#;
+  constructor tearoff • = self::E3|constructor#_#new#tearOff;
+}
+static extension-type-member method E1|constructor#(asy::Future<core::int> it) → self::E1 /* = asy::Future<core::int> */ {
+  lowered final self::E1 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E1|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E1 /* = asy::Future<core::int> */
+  return self::E1|constructor#(it);
+static extension-type-member method E2|constructor#(asy::Future<core::int> it) → self::E2 /* = asy::Future<core::int> */ {
+  lowered final self::E2 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E2|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E2 /* = asy::Future<core::int> */
+  return self::E2|constructor#(it);
+static extension-type-member method E3|constructor#(asy::Future<core::int> it) → self::E3 /* = asy::Future<core::int> */ {
+  lowered final self::E3 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E3|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E3 /* = asy::Future<core::int> */
+  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 /* '%' & '!' = '!' */};
+  }
+}
+static method test2<X extends self::E3? /* = asy::Future<core::int>? */, Y extends Null>(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?> */ ;
+  }
+}
+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 */ {
+  if(x is self::test3::Y) {
+    await x{self::test3::X% & self::test3::Y /* '%' & '!' = '!' */};
+  }
+}
+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 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
new file mode 100644
index 0000000..344b074
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.strong.transformed.expect
@@ -0,0 +1,73 @@
+library;
+//
+// 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'.
+//     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'.
+//     await x; // Error.
+//           ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+extension type E1(asy::Future<core::int> it) {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E1|constructor#;
+  constructor tearoff • = self::E1|constructor#_#new#tearOff;
+}
+extension type E2(asy::Future<core::int> it) implements self::E1 /* = asy::Future<core::int> */, asy::Future<core::int> {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E2|constructor#;
+  constructor tearoff • = self::E2|constructor#_#new#tearOff;
+}
+extension type E3(asy::Future<core::int> it) implements asy::Future<core::int> {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E3|constructor#;
+  constructor tearoff • = self::E3|constructor#_#new#tearOff;
+}
+static extension-type-member method E1|constructor#(asy::Future<core::int> it) → self::E1 /* = asy::Future<core::int> */ {
+  lowered final self::E1 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E1|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E1 /* = asy::Future<core::int> */
+  return self::E1|constructor#(it);
+static extension-type-member method E2|constructor#(asy::Future<core::int> it) → self::E2 /* = asy::Future<core::int> */ {
+  lowered final self::E2 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E2|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E2 /* = asy::Future<core::int> */
+  return self::E2|constructor#(it);
+static extension-type-member method E3|constructor#(asy::Future<core::int> it) → self::E3 /* = asy::Future<core::int> */ {
+  lowered final self::E3 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E3|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E3 /* = asy::Future<core::int> */
+  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 /* '%' & '!' = '!' */};
+  }
+}
+static method test2<X extends self::E3? /* = asy::Future<core::int>? */, Y extends Null>(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?> */ ;
+  }
+}
+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 */ {
+  if(x is self::test3::Y) {
+    await x{self::test3::X% & self::test3::Y /* '%' & '!' = '!' */};
+  }
+}
+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 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
new file mode 100644
index 0000000..c866879
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.textual_outline.expect
@@ -0,0 +1,13 @@
+extension type E1(Future<int> it) {}
+
+extension type E2(Future<int> it) implements E1, Future<int> {}
+
+extension type E3(Future<int> it) implements Future<int> {}
+
+test1<X extends E1, Y extends E2>(X x) async {}
+
+test2<X extends E3?, Y extends Null>(X x) async {}
+
+test3<X extends E3?, Y extends E3>(X x) async {}
+
+test4<X extends E1, Y extends X>(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
new file mode 100644
index 0000000..c866879
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.textual_outline_modelled.expect
@@ -0,0 +1,13 @@
+extension type E1(Future<int> it) {}
+
+extension type E2(Future<int> it) implements E1, Future<int> {}
+
+extension type E3(Future<int> it) implements Future<int> {}
+
+test1<X extends E1, Y extends E2>(X x) async {}
+
+test2<X extends E3?, Y extends Null>(X x) async {}
+
+test3<X extends E3?, Y extends E3>(X x) async {}
+
+test4<X extends E1, Y extends X>(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
new file mode 100644
index 0000000..344b074
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.expect
@@ -0,0 +1,73 @@
+library;
+//
+// 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'.
+//     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'.
+//     await x; // Error.
+//           ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+extension type E1(asy::Future<core::int> it) {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E1|constructor#;
+  constructor tearoff • = self::E1|constructor#_#new#tearOff;
+}
+extension type E2(asy::Future<core::int> it) implements self::E1 /* = asy::Future<core::int> */, asy::Future<core::int> {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E2|constructor#;
+  constructor tearoff • = self::E2|constructor#_#new#tearOff;
+}
+extension type E3(asy::Future<core::int> it) implements asy::Future<core::int> {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E3|constructor#;
+  constructor tearoff • = self::E3|constructor#_#new#tearOff;
+}
+static extension-type-member method E1|constructor#(asy::Future<core::int> it) → self::E1 /* = asy::Future<core::int> */ {
+  lowered final self::E1 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E1|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E1 /* = asy::Future<core::int> */
+  return self::E1|constructor#(it);
+static extension-type-member method E2|constructor#(asy::Future<core::int> it) → self::E2 /* = asy::Future<core::int> */ {
+  lowered final self::E2 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E2|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E2 /* = asy::Future<core::int> */
+  return self::E2|constructor#(it);
+static extension-type-member method E3|constructor#(asy::Future<core::int> it) → self::E3 /* = asy::Future<core::int> */ {
+  lowered final self::E3 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E3|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E3 /* = asy::Future<core::int> */
+  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 /* '%' & '!' = '!' */};
+  }
+}
+static method test2<X extends self::E3? /* = asy::Future<core::int>? */, Y extends Null>(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?> */ ;
+  }
+}
+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 */ {
+  if(x is self::test3::Y) {
+    await x{self::test3::X% & self::test3::Y /* '%' & '!' = '!' */};
+  }
+}
+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 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
new file mode 100644
index 0000000..344b074
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.modular.expect
@@ -0,0 +1,73 @@
+library;
+//
+// 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'.
+//     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'.
+//     await x; // Error.
+//           ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+extension type E1(asy::Future<core::int> it) {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E1|constructor#;
+  constructor tearoff • = self::E1|constructor#_#new#tearOff;
+}
+extension type E2(asy::Future<core::int> it) implements self::E1 /* = asy::Future<core::int> */, asy::Future<core::int> {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E2|constructor#;
+  constructor tearoff • = self::E2|constructor#_#new#tearOff;
+}
+extension type E3(asy::Future<core::int> it) implements asy::Future<core::int> {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E3|constructor#;
+  constructor tearoff • = self::E3|constructor#_#new#tearOff;
+}
+static extension-type-member method E1|constructor#(asy::Future<core::int> it) → self::E1 /* = asy::Future<core::int> */ {
+  lowered final self::E1 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E1|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E1 /* = asy::Future<core::int> */
+  return self::E1|constructor#(it);
+static extension-type-member method E2|constructor#(asy::Future<core::int> it) → self::E2 /* = asy::Future<core::int> */ {
+  lowered final self::E2 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E2|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E2 /* = asy::Future<core::int> */
+  return self::E2|constructor#(it);
+static extension-type-member method E3|constructor#(asy::Future<core::int> it) → self::E3 /* = asy::Future<core::int> */ {
+  lowered final self::E3 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E3|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E3 /* = asy::Future<core::int> */
+  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 /* '%' & '!' = '!' */};
+  }
+}
+static method test2<X extends self::E3? /* = asy::Future<core::int>? */, Y extends Null>(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?> */ ;
+  }
+}
+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 */ {
+  if(x is self::test3::Y) {
+    await x{self::test3::X% & self::test3::Y /* '%' & '!' = '!' */};
+  }
+}
+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 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
new file mode 100644
index 0000000..73f7135
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.outline.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+extension type E1(asy::Future<core::int> it) {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E1|constructor#;
+  constructor tearoff • = self::E1|constructor#_#new#tearOff;
+}
+extension type E2(asy::Future<core::int> it) implements self::E1 /* = asy::Future<core::int> */, asy::Future<core::int> {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E2|constructor#;
+  constructor tearoff • = self::E2|constructor#_#new#tearOff;
+}
+extension type E3(asy::Future<core::int> it) implements asy::Future<core::int> {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E3|constructor#;
+  constructor tearoff • = self::E3|constructor#_#new#tearOff;
+}
+static extension-type-member method E1|constructor#(asy::Future<core::int> it) → self::E1 /* = asy::Future<core::int> */
+  ;
+static extension-type-member method E1|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E1 /* = asy::Future<core::int> */
+  return self::E1|constructor#(it);
+static extension-type-member method E2|constructor#(asy::Future<core::int> it) → self::E2 /* = asy::Future<core::int> */
+  ;
+static extension-type-member method E2|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E2 /* = asy::Future<core::int> */
+  return self::E2|constructor#(it);
+static extension-type-member method E3|constructor#(asy::Future<core::int> it) → self::E3 /* = asy::Future<core::int> */
+  ;
+static extension-type-member method E3|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E3 /* = asy::Future<core::int> */
+  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 test3<X extends self::E3? /* = asy::Future<core::int>? */, Y extends self::E3 /* = asy::Future<core::int> */>(self::test3::X% x) → dynamic async 
+  ;
+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 
+  ;
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
new file mode 100644
index 0000000..344b074
--- /dev/null
+++ b/pkg/front_end/testcases/extension_types/issue54649_2.dart.weak.transformed.expect
@@ -0,0 +1,73 @@
+library;
+//
+// 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'.
+//     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'.
+//     await x; // Error.
+//           ^
+//
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+extension type E1(asy::Future<core::int> it) {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E1|constructor#;
+  constructor tearoff • = self::E1|constructor#_#new#tearOff;
+}
+extension type E2(asy::Future<core::int> it) implements self::E1 /* = asy::Future<core::int> */, asy::Future<core::int> {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E2|constructor#;
+  constructor tearoff • = self::E2|constructor#_#new#tearOff;
+}
+extension type E3(asy::Future<core::int> it) implements asy::Future<core::int> {
+  abstract extension-type-member representation-field get it() → asy::Future<core::int>;
+  constructor • = self::E3|constructor#;
+  constructor tearoff • = self::E3|constructor#_#new#tearOff;
+}
+static extension-type-member method E1|constructor#(asy::Future<core::int> it) → self::E1 /* = asy::Future<core::int> */ {
+  lowered final self::E1 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E1|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E1 /* = asy::Future<core::int> */
+  return self::E1|constructor#(it);
+static extension-type-member method E2|constructor#(asy::Future<core::int> it) → self::E2 /* = asy::Future<core::int> */ {
+  lowered final self::E2 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E2|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E2 /* = asy::Future<core::int> */
+  return self::E2|constructor#(it);
+static extension-type-member method E3|constructor#(asy::Future<core::int> it) → self::E3 /* = asy::Future<core::int> */ {
+  lowered final self::E3 /* = asy::Future<core::int> */ #this = it;
+  return #this;
+}
+static extension-type-member method E3|constructor#_#new#tearOff(asy::Future<core::int> it) → self::E3 /* = asy::Future<core::int> */
+  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 /* '%' & '!' = '!' */};
+  }
+}
+static method test2<X extends self::E3? /* = asy::Future<core::int>? */, Y extends Null>(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?> */ ;
+  }
+}
+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 */ {
+  if(x is self::test3::Y) {
+    await x{self::test3::X% & self::test3::Y /* '%' & '!' = '!' */};
+  }
+}
+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 x; // Error.
+          ^" in x{self::test4::Y%} /* runtimeCheckType= asy::Future<self::test4::Y%> */ ;
+  }
+}