mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 15:01:29 +00:00
c486a07b02
This adds a mechanism similar to that used in async functions where exceptions are caught in the synthetic code and passed into the generated body to be rethrow'n. This ensures the exception is throw'n from the same place as the original yield*, as per the spec. Bug: https://github.com/dart-lang/sdk/issues/42466 Change-Id: I054b9db568a49b046b6bb49f3e775bf093f83950 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/160221 Commit-Queue: Clement Skau <cskau@google.com> Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
47 lines
1.1 KiB
Dart
47 lines
1.1 KiB
Dart
// Copyright (c) 2020, 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.
|
|
|
|
// See: https://github.com/dart-lang/sdk/issues/42466
|
|
|
|
import 'dart:collection';
|
|
import 'package:expect/expect.dart';
|
|
|
|
var caughtString;
|
|
|
|
class AlwaysThrowingIterator implements Iterator<int> {
|
|
bool moveNext() => throw 'moveNext';
|
|
int get current => throw 'current';
|
|
}
|
|
|
|
class AlwaysThrowing extends IterableBase<int> {
|
|
Iterator<int> get iterator => AlwaysThrowingIterator();
|
|
}
|
|
|
|
Iterable<int> f() sync* {
|
|
try {
|
|
yield* AlwaysThrowing();
|
|
} catch (e, st) {
|
|
caughtString = 'caught $e in f';
|
|
}
|
|
}
|
|
|
|
void g() {
|
|
try {
|
|
for (int x in f()) {
|
|
print(x);
|
|
}
|
|
} catch (e, st) {
|
|
caughtString = 'caught $e in g';
|
|
}
|
|
}
|
|
|
|
main() {
|
|
g();
|
|
// The spec dictates that if `e` (moveNext, current) throws then `yield* e`
|
|
// should throw.
|
|
// I.e. even though the iteration is happening in `g`, the `yield*` is in `f`
|
|
// so its catch should trigger.
|
|
Expect.equals('caught moveNext in f', caughtString);
|
|
}
|