[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>
This commit is contained in:
Chloe Stefantsova 2024-01-29 13:48:39 +00:00 committed by Commit Queue
parent a2ee738dfc
commit 1672177c20
21 changed files with 1173 additions and 6 deletions

View file

@ -807,6 +807,108 @@ class InferenceVisitorImpl extends InferenceVisitorBase
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 @@ class InferenceVisitorImpl extends InferenceVisitorBase
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);

View file

@ -833,6 +833,7 @@ dereferenced
derivation
derive
derived
derives
descendant
descendants
describe

View file

@ -336,6 +336,7 @@ forty
fortytwo
foundation
fox
fq
frequency
frozen
fruits
@ -525,6 +526,7 @@ nonexisting
noo
noted
nottest
nq
null'ed
numerator
nums
@ -584,6 +586,7 @@ pooled
population
portions
pp
pr
preliminary
prematurely
prerequisite
@ -836,7 +839,9 @@ wrongly
ws
x's
xf
xfq
xlate
xnq
xrequired
xxx
xxxxxxxx

View file

@ -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?`.
}

View file

@ -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?> */ ;
}

View file

@ -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?> */ ;
}

View file

@ -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 {}

View file

@ -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 {}

View file

@ -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?> */ ;
}

View file

@ -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?> */ ;
}

View file

@ -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
;

View file

@ -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?> */ ;
}

View file

@ -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.
}
}

View file

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

View file

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

View file

@ -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 {}

View file

@ -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 {}

View file

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

View file

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

View file

@ -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
;

View file

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