[dart2wasm] Fix a bug in async* desugaring

The desugared code uses `Completer<bool>` values to suspend the `async*`
function, but we can't use a type test and to check if a value is the
`Completer<bool>` value for the suspension or a user-emitted value as
the `async*` function can also yield `Completer<bool>` values. Update
the test from `value is Completer<bool>` to `!isEven`.

Change-Id: I74f54b838e6a2aab942154ec7f3e667e291523e0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304880
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
This commit is contained in:
Ömer Sinan Ağacan
2023-05-23 21:24:16 +00:00
committed by Commit Queue
parent 71304ce543
commit c7dcbff358
3 changed files with 27 additions and 2 deletions
+1 -1
View File
@@ -522,7 +522,7 @@ class _WasmTransformer extends Transformer {
]),
null),
IfStatement(
IsExpression(VariableGet(completerPrePassArg), completerBoolType),
Not(VariableGet(isEven)),
ExpressionStatement(InstanceInvocation(
InstanceAccessKind.Instance,
VariableGet(completerPrePassArg),
@@ -101,7 +101,7 @@ static method asyncMethod(asy::Stream<core::int> stream) → asy::Stream<core::i
#body(){() → asy::Future<void>};
return #C3;
}
if(value is asy::Completer<core::bool>)
if(!#isEven)
value.{asy::Completer::complete}(#C2){([FutureOr<core::bool>?]) → void};
return value;
}){((core::Object?) → FutureOr<core::Object?>) → asy::Stream<core::Object?>}.{asy::Stream::where}((synthesized core::Object? value) → core::Object? {
@@ -0,0 +1,25 @@
// Copyright (c) 2023, 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.
import "dart:async";
import 'package:expect/expect.dart';
// async* desugaring uses `Completer<bool>` values to suspend the async*
// function until the last emitted value is consumed. Check that the desugared
// code distinguishes user-written `Completer<bool>` values from the values
// used by the desugared code.
Stream<Completer<bool>> test() async* {
yield Completer<bool>();
yield Completer<bool>();
yield Completer<bool>();
}
void main() async {
final values = await test().toList();
Expect.equals(values.length, 3);
for (final completer in values) {
Expect.isFalse(completer.isCompleted);
}
}