[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%> */ ;
+ }
+}