From c7dcbff358ef887fcd68d8fec77652399521ffd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Sinan=20A=C4=9Facan?= Date: Tue, 23 May 2023 21:24:16 +0000 Subject: [PATCH] [dart2wasm] Fix a bug in async* desugaring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The desugared code uses `Completer` values to suspend the `async*` function, but we can't use a type test and to check if a value is the `Completer` value for the suspension or a user-emitted value as the `async*` function can also yield `Completer` values. Update the test from `value is Completer` to `!isEven`. Change-Id: I74f54b838e6a2aab942154ec7f3e667e291523e0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304880 Reviewed-by: Joshua Litt Commit-Queue: Ömer Ağacan --- pkg/dart2wasm/lib/transformers.dart | 2 +- .../yield.dart.strong.transformed.expect | 2 +- tests/web/wasm/asyncstar_desugaring_test.dart | 25 +++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 tests/web/wasm/asyncstar_desugaring_test.dart diff --git a/pkg/dart2wasm/lib/transformers.dart b/pkg/dart2wasm/lib/transformers.dart index 532987679b6..2634dc76567 100644 --- a/pkg/dart2wasm/lib/transformers.dart +++ b/pkg/dart2wasm/lib/transformers.dart @@ -522,7 +522,7 @@ class _WasmTransformer extends Transformer { ]), null), IfStatement( - IsExpression(VariableGet(completerPrePassArg), completerBoolType), + Not(VariableGet(isEven)), ExpressionStatement(InstanceInvocation( InstanceAccessKind.Instance, VariableGet(completerPrePassArg), diff --git a/pkg/front_end/testcases/dart2wasm/yield.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2wasm/yield.dart.strong.transformed.expect index f2c2499d2a8..5179377eb88 100644 --- a/pkg/front_end/testcases/dart2wasm/yield.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/dart2wasm/yield.dart.strong.transformed.expect @@ -101,7 +101,7 @@ static method asyncMethod(asy::Stream stream) → asy::Stream}; return #C3; } - if(value is asy::Completer) + if(!#isEven) value.{asy::Completer::complete}(#C2){([FutureOr?]) → void}; return value; }){((core::Object?) → FutureOr) → asy::Stream}.{asy::Stream::where}((synthesized core::Object? value) → core::Object? { diff --git a/tests/web/wasm/asyncstar_desugaring_test.dart b/tests/web/wasm/asyncstar_desugaring_test.dart new file mode 100644 index 00000000000..a89ba008bd8 --- /dev/null +++ b/tests/web/wasm/asyncstar_desugaring_test.dart @@ -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` values to suspend the async* +// function until the last emitted value is consumed. Check that the desugared +// code distinguishes user-written `Completer` values from the values +// used by the desugared code. +Stream> test() async* { + yield Completer(); + yield Completer(); + yield Completer(); +} + +void main() async { + final values = await test().toList(); + Expect.equals(values.length, 3); + for (final completer in values) { + Expect.isFalse(completer.isCompleted); + } +}