Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

yield* does not terminate enclosing function on stream cancellation #25748

Closed
alsemenov opened this issue Feb 10, 2016 · 4 comments
Closed

yield* does not terminate enclosing function on stream cancellation #25748

alsemenov opened this issue Feb 10, 2016 · 4 comments
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. closed-duplicate Closed in favor of an existing report

Comments

@alsemenov
Copy link
Contributor

The Dart Programming Language Specification (4th edition draft) version 1.11, chapter 17.16.2 Yield-Each reads:

If m is marked async* (9), then:
• It is a dynamic error if the class of o does not implement Stream. Otherwise
• For each element x of o:
– If the stream u associated with m has been paused, then execution
of m is suspended until u is resumed or canceled.
If the stream u associated with m has been canceled, then let c be
the finally clause (17.11) of the innermost enclosing try-finally state-
ment, if any. If c is defined, let h be the handler induced by c. If h is
defined, control is transferred to h. If h is undefined, the immediately
enclosing function terminates
.
– Otherwise, x is added to the stream associated with m in the order
it appears in o. The function m may suspend.
• If the stream o is done, execution of s is complete.

The following code demonstrates, that execution of immediately enclosing function continues after yield* statement even if the associated stream subscription is cancelled.

import 'dart:async';

Stream<int> generator(Stream<int> input) async* {
  yield* input;
  print("Error!!! Code after yield* should not be executed");
}

main() async {
  StreamController<int> sc = new StreamController<int>();
  Stream<int> s = generator(sc.stream);
  StreamSubscription<int> ss = s.listen(
      (int i){
        print(i);
      }
  );
  sc.add(1);
  sc.add(2);
  sc.add(3);
  await new Future.delayed(new Duration(milliseconds: 100));
  await ss.cancel();
  sc.add(4);
  sc.add(5);
  await new Future.delayed(new Duration(milliseconds: 100));
  await sc.close();
}

Output:

1
2
3
Error!!! Code after yield* should not be executed

Expected output:

1
2
3

Dart VM version: 1.14.1 (Wed Feb 03 11:59:06 2016) on "windows_x64"

@kevmoo kevmoo added the area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). label Feb 10, 2016
@kevmoo
Copy link
Member

kevmoo commented Feb 10, 2016

@floitschG thoughts?

@floitschG floitschG added area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. and removed area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). labels Feb 10, 2016
@floitschG
Copy link
Contributor

Looks like a bug in the VM.
Dart2js has the expected output.

whesse pushed a commit that referenced this issue Mar 9, 2016
@mhausner mhausner self-assigned this Mar 18, 2016
@mhausner mhausner removed their assignment Mar 20, 2017
@mhausner
Copy link
Contributor

Still reproduces on the VM.

@natebosch
Copy link
Member

Closing in favor of #34775 which has more specifics around both pausing and cancelling.

@natebosch natebosch added the closed-duplicate Closed in favor of an existing report label Nov 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. closed-duplicate Closed in favor of an existing report
Projects
None yet
Development

No branches or pull requests

5 participants