Version 2.11.0-266.0.dev
Merge commit 'c486a07b02d27559e8661b650bf4eebbd93cfa87' into 'dev'
diff --git a/pkg/front_end/testcases/extensions/async_extensions.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/async_extensions.dart.strong.transformed.expect
index 1ef6cf1..f4de67a 100644
--- a/pkg/front_end/testcases/extensions/async_extensions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/async_extensions.dart.strong.transformed.expect
@@ -12,13 +12,14 @@
tearoff asyncStarMethod = self::Extension|get#asyncStarMethod;
}
static method Extension|syncStarMethod(final core::int* #this) → dynamic /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}
diff --git a/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect b/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect
index d341b2a..056a35a 100644
--- a/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect
@@ -62,10 +62,10 @@
return :async_completer.{asy::Completer::future};
}
static method syncStarString() → core::Iterable<core::String*>* /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = "foo";
@@ -81,15 +81,16 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::String*>(:sync_op_gen);
}
static method syncStarString2() → core::Iterable<core::String*>* /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = "foo";
@@ -97,7 +98,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::String*>(:sync_op_gen);
}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect
index d341b2a..056a35a 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect
@@ -62,10 +62,10 @@
return :async_completer.{asy::Completer::future};
}
static method syncStarString() → core::Iterable<core::String*>* /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = "foo";
@@ -81,15 +81,16 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::String*>(:sync_op_gen);
}
static method syncStarString2() → core::Iterable<core::String*>* /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = "foo";
@@ -97,7 +98,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::String*>(:sync_op_gen);
}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.transformed.expect
index 8ef54ea..ad5d5f0 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.transformed.expect
@@ -4,10 +4,10 @@
static method main() → dynamic {
() →* core::Iterable<core::Null?>* f = () → core::Iterable<core::Null?>* /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = null;
@@ -15,7 +15,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::Null?>(:sync_op_gen);
};
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.strong.transformed.expect
index 8ba245d..6dba553 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.strong.transformed.expect
@@ -4,10 +4,10 @@
static method test() → dynamic {
() →* core::Iterable<core::num*>* f = () → core::Iterable<core::num*>* /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = 1;
@@ -19,7 +19,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::num*>(:sync_op_gen);
};
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
index 2cef8c5..91c8102 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.transformed.expect
@@ -139,10 +139,10 @@
return :controller_stream;
}
static method bar() → core::Iterable<core::Map<core::int*, core::int*>*>* /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = core::Map::•<core::int*, core::int*>();
@@ -170,7 +170,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::Map<core::int*, core::int*>*>(:sync_op_gen);
}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect
index f330a82..ef727eb 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect
@@ -64,10 +64,10 @@
return :async_completer.{asy::Completer::future};
}
function f4() → core::Iterable<core::int*>* /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = 42;
@@ -75,7 +75,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::int*>(:sync_op_gen);
}
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
index 61d7ab7..392e13e 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
@@ -49,10 +49,10 @@
return :async_completer.{asy::Completer::future};
}
function c() → core::Iterable<(core::int*) →* core::int*>* /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = (core::int* x) → core::int* => x;
@@ -60,15 +60,16 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<(core::int*) →* core::int*>(:sync_op_gen);
}
function d() → core::Iterable<(core::int*) →* core::int*>* /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_yieldEachIterable} = <(core::int*) →* core::int*>[(core::int* x) → core::int* => x];
@@ -76,7 +77,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<(core::int*) →* core::int*>(:sync_op_gen);
}
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
index e58866d..e9c085d 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
@@ -48,10 +48,10 @@
return :async_completer.{asy::Completer::future};
}
static method c() → core::Iterable<(core::int*) →* core::int*>* /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = (core::int* x) → core::int* => x;
@@ -59,15 +59,16 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<(core::int*) →* core::int*>(:sync_op_gen);
}
static method d() → core::Iterable<(core::int*) →* core::int*>* /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_yieldEachIterable} = <(core::int*) →* core::int*>[(core::int* x) → core::int* => x];
@@ -75,7 +76,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<(core::int*) →* core::int*>(:sync_op_gen);
}
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
index bc6171e..89e8bd5 100644
--- a/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
@@ -44,10 +44,10 @@
static method getNull() → dynamic
return null;
static method getIterableNull() → core::Iterable<dynamic> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = null;
@@ -55,15 +55,16 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}
static method getIterableBool() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = true;
@@ -71,15 +72,16 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}
static method test1() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
@@ -87,7 +89,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}
@@ -96,10 +99,10 @@
static method test3() → core::bool
return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
static method test4() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_yieldEachIterable} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
@@ -110,7 +113,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}
@@ -122,10 +126,10 @@
static method test6() → core::Iterable<core::bool>
return self::getIterableBool();
static method test7() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
@@ -133,7 +137,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}
@@ -150,10 +155,10 @@
#L1:
{
function test1() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
@@ -161,7 +166,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}
@@ -170,10 +176,10 @@
function test3() → core::bool
return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
function test4() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_yieldEachIterable} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
@@ -184,7 +190,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}
@@ -196,10 +203,10 @@
function test6() → core::Iterable<core::bool>
return self::getIterableBool();
function test7() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
@@ -207,7 +214,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}
@@ -215,10 +223,10 @@
- 'Iterable' is from 'dart:core'.
})(); // error
^" in (() → core::Iterable<dynamic> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = self::getNull();
@@ -226,7 +234,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
@@ -236,10 +245,10 @@
- 'Iterable' is from 'dart:core'.
})(); // error
^" in (() → core::Iterable<dynamic> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableNull();
@@ -247,7 +256,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
@@ -257,10 +267,10 @@
^" in (() → core::Iterable<dynamic> => self::getIterableNull()).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
core::Iterable<core::bool> var6 = (() → core::Iterable<core::bool> => self::getIterableBool()).call();
core::Iterable<core::bool> var7 = (() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
@@ -268,7 +278,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}).call();
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
index bc6171e..89e8bd5 100644
--- a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
@@ -44,10 +44,10 @@
static method getNull() → dynamic
return null;
static method getIterableNull() → core::Iterable<dynamic> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = null;
@@ -55,15 +55,16 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}
static method getIterableBool() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = true;
@@ -71,15 +72,16 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}
static method test1() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
@@ -87,7 +89,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}
@@ -96,10 +99,10 @@
static method test3() → core::bool
return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
static method test4() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_yieldEachIterable} = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:21:10: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
@@ -110,7 +113,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}
@@ -122,10 +126,10 @@
static method test6() → core::Iterable<core::bool>
return self::getIterableBool();
static method test7() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
@@ -133,7 +137,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}
@@ -150,10 +155,10 @@
#L1:
{
function test1() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
@@ -161,7 +166,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}
@@ -170,10 +176,10 @@
function test3() → core::bool
return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
function test4() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_yieldEachIterable} = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437b.dart:38:12: Error: A value of type 'Iterable<dynamic>' can't be assigned to a variable of type 'Iterable<bool>'.
@@ -184,7 +190,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}
@@ -196,10 +203,10 @@
function test6() → core::Iterable<core::bool>
return self::getIterableBool();
function test7() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
@@ -207,7 +214,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}
@@ -215,10 +223,10 @@
- 'Iterable' is from 'dart:core'.
})(); // error
^" in (() → core::Iterable<dynamic> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = self::getNull();
@@ -226,7 +234,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
@@ -236,10 +245,10 @@
- 'Iterable' is from 'dart:core'.
})(); // error
^" in (() → core::Iterable<dynamic> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableNull();
@@ -247,7 +256,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
@@ -257,10 +267,10 @@
^" in (() → core::Iterable<dynamic> => self::getIterableNull()).call() as{TypeError,ForNonNullableByDefault} core::Iterable<core::bool>;
core::Iterable<core::bool> var6 = (() → core::Iterable<core::bool> => self::getIterableBool()).call();
core::Iterable<core::bool> var7 = (() → core::Iterable<core::bool> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_yieldEachIterable} = self::getIterableBool();
@@ -268,7 +278,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
}).call();
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
index 3d6ecf6..68cae46 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
@@ -270,13 +270,14 @@
return :async_completer.{asy::Completer::future};
}
static method yieldSync() → core::Iterable<dynamic> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}
@@ -539,13 +540,14 @@
return :async_completer.{asy::Completer::future};
}
function yieldSync() → core::Iterable<dynamic> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
index 91bc7b3..eb7d09f 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
@@ -271,13 +271,14 @@
return :async_completer.{asy::Completer::future};
}
static method yieldSync() → core::Iterable<dynamic> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}
@@ -543,13 +544,14 @@
return :async_completer.{asy::Completer::future};
}
function yieldSync() → core::Iterable<dynamic> /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>?) → core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>? :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>? :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}
diff --git a/pkg/front_end/testcases/regress/issue_29983.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29983.dart.strong.transformed.expect
index 63808a8..aeb1e86 100644
--- a/pkg/front_end/testcases/regress/issue_29983.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29983.dart.strong.transformed.expect
@@ -22,43 +22,46 @@
import "dart:core" as core;
static method f() → dynamic /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
invalid-expression "pkg/front_end/testcases/regress/issue_29983.dart:7:3: Error: 'sync*' and 'async*' can't return a value.
return missing;
^";
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}
static method g() → dynamic /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
invalid-expression "pkg/front_end/testcases/regress/issue_29983.dart:11:14: Error: 'sync*' and 'async*' can't return a value.
g() sync* => dummy;
^";
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}
static method h() → dynamic /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
(() → core::String* => "return").call();
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect
index c07e799..5797f90 100644
--- a/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect
@@ -123,10 +123,10 @@
}
}
function f_sync_star() → core::int* /* originally sync* */ {
- function :sync_op_gen() → (core::_SyncIterator<dynamic>*) →* core::bool* {
+ function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
core::int* :await_jump_var = 0;
dynamic :await_ctx_var;
- return (core::_SyncIterator<dynamic>* :iterator) → core::bool* yielding {
+ function :sync_op(core::_SyncIterator<dynamic>* :iterator, dynamic :exception, dynamic :stack_trace) → core::bool* yielding {
{
{
:iterator.{core::_SyncIterator::_current} = 42;
@@ -134,7 +134,8 @@
}
}
return false;
- };
+ }
+ return :sync_op;
}
return new core::_SyncIterable::•<dynamic>(:sync_op_gen);
}
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
index d04c465..13942d4 100644
--- a/pkg/kernel/lib/transformations/continuation.dart
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -28,9 +28,10 @@
static const stream = ':stream';
static const syncForIterator = ':sync-for-iterator';
static const syncOpGen = ':sync_op_gen';
+ static const syncOp = ':sync_op';
// sync_op(..) parameter.
static const iteratorParam = ':iterator';
- // async_op(..) parameters.
+ // (a)sync_op(..) parameters.
static const exceptionParam = ':exception';
static const stackTraceParam = ':stack_trace';
@@ -409,35 +410,42 @@
enclosingFunction.body =
enclosingFunction.body.accept<TreeNode>(shadowRewriter);
- final syncOpType = FunctionType([iteratorParameter.type],
- helper.coreTypes.boolLegacyRawType, staticTypeContext.nonNullable);
-
- final syncOpGenVariable = VariableDeclaration(
- ContinuationVariables.syncOpGen,
- type: FunctionType([], syncOpType, staticTypeContext.nonNullable));
-
// TODO(cskau): Figure out why inlining this below causes segfaults.
// Maybe related to http://dartbug.com/41596 ?
final syncOpFN = FunctionNode(buildClosureBody(),
- positionalParameters: [iteratorParameter],
- requiredParameterCount: 1,
+ positionalParameters: [
+ iteratorParameter,
+ new VariableDeclaration(ContinuationVariables.exceptionParam),
+ new VariableDeclaration(ContinuationVariables.stackTraceParam),
+ ],
+ requiredParameterCount: 3,
+ // Note: SyncYielding functions have no Dart equivalent. Since they are
+ // synchronous, we use Sync. (Note also that the Dart VM backend uses
+ // the Dart async marker to decide if functions are debuggable.)
asyncMarker: AsyncMarker.SyncYielding,
dartAsyncMarker: AsyncMarker.Sync,
returnType: helper.coreTypes.boolLegacyRawType)
..fileOffset = enclosingFunction.fileOffset
..fileEndOffset = enclosingFunction.fileEndOffset;
+ final syncOpType =
+ syncOpFN.computeThisFunctionType(staticTypeContext.nonNullable);
+
+ final syncOpGenVariable = VariableDeclaration(
+ ContinuationVariables.syncOpGen,
+ type: FunctionType([], syncOpType, staticTypeContext.nonNullable));
+
+ final syncOpVariable = VariableDeclaration(ContinuationVariables.syncOp);
+ final syncOpDecl = FunctionDeclaration(syncOpVariable, syncOpFN);
enclosingFunction.body = Block([
// :sync_op_gen() {
// :await_jump_var;
// :await_ctx_var;
- // return bool (:iterator) yielding {
+ // bool sync_op(:iterator, e, st) yielding {
// modified <node.body> ...
// };
+ // return sync_op;
// }
- // Note: SyncYielding functions have no Dart equivalent. Since they are
- // synchronous, we use Sync. (Note also that the Dart VM backend uses
- // the Dart async marker to decide if functions are debuggable.)
FunctionDeclaration(
syncOpGenVariable,
FunctionNode(
@@ -446,7 +454,10 @@
...variableDeclarations(),
// Shadow any used function parameters with local copies.
...shadowRewriter.shadowedParameters,
- ReturnStatement(FunctionExpression(syncOpFN)),
+ // :sync_op(..) { .. }
+ syncOpDecl,
+ // return sync_op;
+ ReturnStatement(VariableGet(syncOpVariable)),
]),
returnType: syncOpType)),
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index efc2994..b118c2b 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -4843,13 +4843,19 @@
Fragment continuation(instructions.entry, anchor);
- if (parsed_function()->function().IsAsyncClosure() ||
- parsed_function()->function().IsAsyncGenClosure()) {
- // If function is async closure or async gen closure it takes three
+ RELEASE_ASSERT(parsed_function()->function().IsAsyncClosure() ||
+ parsed_function()->function().IsAsyncGenClosure() ||
+ parsed_function()->function().IsSyncGenClosure());
+
+ // TODO(43900): Only emit this when needed.
+ {
+ // If function is {async, async gen, sync yielding} closure it takes three
// parameters where the second and the third are exception and stack_trace.
// Check if exception is non-null and rethrow it.
//
- // :async_op([:result, :exception, :stack_trace]) {
+ // :sync_op(:iterator, [:exception, :stack_trace]) {
+ // or:
+ // :async_op(:result, [:exception, :stack_trace]) {
// ...
// Continuation<index>:
// if (:exception != null) rethrow(:exception, :stack_trace);
@@ -4868,13 +4874,15 @@
continuation += LoadLocal(exception_var);
continuation += BranchIfNull(&no_error, &error);
- Fragment rethrow(error);
+ Fragment rethrow(/*instruction=*/error);
rethrow += LoadLocal(exception_var);
rethrow += LoadLocal(stack_trace_var);
+
rethrow += RethrowException(position, kInvalidTryIndex);
Drop();
- continuation = Fragment(continuation.entry, no_error);
+ // Set current to the end of the no_error branch.
+ continuation = Fragment(/*entry=*/continuation.entry, /*current=*/no_error);
}
return continuation;
@@ -5005,6 +5013,16 @@
}
function.set_is_generated_body(function_node_helper.async_marker_ ==
FunctionNodeHelper::kSyncYielding);
+ // sync* functions contain two nested synthetic functions, the first of
+ // which (sync_op_gen) is a regular sync function so we need to manually
+ // label it generated:
+ if (function.parent_function() != Function::null()) {
+ const auto& parent = Function::Handle(function.parent_function());
+ if (parent.IsSyncGenerator()) {
+ function.set_is_generated_body(true);
+ }
+ }
+ // Note: Is..() methods use the modifiers set above, so order matters.
if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
function.set_is_inlinable(!FLAG_causal_async_stacks &&
!FLAG_lazy_async_stacks);
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index c0ac9e9..c9a54fd 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -236,15 +236,15 @@
}
ParameterTypeCheckMode type_check_mode = kTypeCheckAllParameters;
- if (function.IsSyncYielding()) {
+ if (function.IsSyncGenClosure()) {
// Don't type check the parameter of sync-yielding since these calls are
// all synthetic and types should always match.
ASSERT((function.NumParameters() - function.NumImplicitParameters()) ==
- 1);
+ 3);
ASSERT(
Class::Handle(
AbstractType::Handle(function.ParameterTypeAt(1)).type_class())
- .Name() == Symbols::_SyncIterator().raw());
+ .ScrubbedName() == Symbols::_SyncIterator().raw());
type_check_mode = kTypeCheckForStaticFunction;
} else if (function.IsNonImplicitClosureFunction()) {
type_check_mode = kTypeCheckAllParameters;
@@ -613,10 +613,12 @@
scope_->AddVariable(asyncStackTraceVar);
}
+ // The :sync_op and :async_op continuations are called multiple times. So we
+ // don't want the parameters from the first invocation to get stored in the
+ // context and reused on later invocations with different parameters.
if (function_node_helper.async_marker_ == FunctionNodeHelper::kSyncYielding) {
- intptr_t offset = function.num_fixed_parameters();
- for (intptr_t i = 0; i < function.NumOptionalPositionalParameters(); i++) {
- parsed_function_->ParameterVariable(offset + i)->set_is_forced_stack();
+ for (intptr_t i = 0; i < function.NumParameters(); i++) {
+ parsed_function_->ParameterVariable(i)->set_is_forced_stack();
}
}
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 8ad542d..ecbb6f9 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -4831,10 +4831,6 @@
}
continue;
} else {
- // func was just compiled.
- // The local function of a function we just compiled cannot
- // be compiled already.
- ASSERT(!inner_function.HasCode());
if (FLAG_verbose_debug) {
OS::PrintErr(
"Pending breakpoint remains unresolved in "
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index de74fdb..175b1f0 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -9490,7 +9490,7 @@
if (IsClosureFunction()) {
if (fun.IsLocalFunction() && !fun.IsImplicitClosureFunction()) {
Function& parent = Function::Handle(fun.parent_function());
- if (parent.IsAsyncClosure() || parent.IsSyncGenClosure() ||
+ if (parent.IsAsyncClosure() || parent.IsSyncGenClosureMaker() ||
parent.IsAsyncGenClosure()) {
// Skip the closure and use the real function name found in
// the parent.
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 71eeefd..ceffe2f 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -3582,35 +3582,56 @@
return kind == MethodRecognizer::kUtf8DecoderScan;
}
+ // Recognise async functions like:
+ // user_func async {
+ // // ...
+ // }
bool IsAsyncFunction() const { return modifier() == FunctionLayout::kAsync; }
+ // Recognise synthetic sync-yielding functions like the inner-most:
+ // user_func /* was async */ {
+ // :async_op(..) yielding {
+ // // ...
+ // }
+ // }
bool IsAsyncClosure() const {
return is_generated_body() &&
Function::Handle(parent_function()).IsAsyncFunction();
}
- bool IsGenerator() const {
- return (modifier() & FunctionLayout::kGeneratorBit) != 0;
- }
-
+ // Recognise sync* functions like:
+ // user_func sync* {
+ // // ...
+ // }
bool IsSyncGenerator() const {
return modifier() == FunctionLayout::kSyncGen;
}
- bool IsSyncGenClosure() const {
+ // Recognise synthetic :sync_op_gen()s like:
+ // user_func /* was sync* */ {
+ // :sync_op_gen() {
+ // // ...
+ // }
+ // }
+ bool IsSyncGenClosureMaker() const {
return is_generated_body() &&
Function::Handle(parent_function()).IsSyncGenerator();
}
- bool IsGeneratorClosure() const {
- return is_generated_body() &&
- Function::Handle(parent_function()).IsGenerator();
- }
-
+ // Recognise async* functions like:
+ // user_func async* {
+ // // ...
+ // }
bool IsAsyncGenerator() const {
return modifier() == FunctionLayout::kAsyncGen;
}
+ // Recognise synthetic sync-yielding functions like the inner-most:
+ // user_func /* originally async* */ {
+ // :async_op(..) yielding {
+ // // ...
+ // }
+ // }
bool IsAsyncGenClosure() const {
return is_generated_body() &&
Function::Handle(parent_function()).IsAsyncGenerator();
@@ -3623,15 +3644,14 @@
// Recognise synthetic sync-yielding functions like the inner-most:
// user_func /* was sync* */ {
// :sync_op_gen() {
- // :sync_op() yielding {
+ // :sync_op(..) yielding {
// // ...
// }
// }
// }
- bool IsSyncYielding() const {
- return (parent_function() != Function::null())
- ? Function::Handle(parent_function()).IsSyncGenClosure()
- : false;
+ bool IsSyncGenClosure() const {
+ return (parent_function() != Function::null()) &&
+ Function::Handle(parent_function()).IsSyncGenClosureMaker();
}
bool IsTypedDataViewFactory() const {
diff --git a/sdk/lib/_internal/vm/lib/core_patch.dart b/sdk/lib/_internal/vm/lib/core_patch.dart
index b4bbd57..d138549 100644
--- a/sdk/lib/_internal/vm/lib/core_patch.dart
+++ b/sdk/lib/_internal/vm/lib/core_patch.dart
@@ -103,7 +103,8 @@
// implement sync* generator functions. A sync* generator allocates
// and returns a new _SyncIterable object.
-typedef _SyncGeneratorCallback<T> = bool Function(_SyncIterator<T>);
+typedef _SyncGeneratorCallback<T> = bool Function(
+ _SyncIterator<T>, Object?, StackTrace?);
typedef _SyncGeneratorCallbackCallback<T> = _SyncGeneratorCallback<T>
Function();
@@ -123,7 +124,7 @@
_SyncGeneratorCallback<T>? _moveNextFn;
Iterator<T>? _yieldEachIterator;
- // Stack of suspended _moveNextFn.
+ // Stack of suspended _moveNextFn (sync_op).
List<_SyncGeneratorCallback<T>>? _stack;
// These two fields are set by generated code for the yield and yield*
@@ -133,57 +134,85 @@
@override
T get current {
- final iterator = _yieldEachIterator;
- if (iterator != null) {
- return iterator.current;
- } else {
- final cur = _current;
- return (cur != null) ? cur : cur as T;
- }
+ final cur = _current;
+ return (cur != null) ? cur : cur as T;
}
_SyncIterator(this._moveNextFn);
+ @pragma('vm:prefer-inline')
+ bool _handleMoveNextFnCompletion() {
+ _moveNextFn = null;
+ _current = null;
+ final stack = _stack;
+ if (stack != null && stack.isNotEmpty) {
+ _moveNextFn = stack.removeLast();
+ return true;
+ }
+ return false;
+ }
+
@override
bool moveNext() {
if (_moveNextFn == null) {
return false;
}
+ Object? pendingException;
+ StackTrace? pendingStackTrace;
while (true) {
// If the active iterator isn't a nested _SyncIterator, we have to
// delegate downwards from the immediate iterator.
final iterator = _yieldEachIterator;
if (iterator != null) {
- if (iterator.moveNext()) {
- return true;
+ try {
+ if (iterator.moveNext()) {
+ _current = iterator.current;
+ return true;
+ }
+ } catch (e, st) {
+ pendingException = e;
+ pendingStackTrace = st;
}
_yieldEachIterator = null;
}
- final stack = _stack;
- if (!_moveNextFn!.call(this)) {
- _moveNextFn = null;
- _current = null;
- // If we have any suspended parent generators, continue next one up:
- if (stack != null && stack.isNotEmpty) {
- _moveNextFn = stack.removeLast();
+ // Start by calling _moveNextFn (sync_op) to move to the next value (or
+ // nested iterator).
+ try {
+ final haveMore =
+ _moveNextFn!.call(this, pendingException, pendingStackTrace);
+ // Exception was handled.
+ pendingException = null;
+ pendingStackTrace = null;
+ if (!haveMore) {
+ if (_handleMoveNextFnCompletion()) {
+ continue;
+ }
+ return false;
+ }
+ } catch (e, st) {
+ pendingException = e;
+ pendingStackTrace = st;
+ if (_handleMoveNextFnCompletion()) {
continue;
}
- return false;
+ rethrow;
}
+ // Case: yield* some_iterator.
final iterable = _yieldEachIterable;
if (iterable != null) {
if (iterable is _SyncIterable) {
// We got a recursive yield* of sync* function. Instead of creating
// a new iterator we replace our _moveNextFn (remembering the
// current _moveNextFn for later resumption).
- if (stack == null) {
+ if (_stack == null) {
_stack = [];
}
_stack!.add(_moveNextFn!);
final typedIterable = unsafeCast<_SyncIterable<T>>(iterable);
+
_moveNextFn = typedIterable._moveNextFnMaker();
} else {
_yieldEachIterator = iterable.iterator;
@@ -195,6 +224,7 @@
continue;
}
+ // We've successfully found the next `current` value.
return true;
}
}
diff --git a/tests/language/sync_star/sync_star_exception_nested_test.dart b/tests/language/sync_star/sync_star_exception_nested_test.dart
new file mode 100644
index 0000000..ab10c65
--- /dev/null
+++ b/tests/language/sync_star/sync_star_exception_nested_test.dart
@@ -0,0 +1,55 @@
+// 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';
+
+String? caughtString;
+
+a() sync* {
+ yield 3;
+ throw 'Throw from a()';
+ yield 4;
+}
+
+b() sync* {
+ yield 2;
+ yield* a();
+ yield 5;
+}
+
+c() sync* {
+ try {
+ yield 1;
+ yield* b();
+ yield 6;
+ } catch (e, st) {
+ caughtString = 'Caught in c()';
+ }
+}
+
+d() sync* {
+ try {
+ yield 0;
+ yield* c();
+ yield 7;
+ } catch (e, st) {
+ caughtString = 'Caught in d()';
+ }
+}
+
+main() {
+ List yields = [];
+ try {
+ for (final e in d()) {
+ yields.add(e);
+ }
+ } catch (e, st) {
+ caughtString = 'Caught in main()';
+ }
+ Expect.equals('Caught in c()', caughtString);
+ Expect.listEquals([0, 1, 2, 3, 7], yields);
+}
diff --git a/tests/language/sync_star/sync_star_exception_test.dart b/tests/language/sync_star/sync_star_exception_test.dart
new file mode 100644
index 0000000..e1db95a
--- /dev/null
+++ b/tests/language/sync_star/sync_star_exception_test.dart
@@ -0,0 +1,46 @@
+// 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);
+}
diff --git a/tests/language_2/sync_star/sync_star_exception_nested_test.dart b/tests/language_2/sync_star/sync_star_exception_nested_test.dart
new file mode 100644
index 0000000..6c8b702
--- /dev/null
+++ b/tests/language_2/sync_star/sync_star_exception_nested_test.dart
@@ -0,0 +1,55 @@
+// 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';
+
+String caughtString;
+
+a() sync* {
+ yield 3;
+ throw 'Throw from a()';
+ yield 4;
+}
+
+b() sync* {
+ yield 2;
+ yield* a();
+ yield 5;
+}
+
+c() sync* {
+ try {
+ yield 1;
+ yield* b();
+ yield 6;
+ } catch (e, st) {
+ caughtString = 'Caught in c()';
+ }
+}
+
+d() sync* {
+ try {
+ yield 0;
+ yield* c();
+ yield 7;
+ } catch (e, st) {
+ caughtString = 'Caught in d()';
+ }
+}
+
+main() {
+ List yields = [];
+ try {
+ for (final e in d()) {
+ yields.add(e);
+ }
+ } catch (e, st) {
+ caughtString = 'Caught in main()';
+ }
+ Expect.equals('Caught in c()', caughtString);
+ Expect.listEquals([0, 1, 2, 3, 7], yields);
+}
diff --git a/tests/language_2/sync_star/sync_star_exception_test.dart b/tests/language_2/sync_star/sync_star_exception_test.dart
new file mode 100644
index 0000000..e1db95a
--- /dev/null
+++ b/tests/language_2/sync_star/sync_star_exception_test.dart
@@ -0,0 +1,46 @@
+// 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);
+}
diff --git a/tools/VERSION b/tools/VERSION
index e663151..dd0d6b5 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 11
PATCH 0
-PRERELEASE 265
+PRERELEASE 266
PRERELEASE_PATCH 0
\ No newline at end of file