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