[cfe] Async translation of block expressions

Translate block expressions in the VM's async translation.  Closes
https://github.com/dart-lang/sdk/issues/36277

Change-Id: I606b155bfe1364e948d18043c167a272007411e0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/98339
Commit-Queue: Kevin Millikin <kmillikin@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.transformed.expect
index 506d1f6..14b2064 100644
--- a/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.transformed.expect
@@ -1626,6 +1626,10 @@
   dynamic :async_op_error;
   dynamic :await_jump_var = 0;
   dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
   function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
     try {
       #L1:
@@ -1870,110 +1874,234 @@
             #t351.{core::Map::[]=}("bar", i);
           #t351.{core::Map::[]=}("baz", null);
         } =>#t351;
-        core::List<dynamic> list30 = block {
-          final core::List<dynamic> #t354 = <dynamic>[];
-          await for (dynamic i in let final<BottomType> #t355 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:220:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+        final core::List<dynamic> #t354 = <dynamic>[];
+        {
+          dynamic :stream = let final<BottomType> #t355 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:220:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var list30 = [await for (var i in \"not stream\") i];
-                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>)
-            #t354.{core::List::add}(i);
-        } =>#t354;
-        core::Set<dynamic> set30 = block {
-          final core::Set<dynamic> #t356 = col::LinkedHashSet::•<dynamic>();
-          await for (dynamic i in let final<BottomType> #t357 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:221:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>;
+          asy::_asyncStarListenHelper(:stream, :async_op);
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
+          const core::bool :product-mode = const core::bool::fromEnvironment("dart.vm.product");
+          try
+            #L2:
+            while (true) {
+              dynamic #t356 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t357 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic i = :for-iterator.{asy::_StreamIterator::current};
+                #t354.{core::List::add}(i);
+              }
+              else
+                break #L2;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t358 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        core::List<dynamic> list30 = block {} =>#t354;
+        final core::Set<dynamic> #t359 = col::LinkedHashSet::•<dynamic>();
+        {
+          dynamic :stream = let final<BottomType> #t360 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:221:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var set30 = {await for (var i in \"not stream\") i, null};
-                                   ^" in "not stream" as{TypeError} asy::Stream<dynamic>)
-            #t356.{core::Set::add}(i);
-          #t356.{core::Set::add}(null);
-        } =>#t356;
-        core::Map<core::String, dynamic> map30 = block {
-          final core::Map<core::String, dynamic> #t358 = <core::String, dynamic>{};
-          await for (dynamic i in let final<BottomType> #t359 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:222:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+                                   ^" in "not stream" as{TypeError} asy::Stream<dynamic>;
+          asy::_asyncStarListenHelper(:stream, :async_op);
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
+          const core::bool :product-mode = const core::bool::fromEnvironment("dart.vm.product");
+          try
+            #L3:
+            while (true) {
+              dynamic #t361 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t362 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic i = :for-iterator.{asy::_StreamIterator::current};
+                #t359.{core::Set::add}(i);
+              }
+              else
+                break #L3;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t363 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        core::Set<dynamic> set30 = block {
+          #t359.{core::Set::add}(null);
+        } =>#t359;
+        final core::Map<core::String, dynamic> #t364 = <core::String, dynamic>{};
+        {
+          dynamic :stream = let final<BottomType> #t365 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:222:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var map30 = {await for (var i in \"not stream\") \"bar\": i, \"baz\": null};
-                                   ^" in "not stream" as{TypeError} asy::Stream<dynamic>)
-            #t358.{core::Map::[]=}("bar", i);
-          #t358.{core::Map::[]=}("baz", null);
-        } =>#t358;
-        core::List<core::int> list40 = block {
-          final core::List<core::int> #t360 = <core::int>[];
-          await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t361 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                   ^" in "not stream" as{TypeError} asy::Stream<dynamic>;
+          asy::_asyncStarListenHelper(:stream, :async_op);
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(:stream);
+          const core::bool :product-mode = const core::bool::fromEnvironment("dart.vm.product");
+          try
+            #L4:
+            while (true) {
+              dynamic #t366 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t367 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic i = :for-iterator.{asy::_StreamIterator::current};
+                #t364.{core::Map::[]=}("bar", i);
+              }
+              else
+                break #L4;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t368 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        core::Map<core::String, dynamic> map30 = block {
+          #t364.{core::Map::[]=}("baz", null);
+        } =>#t364;
+        final core::List<core::int> #t369 = <core::int>[];
+        {
+          dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t370 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
-                                                         ^" in "not" as{TypeError} core::int, let final<BottomType> #t362 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                         ^" in "not" as{TypeError} core::int, let final<BottomType> #t371 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
-                                                                ^" in "int" as{TypeError} core::int]))
-            #t360.{core::List::add}(i);
-        } =>#t360;
+                                                                ^" in "int" as{TypeError} core::int]);
+          asy::_asyncStarListenHelper(:stream, :async_op);
+          asy::_StreamIterator<core::int> :for-iterator = new asy::_StreamIterator::•<core::int>(:stream);
+          const core::bool :product-mode = const core::bool::fromEnvironment("dart.vm.product");
+          try
+            #L5:
+            while (true) {
+              dynamic #t372 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t373 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                core::int i = :for-iterator.{asy::_StreamIterator::current};
+                #t369.{core::List::add}(i);
+              }
+              else
+                break #L5;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t374 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        core::List<core::int> list40 = block {} =>#t369;
+        final core::Set<core::int> #t375 = col::LinkedHashSet::•<core::int>();
+        {
+          dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t376 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
+                                                        ^" in "not" as{TypeError} core::int, let final<BottomType> #t377 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
+                                                               ^" in "int" as{TypeError} core::int]);
+          asy::_asyncStarListenHelper(:stream, :async_op);
+          asy::_StreamIterator<core::int> :for-iterator = new asy::_StreamIterator::•<core::int>(:stream);
+          const core::bool :product-mode = const core::bool::fromEnvironment("dart.vm.product");
+          try
+            #L6:
+            while (true) {
+              dynamic #t378 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t379 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                core::int i = :for-iterator.{asy::_StreamIterator::current};
+                #t375.{core::Set::add}(i);
+              }
+              else
+                break #L6;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t380 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
         core::Set<core::int> set40 = block {
-          final core::Set<core::int> #t363 = col::LinkedHashSet::•<core::int>();
-          await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t364 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          #t375.{core::Set::add}(null);
+        } =>#t375;
+        final core::Map<core::String, core::int> #t381 = <core::String, core::int>{};
+        {
+          dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t382 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
-                                                        ^" in "not" as{TypeError} core::int, let final<BottomType> #t365 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+  var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
+                                                        ^" in "not" as{TypeError} core::int, let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
-                                                               ^" in "int" as{TypeError} core::int]))
-            #t363.{core::Set::add}(i);
-          #t363.{core::Set::add}(null);
-        } =>#t363;
+  var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
+                                                               ^" in "int" as{TypeError} core::int]);
+          asy::_asyncStarListenHelper(:stream, :async_op);
+          asy::_StreamIterator<core::int> :for-iterator = new asy::_StreamIterator::•<core::int>(:stream);
+          const core::bool :product-mode = const core::bool::fromEnvironment("dart.vm.product");
+          try
+            #L7:
+            while (true) {
+              dynamic #t384 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t385 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                core::int i = :for-iterator.{asy::_StreamIterator::current};
+                #t381.{core::Map::[]=}("bar", i);
+              }
+              else
+                break #L7;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t386 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
         core::Map<core::String, core::int> map40 = block {
-          final core::Map<core::String, core::int> #t366 = <core::String, core::int>{};
-          await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t367 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
-                                                        ^" in "not" as{TypeError} core::int, let final<BottomType> #t368 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
-                                                               ^" in "int" as{TypeError} core::int]))
-            #t366.{core::Map::[]=}("bar", i);
-          #t366.{core::Map::[]=}("baz", null);
-        } =>#t366;
+          #t381.{core::Map::[]=}("baz", null);
+        } =>#t381;
         core::List<core::int> list50 = block {
-          final core::List<core::int> #t369 = <core::int>[];
+          final core::List<core::int> #t387 = <core::int>[];
           for (; ; )
-            #t369.{core::List::add}(42);
-        } =>#t369;
+            #t387.{core::List::add}(42);
+        } =>#t387;
         core::Set<core::int> set50 = block {
-          final core::Set<core::int> #t370 = col::LinkedHashSet::•<core::int>();
+          final core::Set<core::int> #t388 = col::LinkedHashSet::•<core::int>();
           for (; ; )
-            #t370.{core::Set::add}(42);
-          #t370.{core::Set::add}(null);
-        } =>#t370;
+            #t388.{core::Set::add}(42);
+          #t388.{core::Set::add}(null);
+        } =>#t388;
         core::Map<core::String, core::int> map50 = block {
-          final core::Map<core::String, core::int> #t371 = <core::String, core::int>{};
+          final core::Map<core::String, core::int> #t389 = <core::String, core::int>{};
           for (; ; )
-            #t371.{core::Map::[]=}("bar", 42);
-          #t371.{core::Map::[]=}("baz", null);
-        } =>#t371;
+            #t389.{core::Map::[]=}("bar", 42);
+          #t389.{core::Map::[]=}("baz", null);
+        } =>#t389;
         core::List<core::int> list60 = block {
-          final core::List<core::int> #t372 = <core::int>[];
-          for (; let final<BottomType> #t373 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:229:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+          final core::List<core::int> #t390 = <core::int>[];
+          for (; let final<BottomType> #t391 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:229:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var list60 = [for (; \"not bool\";) 42];
                        ^" in "not bool" as{TypeError} core::bool; )
-            #t372.{core::List::add}(42);
-        } =>#t372;
+            #t390.{core::List::add}(42);
+        } =>#t390;
         core::Set<core::int> set60 = block {
-          final core::Set<core::int> #t374 = col::LinkedHashSet::•<core::int>();
-          for (; let final<BottomType> #t375 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:230:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+          final core::Set<core::int> #t392 = col::LinkedHashSet::•<core::int>();
+          for (; let final<BottomType> #t393 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:230:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var set60 = {for (; \"not bool\";) 42, null};
                       ^" in "not bool" as{TypeError} core::bool; )
-            #t374.{core::Set::add}(42);
-          #t374.{core::Set::add}(null);
-        } =>#t374;
+            #t392.{core::Set::add}(42);
+          #t392.{core::Set::add}(null);
+        } =>#t392;
         core::Map<core::String, core::int> map60 = block {
-          final core::Map<core::String, core::int> #t376 = <core::String, core::int>{};
-          for (; let final<BottomType> #t377 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:231:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+          final core::Map<core::String, core::int> #t394 = <core::String, core::int>{};
+          for (; let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:231:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var map60 = {for (; \"not bool\";) \"bar\": 42, \"baz\": null};
                       ^" in "not bool" as{TypeError} core::bool; )
-            #t376.{core::Map::[]=}("bar", 42);
-          #t376.{core::Map::[]=}("baz", null);
-        } =>#t376;
+            #t394.{core::Map::[]=}("bar", 42);
+          #t394.{core::Map::[]=}("baz", null);
+        } =>#t394;
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
@@ -1989,19 +2117,19 @@
 }
 static method testForElementErrorsNotAsync(asy::Stream<core::int> stream) → dynamic {
   block {
-    final core::List<core::int> #t378 = <core::int>[];
+    final core::List<core::int> #t396 = <core::int>[];
     await for (core::int i in stream)
-      #t378.{core::List::add}(i);
-  } =>#t378;
+      #t396.{core::List::add}(i);
+  } =>#t396;
   block {
-    final core::Set<core::int> #t379 = col::LinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t397 = col::LinkedHashSet::•<core::int>();
     await for (core::int i in stream)
-      #t379.{core::Set::add}(i);
-  } =>#t379;
+      #t397.{core::Set::add}(i);
+  } =>#t397;
   block {
-    final core::Map<core::String, core::int> #t380 = <core::String, core::int>{};
+    final core::Map<core::String, core::int> #t398 = <core::String, core::int>{};
     await for (core::int i in stream)
-      #t380.{core::Map::[]=}("bar", i);
-  } =>#t380;
+      #t398.{core::Map::[]=}("bar", i);
+  } =>#t398;
 }
 static method main() → dynamic {}
diff --git a/pkg/kernel/lib/transformations/async.dart b/pkg/kernel/lib/transformations/async.dart
index 31fe3f3..dbdca9b 100644
--- a/pkg/kernel/lib/transformations/async.dart
+++ b/pkg/kernel/lib/transformations/async.dart
@@ -91,11 +91,13 @@
   Expression rewrite(Expression expression, List<Statement> outer) {
     assert(statements.isEmpty);
     assert(nameIndex == 0);
+    var saved = seenAwait;
     seenAwait = false;
     Expression result = expression.accept(this);
     outer.addAll(statements.reversed);
     statements.clear();
     nameIndex = 0;
+    seenAwait = seenAwait || saved;
     return result;
   }
 
@@ -503,4 +505,42 @@
         new RecursiveContinuationRewriter(continuationRewriter.helper);
     return node.accept(nestedRewriter);
   }
+
+  TreeNode visitBlockExpression(BlockExpression expr) {
+    return transform(expr, () {
+      expr.value = expr.value.accept(this)..parent = expr;
+      List<Statement> body = <Statement>[];
+      for (Statement stmt in expr.body.statements.reversed) {
+        Statement translation = stmt.accept(this);
+        if (translation != null) body.add(translation);
+      }
+      expr.body = new Block(body.reversed.toList())..parent = expr;
+    });
+  }
+
+  TreeNode defaultStatement(Statement stmt) {
+    // This method translates a statement nested in an expression (e.g., in a
+    // block expression).  It produces a translated statement, a list of
+    // statements which are side effects necessary for any await, and a flag
+    // indicating whether there was an await in the statement or to its right.
+    // The translated statement can be null in the case where there was already
+    // an await to the right.
+
+    // The translation is accumulating two lists of statements, an inner list
+    // which is a reversed list of effects needed for the current expression and
+    // an outer list which represents the block containing the current
+    // statement.  We need to preserve both of those from side effects.
+    List<Statement> savedInner = statements;
+    List<Statement> savedOuter = continuationRewriter.statements;
+    statements = <Statement>[];
+    continuationRewriter.statements = <Statement>[];
+    stmt.accept(continuationRewriter);
+
+    List<Statement> results = continuationRewriter.statements;
+    statements = savedInner;
+    continuationRewriter.statements = savedOuter;
+    if (!seenAwait && results.length == 1) return results.first;
+    statements.addAll(results.reversed);
+    return null;
+  }
 }
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 4891974..53267cd 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -193,8 +193,6 @@
 constructor6_test: CompileTimeError # Verification error
 control_flow_collections/await_for_inference_test: CompileTimeError
 control_flow_collections/await_for_test: CompileTimeError
-control_flow_collections/for_await_test: Crash
-control_flow_collections/if_await_test: Crash
 control_flow_collections/if_const_error_test/21: MissingCompileTimeError
 control_flow_collections/if_const_error_test/22: MissingCompileTimeError
 control_flow_collections/if_const_error_test/23: MissingCompileTimeError
@@ -232,7 +230,6 @@
 implicit_creation/implicit_const_not_default_values_test/e7: MissingCompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e8: MissingCompileTimeError
 mixin_method_override_test/G4: Crash # Assertion error: mixin_full_resolution.dart': 'src.typeParameters.length == dst.typeParameters.length': is not true.
-spread_collections/await_test: Crash
 spread_collections/const_error_test/12: MissingCompileTimeError
 spread_collections/const_error_test/13: Crash
 spread_collections/const_error_test/13: MissingCompileTimeError