Skip to content

Commit 849ebaf

Browse files
a-sivaathomas
authored andcommitted
Revert "[cfe] Handle conditional await in CFE"
This reverts commit 14032a6. Reason for revert : Several customer flutter tests are failing because of the change in behavior. TEST=revert of previous CL. Change-Id: Ia235aa93b9c81fbab066803dc0625856f93acceb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/181860 Commit-Queue: Siva Annamalai <[email protected]> Reviewed-by: Leaf Petersen <[email protected]> Reviewed-by: Siva Annamalai <[email protected]>
1 parent b9ee9e8 commit 849ebaf

File tree

76 files changed

+428
-3478
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+428
-3478
lines changed

pkg/front_end/lib/src/fasta/type_inference/closure_context.dart

Lines changed: 24 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -546,75 +546,30 @@ class _AsyncClosureContext implements ClosureContext {
546546
statement.expression.fileOffset,
547547
noLength)
548548
..parent = statement;
549-
} else {
550-
DartType futureOrType =
551-
inferrer.computeGreatestClosure2(_returnContext);
552-
if (flattenedExpressionType is! VoidType &&
553-
!inferrer.typeSchemaEnvironment
554-
.performNullabilityAwareSubtypeCheck(
555-
flattenedExpressionType, futureValueType)
556-
.isSubtypeWhenUsingNullabilities()) {
557-
// It is a compile-time error if s is `return e;`, flatten(S) is not
558-
// void, S is not assignable to T_v, and flatten(S) is not a subtype
559-
// of T_v.
560-
statement.expression = inferrer.ensureAssignable(
561-
futureValueType, expressionType, statement.expression,
562-
fileOffset: statement.expression.fileOffset,
563-
runtimeCheckedType: futureOrType,
564-
declaredContextType: returnType,
565-
isVoidAllowed: false,
566-
errorTemplate: templateInvalidReturnAsync,
567-
nullabilityErrorTemplate: templateInvalidReturnAsyncNullability,
568-
nullabilityPartErrorTemplate:
569-
templateInvalidReturnAsyncPartNullability,
570-
nullabilityNullErrorTemplate:
571-
templateInvalidReturnAsyncNullabilityNull,
572-
nullabilityNullTypeErrorTemplate:
573-
templateInvalidReturnAsyncNullabilityNullType)
574-
..parent = statement;
575-
}
576-
// For `return e`:
577-
// When `f` is an asynchronous non-generator with future value type
578-
// T_v, evaluation proceeds as follows:
579-
//
580-
// The expression `e` is evaluated to an object `o`.
581-
// If the run-time type of `o` is a subtype of `Future<T_v>`,
582-
// let `v` be a fresh variable bound to `o` and
583-
// evaluate `await v` to an object `r`;
584-
// otherwise let `r` be `o`.
585-
// A dynamic error occurs unless the dynamic type of `r`
586-
// is a subtype of the actual value of T_v.
587-
// Then the return statement `s` completes returning `r`.
588-
DartType futureType = new InterfaceType(
589-
inferrer.coreTypes.futureClass,
590-
Nullability.nonNullable,
591-
[futureValueType]);
592-
VariableDeclaration variable;
593-
Expression isOperand;
594-
Expression awaitOperand;
595-
Expression resultExpression;
596-
if (isPureExpression(statement.expression)) {
597-
isOperand = clonePureExpression(statement.expression);
598-
awaitOperand = clonePureExpression(statement.expression);
599-
resultExpression = statement.expression;
600-
} else {
601-
variable = createVariable(statement.expression, expressionType);
602-
isOperand = createVariableGet(variable);
603-
awaitOperand = createVariableGet(variable);
604-
resultExpression = createVariableGet(variable);
605-
}
606-
Expression replacement = new ConditionalExpression(
607-
new IsExpression(isOperand, futureType)
608-
..fileOffset = statement.fileOffset,
609-
new AwaitExpression(awaitOperand)
610-
..fileOffset = statement.fileOffset,
611-
resultExpression,
612-
futureOrType)
613-
..fileOffset = statement.fileOffset;
614-
if (variable != null) {
615-
replacement = createLet(variable, replacement);
616-
}
617-
statement.expression = replacement..parent = statement;
549+
} else if (flattenedExpressionType is! VoidType &&
550+
!inferrer.typeSchemaEnvironment
551+
.performNullabilityAwareSubtypeCheck(
552+
flattenedExpressionType, futureValueType)
553+
.isSubtypeWhenUsingNullabilities()) {
554+
// It is a compile-time error if s is `return e;`, flatten(S) is not
555+
// void, S is not assignable to T_v, and flatten(S) is not a subtype
556+
// of T_v.
557+
statement.expression = inferrer.ensureAssignable(
558+
futureValueType, expressionType, statement.expression,
559+
fileOffset: statement.expression.fileOffset,
560+
runtimeCheckedType:
561+
inferrer.computeGreatestClosure2(_returnContext),
562+
declaredContextType: returnType,
563+
isVoidAllowed: false,
564+
errorTemplate: templateInvalidReturnAsync,
565+
nullabilityErrorTemplate: templateInvalidReturnAsyncNullability,
566+
nullabilityPartErrorTemplate:
567+
templateInvalidReturnAsyncPartNullability,
568+
nullabilityNullErrorTemplate:
569+
templateInvalidReturnAsyncNullabilityNull,
570+
nullabilityNullTypeErrorTemplate:
571+
templateInvalidReturnAsyncNullabilityNullType)
572+
..parent = statement;
618573
}
619574
}
620575
} else {

pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2514,13 +2514,16 @@ class TypeInferrerImpl implements TypeInferrer {
25142514
// `void` if `B’` contains no `yield` expressions. Otherwise, let `M` be
25152515
// the least upper bound of the types of the `return` expressions in `B’`,
25162516
// or `void` if `B’` contains no `return` expressions.
2517+
DartType inferredReturnType;
25172518
if (needToSetReturnType) {
2518-
DartType inferredReturnType = closureContext.inferReturnType(this,
2519+
inferredReturnType = closureContext.inferReturnType(this,
25192520
hasImplicitReturn: flowAnalysis.isReachable);
2521+
}
25202522

2521-
// Then the result of inference is `<T0, ..., Tn>(R0 x0, ..., Rn xn) B`
2522-
// with type `<T0, ..., Tn>(R0, ..., Rn) -> M'` (with some of the `Ri` and
2523-
// `xi` denoted as optional or named parameters, if appropriate).
2523+
// Then the result of inference is `<T0, ..., Tn>(R0 x0, ..., Rn xn) B` with
2524+
// type `<T0, ..., Tn>(R0, ..., Rn) -> M’` (with some of the `Ri` and `xi`
2525+
// denoted as optional or named parameters, if appropriate).
2526+
if (needToSetReturnType) {
25242527
instrumentation?.record(uriForInstrumentation, fileOffset, 'returnType',
25252528
new InstrumentationValueForType(inferredReturnType));
25262529
function.returnType = inferredReturnType;

pkg/front_end/test/spell_checking_list_code.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,6 @@ printer
868868
printf
869869
println
870870
proc
871-
proceeds
872871
producers
873872
product
874873
progresses

pkg/front_end/test/spell_checking_list_tests.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,6 @@ ugly
737737
unassignment
738738
unawaited
739739
unbreak
740-
uncaught
741740
unconverted
742741
uncover
743742
uncovers

pkg/front_end/test/text_representation/data/expressions.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,9 +382,7 @@ exprEmptyTypedMap() => <int, String>{};
382382
exprMap() => {0: "foo", 1: "bar"};
383383

384384
/*member: exprAwait:await o*/
385-
exprAwait(o) async {
386-
await o;
387-
}
385+
exprAwait(o) async => await o;
388386

389387
/*member: exprLoadLibrary:prefix.loadLibrary()*/
390388
exprLoadLibrary() => prefix.loadLibrary();

pkg/front_end/test/text_representation/text_representation_test.dart

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,16 +156,14 @@ class TextRepresentationDataExtractor extends CfeDataExtractor<String> {
156156

157157
@override
158158
String computeMemberValue(Id id, Member node) {
159+
if (node.name.text == 'stmtVariableDeclarationMulti') {
160+
print(node);
161+
}
159162
if (node.name.text.startsWith(expressionMarker)) {
160163
if (node is Procedure) {
161164
Statement body = node.function.body;
162165
if (body is ReturnStatement) {
163166
return body.expression.toText(strategy);
164-
} else if (body is Block &&
165-
body.statements.isNotEmpty &&
166-
body.statements.first is ExpressionStatement) {
167-
ExpressionStatement statement = body.statements.first;
168-
return statement.expression.toText(strategy);
169167
}
170168
} else if (node is Field && node.initializer != null) {
171169
return node.initializer.toText(strategy);

pkg/front_end/testcases/late_lowering/later.dart.strong.expect

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -134,28 +134,28 @@ static method hest() → dynamic async {
134134
await for (core::String s in asy::Stream::fromIterable<core::String>(<core::String>["hest"])) {
135135
core::print(s);
136136
}
137-
return let final core::String #t8 = "hest" in #t8 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t8 : #t8;
137+
return "hest";
138138
}
139139
static method fisk() → dynamic async {
140140
lowered core::String? #s1;
141141
function #s1#get() → core::String
142-
return let final core::String? #t9 = #s1 in #t9.==(null) ?{core::String} #s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
142+
return let final core::String? #t8 = #s1 in #t8.==(null) ?{core::String} #s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
143143
late String s1 = await hest(); // Error.
144-
^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::String : #t9{core::String};
145-
function #s1#set(core::String #t10) → dynamic
146-
return #s1 = #t10;
144+
^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::String : #t8{core::String};
145+
function #s1#set(core::String #t9) → dynamic
146+
return #s1 = #t9;
147147
lowered core::String? #s2;
148148
function #s2#get() → core::String
149-
return let final core::String? #t11 = #s2 in #t11.==(null) ?{core::String} #s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
149+
return let final core::String? #t10 = #s2 in #t10.==(null) ?{core::String} #s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
150150
late String s2 = '\${fisk}\${await hest()}\${fisk}'; // Error.
151-
^^^^^"}${#C1}" : #t11{core::String};
152-
function #s2#set(core::String #t12) → dynamic
153-
return #s2 = #t12;
151+
^^^^^"}${#C1}" : #t10{core::String};
152+
function #s2#set(core::String #t11) → dynamic
153+
return #s2 = #t11;
154154
lowered core::Function? #f;
155155
function #f#get() → core::Function
156-
return let final core::Function? #t13 = #f in #t13.==(null) ?{core::Function} #f = () → asy::Future<dynamic> async => let final dynamic #t14 = await self::hest() in #t14 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t14 : #t14 : #t13{core::Function};
157-
function #f#set(core::Function #t15) → dynamic
158-
return #f = #t15;
156+
return let final core::Function? #t12 = #f in #t12.==(null) ?{core::Function} #f = () → asy::Future<dynamic> async => await self::hest() : #t12{core::Function};
157+
function #f#set(core::Function #t13) → dynamic
158+
return #f = #t13;
159159
}
160160
static method main() → dynamic {}
161161

pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,6 @@ static method hest() → dynamic /* originally async */ {
148148
dynamic :saved_try_context_var1;
149149
dynamic :exception0;
150150
dynamic :stack_trace0;
151-
FutureOr<dynamic>:async_temporary_0;
152-
FutureOr<dynamic>:async_temporary_1;
153151
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
154152
try {
155153
#L1:
@@ -177,15 +175,7 @@ static method hest() → dynamic /* originally async */ {
177175
:result;
178176
}
179177
}
180-
final core::String #t11 = "hest";
181-
if(#t11 is asy::Future<dynamic>) {
182-
[yield] let dynamic #t12 = asy::_awaitHelper(#t11, :async_op_then, :async_op_error, :async_op) in null;
183-
:async_temporary_1 = _in::unsafeCast<core::String>(:result);
184-
}
185-
else {
186-
:async_temporary_1 = #t11;
187-
}
188-
:return_value = :async_temporary_1;
178+
:return_value = "hest";
189179
break #L1;
190180
}
191181
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -214,21 +204,21 @@ static method fisk() → dynamic /* originally async */ {
214204
{
215205
lowered core::String? #s1;
216206
function #s1#get() → core::String
217-
return let final core::String? #t13 = #s1 in #t13.==(null) ?{core::String} #s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
207+
return let final core::String? #t11 = #s1 in #t11.==(null) ?{core::String} #s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
218208
late String s1 = await hest(); // Error.
219-
^^^^^" : #t13{core::String};
220-
function #s1#set(core::String #t14) → dynamic
221-
return #s1 = #t14;
209+
^^^^^" : #t11{core::String};
210+
function #s1#set(core::String #t12) → dynamic
211+
return #s1 = #t12;
222212
lowered core::String? #s2;
223213
function #s2#get() → core::String
224-
return let final core::String? #t15 = #s2 in #t15.==(null) ?{core::String} #s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
214+
return let final core::String? #t13 = #s2 in #t13.==(null) ?{core::String} #s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
225215
late String s2 = '\${fisk}\${await hest()}\${fisk}'; // Error.
226-
^^^^^"}${#C1}" : #t15{core::String};
227-
function #s2#set(core::String #t16) → dynamic
228-
return #s2 = #t16;
216+
^^^^^"}${#C1}" : #t13{core::String};
217+
function #s2#set(core::String #t14) → dynamic
218+
return #s2 = #t14;
229219
lowered core::Function? #f;
230220
function #f#get() → core::Function
231-
return let final core::Function? #t17 = #f in #t17.==(null) ?{core::Function} #f = () → asy::Future<dynamic> /* originally async */ {
221+
return let final core::Function? #t15 = #f in #t15.==(null) ?{core::Function} #f = () → asy::Future<dynamic> /* originally async */ {
232222
final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
233223
core::bool* :is_sync = false;
234224
FutureOr<dynamic>? :return_value;
@@ -237,21 +227,12 @@ static method fisk() → dynamic /* originally async */ {
237227
core::int :await_jump_var = 0;
238228
dynamic :await_ctx_var;
239229
dynamic :saved_try_context_var0;
240-
FutureOr<dynamic>:async_temporary_0;
241230
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
242231
try {
243232
#L4:
244233
{
245-
[yield] let dynamic #t18 = asy::_awaitHelper(self::hest(), :async_op_then, :async_op_error, :async_op) in null;
246-
final dynamic #t19 = :result;
247-
if(#t19 is asy::Future<dynamic>) {
248-
[yield] let dynamic #t20 = asy::_awaitHelper(#t19, :async_op_then, :async_op_error, :async_op) in null;
249-
:async_temporary_0 = :result;
250-
}
251-
else {
252-
:async_temporary_0 = #t19;
253-
}
254-
:return_value = :async_temporary_0;
234+
[yield] let dynamic #t16 = asy::_awaitHelper(self::hest(), :async_op_then, :async_op_error, :async_op) in null;
235+
:return_value = :result;
255236
break #L4;
256237
}
257238
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -265,9 +246,9 @@ static method fisk() → dynamic /* originally async */ {
265246
:async_op.call();
266247
:is_sync = true;
267248
return :async_future;
268-
} : #t17{core::Function};
269-
function #f#set(core::Function #t21) → dynamic
270-
return #f = #t21;
249+
} : #t15{core::Function};
250+
function #f#set(core::Function #t17) → dynamic
251+
return #f = #t17;
271252
}
272253
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
273254
return;
@@ -289,4 +270,4 @@ constants {
289270

290271
Extra constant evaluation status:
291272
Evaluated: VariableGet @ org-dartlang-testcase:///later.dart:46:18 -> IntConstant(42)
292-
Extra constant evaluation: evaluated: 234, effectively constant: 1
273+
Extra constant evaluation: evaluated: 207, effectively constant: 1

pkg/front_end/testcases/late_lowering/later.dart.weak.expect

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ static method hest() → dynamic async {
154154
await for (core::String s in asy::Stream::fromIterable<core::String>(<core::String>["hest"])) {
155155
core::print(s);
156156
}
157-
return let final core::String #t8 = "hest" in #t8 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t8 : #t8;
157+
return "hest";
158158
}
159159
static method fisk() → dynamic async {
160160
lowered core::String? #s1;
@@ -168,9 +168,9 @@ static method fisk() → dynamic async {
168168
}
169169
return #s1{core::String};
170170
}
171-
function #s1#set(core::String #t9) → dynamic {
171+
function #s1#set(core::String #t8) → dynamic {
172172
#s1#isSet = true;
173-
return #s1 = #t9;
173+
return #s1 = #t8;
174174
}
175175
lowered core::String? #s2;
176176
lowered core::bool #s2#isSet = false;
@@ -183,22 +183,22 @@ static method fisk() → dynamic async {
183183
}
184184
return #s2{core::String};
185185
}
186-
function #s2#set(core::String #t10) → dynamic {
186+
function #s2#set(core::String #t9) → dynamic {
187187
#s2#isSet = true;
188-
return #s2 = #t10;
188+
return #s2 = #t9;
189189
}
190190
lowered core::Function? #f;
191191
lowered core::bool #f#isSet = false;
192192
function #f#get() → core::Function {
193193
if(!#f#isSet) {
194-
#f = () → asy::Future<dynamic> async => let final dynamic #t11 = await self::hest() in #t11 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t11 : #t11;
194+
#f = () → asy::Future<dynamic> async => await self::hest();
195195
#f#isSet = true;
196196
}
197197
return #f{core::Function};
198198
}
199-
function #f#set(core::Function #t12) → dynamic {
199+
function #f#set(core::Function #t10) → dynamic {
200200
#f#isSet = true;
201-
return #f = #t12;
201+
return #f = #t10;
202202
}
203203
}
204204
static method main() → dynamic {}

0 commit comments

Comments
 (0)