[vm/kernel] Preserve strong mode types in async transformation

Async transformation uses dynamic variables in few places (e.g.
for temporaries and for incomming arguments) - which creates
not strongly typed AST with method invocations having dynamic
receivers and non-null interface targets at the same time.

To maintain strong typedness of the AST we insert unsafeCast
when accessing the temporaries.

Bug: https://github.com/dart-lang/sdk/issues/34463
Change-Id: I11e38c128645ebc8acb0c982a80fe4c5c4036673
Reviewed-on: https://dart-review.googlesource.com/75000
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
diff --git a/pkg/front_end/testcases/async_function.dart.direct.transformed.expect b/pkg/front_end/testcases/async_function.dart.direct.transformed.expect
index d09ecec..6638f7c 100644
--- a/pkg/front_end/testcases/async_function.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/async_function.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static field core::List<core::String> stringList = <dynamic>["bar"];
 static method asyncString() → asy::Future<core::String> /* originally async */ {
@@ -118,7 +119,7 @@
           else
             [yield] null;
           [yield] let dynamic #t1 = asy::_awaitHelper(self::asyncString(), :async_op_then, :async_op_error, :async_op) in null;
-          if(:controller.{asy::_AsyncStarStreamController::add}(:result))
+          if(:controller.{asy::_AsyncStarStreamController::add}(_in::unsafeCast<core::String>(:result)))
             return null;
           else
             [yield] null;
@@ -187,7 +188,7 @@
       #L5:
       {
         [yield] let dynamic #t2 = asy::_awaitHelper(self::asyncString(), :async_op_then, :async_op_error, :async_op) in null;
-        core::String str = :result;
+        core::String str = _in::unsafeCast<core::String>(:result);
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
diff --git a/pkg/front_end/testcases/async_nested.dart.direct.transformed.expect b/pkg/front_end/testcases/async_nested.dart.direct.transformed.expect
index da3a56f..1d8ba8f 100644
--- a/pkg/front_end/testcases/async_nested.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/async_nested.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class Node extends core::Object {
   final field core::List<self::Node> nested;
@@ -43,7 +44,7 @@
         [yield] let dynamic #t9 = asy::_awaitHelper(asy::Future::value<dynamic>(new self::Node::•("3", <dynamic>[:result])), :async_op_then, :async_op_error, :async_op) in null;
         :async_temporary_0 = :result;
         [yield] let dynamic #t10 = asy::_awaitHelper(asy::Future::value<dynamic>(new self::Node::•("10", <dynamic>[])), :async_op_then, :async_op_error, :async_op) in null;
-        self::Node node = new self::Node::•("1", <dynamic>[:async_temporary_2, :async_temporary_0, :result]);
+        self::Node node = new self::Node::•("1", <dynamic>[_in::unsafeCast<self::Node>(:async_temporary_2), :async_temporary_0, :result]);
         core::String actual = node.toSimpleString();
         core::print(actual);
         if(!actual.==(expected)) {
diff --git a/pkg/front_end/testcases/async_nested.dart.strong.transformed.expect b/pkg/front_end/testcases/async_nested.dart.strong.transformed.expect
index 39cfaaf..17767e7 100644
--- a/pkg/front_end/testcases/async_nested.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/async_nested.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class Node extends core::Object {
   final field core::List<self::Node> nested;
@@ -34,16 +35,16 @@
         core::String expected = "1 2 3 4 5 6 7 8 9 10";
         :async_temporary_2 = new self::Node::•("2", <self::Node>[]);
         [yield] let dynamic #t4 = asy::_awaitHelper(asy::Future::value<self::Node>(new self::Node::•("7", <self::Node>[])), :async_op_then, :async_op_error, :async_op) in null;
-        [yield] let dynamic #t5 = asy::_awaitHelper(asy::Future::value<self::Node>(new self::Node::•("6", <self::Node>[:result])), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t5 = asy::_awaitHelper(asy::Future::value<self::Node>(new self::Node::•("6", <self::Node>[_in::unsafeCast<self::Node>(:result)])), :async_op_then, :async_op_error, :async_op) in null;
         :async_temporary_1 = :result;
         [yield] let dynamic #t6 = asy::_awaitHelper(asy::Future::value<self::Node>(new self::Node::•("8", <self::Node>[])), :async_op_then, :async_op_error, :async_op) in null;
         :async_temporary_0 = :result;
         [yield] let dynamic #t7 = asy::_awaitHelper(asy::Future::value<self::Node>(new self::Node::•("9", <self::Node>[])), :async_op_then, :async_op_error, :async_op) in null;
-        [yield] let dynamic #t8 = asy::_awaitHelper(asy::Future::value<self::Node>(new self::Node::•("4", <self::Node>[new self::Node::•("5", <self::Node>[:async_temporary_1, :async_temporary_0, :result])])), :async_op_then, :async_op_error, :async_op) in null;
-        [yield] let dynamic #t9 = asy::_awaitHelper(asy::Future::value<self::Node>(new self::Node::•("3", <self::Node>[:result])), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t8 = asy::_awaitHelper(asy::Future::value<self::Node>(new self::Node::•("4", <self::Node>[new self::Node::•("5", <self::Node>[_in::unsafeCast<self::Node>(:async_temporary_1), _in::unsafeCast<self::Node>(:async_temporary_0), _in::unsafeCast<self::Node>(:result)])])), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t9 = asy::_awaitHelper(asy::Future::value<self::Node>(new self::Node::•("3", <self::Node>[_in::unsafeCast<self::Node>(:result)])), :async_op_then, :async_op_error, :async_op) in null;
         :async_temporary_0 = :result;
         [yield] let dynamic #t10 = asy::_awaitHelper(asy::Future::value<self::Node>(new self::Node::•("10", <self::Node>[])), :async_op_then, :async_op_error, :async_op) in null;
-        self::Node node = new self::Node::•("1", <self::Node>[:async_temporary_2, :async_temporary_0, :result]);
+        self::Node node = new self::Node::•("1", <self::Node>[_in::unsafeCast<self::Node>(:async_temporary_2), _in::unsafeCast<self::Node>(:async_temporary_0), _in::unsafeCast<self::Node>(:result)]);
         core::String actual = node.{self::Node::toSimpleString}() as{TypeError} core::String;
         core::print(actual);
         if(!actual.{core::String::==}(expected)) {
diff --git a/pkg/front_end/testcases/await.dart.direct.transformed.expect b/pkg/front_end/testcases/await.dart.direct.transformed.expect
index 7693f8c..655215a 100644
--- a/pkg/front_end/testcases/await.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/await.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method main() → dynamic /* originally async */ {
   final asy::Completer<dynamic> :async_completer = asy::Completer::sync<dynamic>();
@@ -17,7 +18,7 @@
       #L1:
       {
         [yield] let dynamic #t1 = asy::_awaitHelper("Hello, World!", :async_op_then, :async_op_error, :async_op) in null;
-        core::print(:result);
+        core::print(_in::unsafeCast<core::String>(:result));
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
diff --git a/pkg/front_end/testcases/bug33206.dart.direct.transformed.expect b/pkg/front_end/testcases/bug33206.dart.direct.transformed.expect
index b5f9c88..b27bff7 100644
--- a/pkg/front_end/testcases/bug33206.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/bug33206.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class X extends core::Object {
   final field dynamic x;
@@ -89,10 +90,10 @@
       {
         final dynamic #t1 = new self::Y::•();
         [yield] let dynamic #t2 = asy::_awaitHelper(self::f1(), :async_op_then, :async_op_error, :async_op) in null;
-        final dynamic #t3 = #t1.f(:result);
+        final dynamic #t3 = #t1.f(_in::unsafeCast<core::List<core::Object>>(:result));
         final dynamic #t4 = #t1.f(self::f2());
         [yield] let dynamic #t5 = asy::_awaitHelper(self::f3(), :async_op_then, :async_op_error, :async_op) in null;
-        :return_value = new self::X::•(#t1, :result);
+        :return_value = new self::X::•(#t1, _in::unsafeCast<core::Object>(:result));
         break #L3;
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -121,7 +122,7 @@
       #L4:
       {
         [yield] let dynamic #t6 = asy::_awaitHelper(self::foo(), :async_op_then, :async_op_error, :async_op) in null;
-        core::print(:result);
+        core::print(_in::unsafeCast<self::X>(:result));
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
diff --git a/pkg/front_end/testcases/bug33206.dart.strong.transformed.expect b/pkg/front_end/testcases/bug33206.dart.strong.transformed.expect
index 072c2fe..5643449 100644
--- a/pkg/front_end/testcases/bug33206.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/bug33206.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class X extends core::Object {
   final field dynamic x;
@@ -89,10 +90,10 @@
       {
         final self::Y #t1 = new self::Y::•();
         [yield] let dynamic #t2 = asy::_awaitHelper(self::f1(), :async_op_then, :async_op_error, :async_op) in null;
-        final dynamic #t3 = #t1.{self::Y::f}(:result);
+        final dynamic #t3 = #t1.{self::Y::f}(_in::unsafeCast<core::List<core::Object>>(:result));
         final dynamic #t4 = #t1.{self::Y::f}(self::f2());
         [yield] let dynamic #t5 = asy::_awaitHelper(self::f3(), :async_op_then, :async_op_error, :async_op) in null;
-        :return_value = new self::X::•(#t1, :result);
+        :return_value = new self::X::•(#t1, _in::unsafeCast<core::Object>(:result));
         break #L3;
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -121,7 +122,7 @@
       #L4:
       {
         [yield] let dynamic #t6 = asy::_awaitHelper(self::foo(), :async_op_then, :async_op_error, :async_op) in null;
-        core::print(:result);
+        core::print(_in::unsafeCast<self::X>(:result));
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
diff --git a/pkg/front_end/testcases/inference/async_await.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/async_await.dart.direct.transformed.expect
index d797b5d..a358731 100644
--- a/pkg/front_end/testcases/inference/async_await.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_await.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 abstract class MyFuture extends core::Object implements asy::Future<core::int> {
   synthetic constructor •() → void
@@ -302,25 +303,25 @@
           return :async_completer.{asy::Completer::future};
         }
         [yield] let dynamic #t1 = asy::_awaitHelper(x0, :async_op_then, :async_op_error, :async_op) in null;
-        dynamic y0 = :result;
+        dynamic y0 = _in::unsafeCast<core::int>(:result);
         [yield] let dynamic #t2 = asy::_awaitHelper(x1, :async_op_then, :async_op_error, :async_op) in null;
-        dynamic y1 = :result;
+        dynamic y1 = _in::unsafeCast<core::int>(:result);
         [yield] let dynamic #t3 = asy::_awaitHelper(x2, :async_op_then, :async_op_error, :async_op) in null;
-        dynamic y2 = :result;
+        dynamic y2 = _in::unsafeCast<asy::Future<core::int>>(:result);
         [yield] let dynamic #t4 = asy::_awaitHelper(x3, :async_op_then, :async_op_error, :async_op) in null;
-        dynamic y3 = :result;
+        dynamic y3 = _in::unsafeCast<asy::FutureOr<core::int>>(:result);
         [yield] let dynamic #t5 = asy::_awaitHelper(x4, :async_op_then, :async_op_error, :async_op) in null;
-        dynamic y4 = :result;
+        dynamic y4 = _in::unsafeCast<self::MyFuture>(:result);
         [yield] let dynamic #t6 = asy::_awaitHelper(x5, :async_op_then, :async_op_error, :async_op) in null;
-        dynamic y5 = :result;
+        dynamic y5 = _in::unsafeCast<core::int>(:result);
         [yield] let dynamic #t7 = asy::_awaitHelper(x6, :async_op_then, :async_op_error, :async_op) in null;
-        dynamic y6 = :result;
+        dynamic y6 = _in::unsafeCast<asy::Future<core::int>>(:result);
         [yield] let dynamic #t8 = asy::_awaitHelper(x7, :async_op_then, :async_op_error, :async_op) in null;
-        dynamic y7 = :result;
+        dynamic y7 = _in::unsafeCast<asy::FutureOr<core::int>>(:result);
         [yield] let dynamic #t9 = asy::_awaitHelper(x8, :async_op_then, :async_op_error, :async_op) in null;
-        dynamic y8 = :result;
+        dynamic y8 = _in::unsafeCast<self::MyFuture>(:result);
         [yield] let dynamic #t10 = asy::_awaitHelper(x9, :async_op_then, :async_op_error, :async_op) in null;
-        dynamic y9 = :result;
+        dynamic y9 = _in::unsafeCast<core::int>(:result);
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
diff --git a/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
index e437f50..353e4cf 100644
--- a/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 abstract class MyFuture extends core::Object implements asy::Future<core::int> {
   synthetic constructor •() → void
@@ -302,25 +303,25 @@
           return :async_completer.{asy::Completer::future};
         }
         [yield] let dynamic #t1 = asy::_awaitHelper(x0, :async_op_then, :async_op_error, :async_op) in null;
-        core::int y0 = :result;
+        core::int y0 = _in::unsafeCast<core::int>(:result);
         [yield] let dynamic #t2 = asy::_awaitHelper(x1, :async_op_then, :async_op_error, :async_op) in null;
-        core::int y1 = :result;
+        core::int y1 = _in::unsafeCast<core::int>(:result);
         [yield] let dynamic #t3 = asy::_awaitHelper(x2, :async_op_then, :async_op_error, :async_op) in null;
-        asy::Future<core::int> y2 = :result;
+        asy::Future<core::int> y2 = _in::unsafeCast<asy::Future<core::int>>(:result);
         [yield] let dynamic #t4 = asy::_awaitHelper(x3, :async_op_then, :async_op_error, :async_op) in null;
-        asy::FutureOr<core::int> y3 = :result;
+        asy::FutureOr<core::int> y3 = _in::unsafeCast<asy::FutureOr<core::int>>(:result);
         [yield] let dynamic #t5 = asy::_awaitHelper(x4, :async_op_then, :async_op_error, :async_op) in null;
-        self::MyFuture y4 = :result;
+        self::MyFuture y4 = _in::unsafeCast<self::MyFuture>(:result);
         [yield] let dynamic #t6 = asy::_awaitHelper(x5, :async_op_then, :async_op_error, :async_op) in null;
-        core::int y5 = :result;
+        core::int y5 = _in::unsafeCast<core::int>(:result);
         [yield] let dynamic #t7 = asy::_awaitHelper(x6, :async_op_then, :async_op_error, :async_op) in null;
-        asy::Future<core::int> y6 = :result;
+        asy::Future<core::int> y6 = _in::unsafeCast<asy::Future<core::int>>(:result);
         [yield] let dynamic #t8 = asy::_awaitHelper(x7, :async_op_then, :async_op_error, :async_op) in null;
-        asy::FutureOr<core::int> y7 = :result;
+        asy::FutureOr<core::int> y7 = _in::unsafeCast<asy::FutureOr<core::int>>(:result);
         [yield] let dynamic #t9 = asy::_awaitHelper(x8, :async_op_then, :async_op_error, :async_op) in null;
-        self::MyFuture y8 = :result;
+        self::MyFuture y8 = _in::unsafeCast<self::MyFuture>(:result);
         [yield] let dynamic #t10 = asy::_awaitHelper(x9, :async_op_then, :async_op_error, :async_op) in null;
-        core::int y9 = :result;
+        core::int y9 = _in::unsafeCast<core::int>(:result);
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
index 510f5e8..562bee8 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method main() → dynamic /* originally async */ {
   final asy::Completer<dynamic> :async_completer = asy::Completer::sync<dynamic>();
@@ -46,7 +47,7 @@
         asy::Future<dynamic> y = f.call();
         asy::Future<core::String> z = f.call();
         [yield] let dynamic #t1 = asy::_awaitHelper(f.call(), :async_op_then, :async_op_error, :async_op) in null;
-        core::String s = :result;
+        core::String s = _in::unsafeCast<core::Null>(:result);
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
index 3b73b9c..26f025e 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method main() → dynamic /* originally async */ {
   final asy::Completer<dynamic> :async_completer = asy::Completer::sync<dynamic>();
@@ -54,7 +55,7 @@
         asy::Stream<dynamic> y = f.call();
         asy::Stream<core::String> z = f.call();
         [yield] let dynamic #t1 = asy::_awaitHelper(f.call().{asy::Stream::first}, :async_op_then, :async_op_error, :async_op) in null;
-        core::String s = :result;
+        core::String s = _in::unsafeCast<core::Null>(:result);
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.direct.transformed.expect
index af02e87..8e76657 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method main() → asy::Future<dynamic> /* originally async */ {
   final asy::Completer<dynamic> :async_completer = asy::Completer::sync<dynamic>();
@@ -18,7 +19,7 @@
       {
         dynamic d;
         [yield] let dynamic #t1 = asy::_awaitHelper(<dynamic>[d], :async_op_then, :async_op_error, :async_op) in null;
-        core::List<core::int> l0 = :result;
+        core::List<core::int> l0 = _in::unsafeCast<core::List<dynamic>>(:result);
         [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<dynamic>(<dynamic>[d]), :async_op_then, :async_op_error, :async_op) in null;
         core::List<core::int> l1 = :result;
       }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect
index fdda593..ef93ec0 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method main() → asy::Future<dynamic> /* originally async */ {
   final asy::Completer<dynamic> :async_completer = asy::Completer::sync<dynamic>();
@@ -18,9 +19,9 @@
       {
         dynamic d;
         [yield] let dynamic #t1 = asy::_awaitHelper(<core::int>[d as{TypeError} core::int], :async_op_then, :async_op_error, :async_op) in null;
-        core::List<core::int> l0 = :result;
+        core::List<core::int> l0 = _in::unsafeCast<core::List<core::int>>(:result);
         [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::List<core::int>>(<core::int>[d as{TypeError} core::int]), :async_op_then, :async_op_error, :async_op) in null;
-        core::List<core::int> l1 = :result;
+        core::List<core::int> l1 = _in::unsafeCast<core::List<core::int>>(:result);
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.direct.transformed.expect
index c6a2b38..8bbd33f 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 abstract class MyStream<T extends core::Object = dynamic> extends asy::Stream<self::MyStream::T> {
   static factory •<T extends core::Object = dynamic>() → self::MyStream<self::MyStream::•::T>
@@ -49,7 +50,7 @@
             while (true) {
               dynamic #t3 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic x = :for-iterator.{asy::_StreamIterator::current};
                 {}
               }
@@ -72,7 +73,7 @@
             while (true) {
               dynamic #t6 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t7 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic x = :for-iterator.{asy::_StreamIterator::current};
                 {}
               }
@@ -95,7 +96,7 @@
             while (true) {
               dynamic #t9 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t10 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 core::Object x = :for-iterator.{asy::_StreamIterator::current};
                 {}
               }
@@ -118,7 +119,7 @@
             while (true) {
               dynamic #t12 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t13 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final dynamic #t14 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   d = #t14;
@@ -143,7 +144,7 @@
             while (true) {
               dynamic #t16 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t17 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final dynamic #t18 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   o = #t18;
@@ -203,7 +204,7 @@
             while (true) {
               dynamic #t20 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t21 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 core::int x = :for-iterator.{asy::_StreamIterator::current};
                 {}
               }
@@ -226,7 +227,7 @@
             while (true) {
               dynamic #t23 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t24 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic x = :for-iterator.{asy::_StreamIterator::current};
                 {}
               }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect
index 60d8dbb..d174a2f 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 abstract class MyStream<T extends core::Object = dynamic> extends asy::Stream<self::MyStream::T> {
   static factory •<T extends core::Object = dynamic>() → self::MyStream<self::MyStream::•::T>
@@ -49,7 +50,7 @@
             while (true) {
               dynamic #t3 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic x = :for-iterator.{asy::_StreamIterator::current};
                 {}
               }
@@ -72,7 +73,7 @@
             while (true) {
               dynamic #t6 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t7 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic x = :for-iterator.{asy::_StreamIterator::current};
                 {}
               }
@@ -95,7 +96,7 @@
             while (true) {
               dynamic #t9 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t10 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 core::Object x = :for-iterator.{asy::_StreamIterator::current};
                 {}
               }
@@ -118,7 +119,7 @@
             while (true) {
               dynamic #t12 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t13 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final dynamic #t14 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   d = #t14;
@@ -143,7 +144,7 @@
             while (true) {
               dynamic #t16 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t17 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final core::Object #t18 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   o = #t18;
@@ -203,7 +204,7 @@
             while (true) {
               dynamic #t20 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t21 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 core::int x = :for-iterator.{asy::_StreamIterator::current};
                 {}
               }
@@ -226,7 +227,7 @@
             while (true) {
               dynamic #t23 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t24 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 core::int x = :for-iterator.{asy::_StreamIterator::current};
                 {}
               }
diff --git a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.direct.transformed.expect
index 46d4a06..8ac230e 100644
--- a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method test() → dynamic /* originally async */ {
   final asy::Completer<dynamic> :async_completer = asy::Completer::sync<dynamic>();
@@ -32,7 +33,7 @@
             while (true) {
               dynamic #t1 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t2 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic x = :for-iterator.{asy::_StreamIterator::current};
                 {}
               }
@@ -59,7 +60,7 @@
             while (true) {
               dynamic #t5 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t6 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final dynamic #t7 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   y = #t7;
diff --git a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect
index abfce65..faa9884 100644
--- a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method test() → dynamic /* originally async */ {
   final asy::Completer<dynamic> :async_completer = asy::Completer::sync<dynamic>();
@@ -32,7 +33,7 @@
             while (true) {
               dynamic #t1 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t2 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic x = :for-iterator.{asy::_StreamIterator::current};
                 {}
               }
@@ -59,7 +60,7 @@
             while (true) {
               dynamic #t5 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t6 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final dynamic #t7 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   y = #t7 as{TypeError} core::int;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect
index f27ed38..6159047 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -37,7 +38,7 @@
         #L1:
         {
           [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -66,7 +67,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
index 8b41d75..18ab021 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -37,7 +38,7 @@
         #L1:
         {
           [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -66,7 +67,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect
index 20ee8d1..d395a35 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -37,7 +38,7 @@
         #L1:
         {
           [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -66,7 +67,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
index 7927f17..3648d5c 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -37,7 +38,7 @@
         #L1:
         {
           [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -66,7 +67,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect
index c6d3766..9131ddc 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -37,7 +38,7 @@
         #L1:
         {
           [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -66,7 +67,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
index 775141b..d8d112a 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -37,7 +38,7 @@
         #L1:
         {
           [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -66,7 +67,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect
index 8f4e8ca..9fc9fc2 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -37,7 +38,7 @@
         #L1:
         {
           [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -66,7 +67,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
index dacc8a3..10a8e11 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -37,7 +38,7 @@
         #L1:
         {
           [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -66,7 +67,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect
index a617678..c6b8288 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -37,7 +38,7 @@
         #L1:
         {
           [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -66,7 +67,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
index b1614ca..0982974 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -37,7 +38,7 @@
         #L1:
         {
           [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -66,7 +67,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect
index 925090f..8a90334 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -37,7 +38,7 @@
         #L1:
         {
           [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -66,7 +67,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
index a13a479..5b0165f 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -37,7 +38,7 @@
         #L1:
         {
           [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -66,7 +67,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = :result;
+          :return_value = _in::unsafeCast<core::int>(:result);
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
index b5a19f3..182d288 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -44,7 +45,7 @@
             [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
             :async_temporary_0 = :result;
           }
-          :return_value = :async_temporary_0;
+          :return_value = _in::unsafeCast<core::int>(:async_temporary_0);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -73,7 +74,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = (:result ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+          :return_value = (_in::unsafeCast<core::bool>(:result) ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
index b0dbd8f..da226cc 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -44,7 +45,7 @@
             [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
             :async_temporary_0 = :result;
           }
-          :return_value = :async_temporary_0;
+          :return_value = _in::unsafeCast<core::int>(:async_temporary_0);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -73,7 +74,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = (:result ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+          :return_value = (_in::unsafeCast<core::bool>(:result) ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
index e855e8b..1c95710 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -44,7 +45,7 @@
             [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
             :async_temporary_0 = :result;
           }
-          :return_value = :async_temporary_0;
+          :return_value = _in::unsafeCast<core::int>(:async_temporary_0);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -73,7 +74,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = (:result ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+          :return_value = (_in::unsafeCast<core::bool>(:result) ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
index b567ae6..f4b49d2 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -44,7 +45,7 @@
             [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
             :async_temporary_0 = :result;
           }
-          :return_value = :async_temporary_0;
+          :return_value = _in::unsafeCast<core::int>(:async_temporary_0);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -73,7 +74,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = (:result ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+          :return_value = (_in::unsafeCast<core::bool>(:result) ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
index 5bd9628..a710edd 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -44,7 +45,7 @@
             [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
             :async_temporary_0 = :result;
           }
-          :return_value = :async_temporary_0;
+          :return_value = _in::unsafeCast<core::int>(:async_temporary_0);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -73,7 +74,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = (:result ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+          :return_value = (_in::unsafeCast<core::bool>(:result) ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
index 03e6d37..eecf17f 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -44,7 +45,7 @@
             [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
             :async_temporary_0 = :result;
           }
-          :return_value = :async_temporary_0;
+          :return_value = _in::unsafeCast<core::int>(:async_temporary_0);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -73,7 +74,7 @@
         #L2:
         {
           [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = (:result ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+          :return_value = (_in::unsafeCast<core::bool>(:result) ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
index c1cd7d1..b08ab2d 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → void
@@ -45,7 +46,7 @@
           else {
             :async_temporary_0 = #t1;
           }
-          :return_value = :async_temporary_0;
+          :return_value = _in::unsafeCast<core::int>(:async_temporary_0);
           break #L1;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -74,7 +75,7 @@
         #L2:
         {
           [yield] let dynamic #t3 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
-          :return_value = (let final core::int #t4 = :result in #t4.==(null) ?{core::Object} asy::Future::value<core::int>(3) : #t4) as{TypeError} asy::FutureOr<core::int>;
+          :return_value = (let final core::int #t4 = _in::unsafeCast<core::int>(:result) in #t4.==(null) ?{core::Object} asy::Future::value<core::int>(3) : #t4) as{TypeError} asy::FutureOr<core::int>;
           break #L2;
         }
         asy::_completeOnAsyncReturn(:async_completer, :return_value);
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.direct.transformed.expect
index 89b8af9..4461a83 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class A extends core::Object {
   synthetic constructor •() → void
@@ -24,7 +25,7 @@
         asy::Future<core::List<self::A>> f1 = null;
         asy::Future<core::List<self::A>> f2 = null;
         [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::wait<dynamic>(<dynamic>[f1, f2]), :async_op_then, :async_op_error, :async_op) in null;
-        core::List<core::List<self::A>> merged = :result;
+        core::List<core::List<self::A>> merged = _in::unsafeCast<core::List<dynamic>>(:result);
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect
index 1bc6ed6..a9c9d22 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class A extends core::Object {
   synthetic constructor •() → void
@@ -24,7 +25,7 @@
         asy::Future<core::List<self::A>> f1 = null;
         asy::Future<core::List<self::A>> f2 = null;
         [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::wait<core::List<self::A>>(<asy::Future<core::List<self::A>>>[f1, f2]), :async_op_then, :async_op_error, :async_op) in null;
-        core::List<core::List<self::A>> merged = :result;
+        core::List<core::List<self::A>> merged = _in::unsafeCast<core::List<core::List<self::A>>>(:result);
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect
index 8a4ec7e..806190b 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 static method id<T extends core::Object = dynamic>(self::id::T x) → self::id::T
   return x;
@@ -20,7 +21,7 @@
       {
         asy::Future<core::String> f;
         [yield] let dynamic #t1 = asy::_awaitHelper(self::id<asy::FutureOr<core::String>>(f), :async_op_then, :async_op_error, :async_op) in null;
-        core::String s = :result;
+        core::String s = _in::unsafeCast<core::String>(:result);
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.direct.transformed.expect
index 7bc149c..ebe93d9 100644
--- a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class A extends core::Object {
   synthetic constructor •() → void
@@ -35,9 +36,9 @@
         dynamic c = asy::Future::value<self::C>(new self::C::•());
         dynamic lll = <dynamic>[b, c];
         [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::wait<dynamic>(lll), :async_op_then, :async_op_error, :async_op) in null;
-        dynamic result = :result;
+        dynamic result = _in::unsafeCast<core::List<dynamic>>(:result);
         [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::wait<dynamic>(<dynamic>[b, c]), :async_op_then, :async_op_error, :async_op) in null;
-        dynamic result2 = :result;
+        dynamic result2 = _in::unsafeCast<core::List<dynamic>>(:result);
         core::List<self::A> list = result;
         list = result2;
       }
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect
index e202cf1..9cba179 100644
--- a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class A extends core::Object {
   synthetic constructor •() → void
@@ -35,9 +36,9 @@
         asy::Future<self::C> c = asy::Future::value<self::C>(new self::C::•());
         core::List<asy::Future<self::A>> lll = <asy::Future<self::A>>[b, c];
         [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::wait<self::A>(lll), :async_op_then, :async_op_error, :async_op) in null;
-        core::List<self::A> result = :result;
+        core::List<self::A> result = _in::unsafeCast<core::List<self::A>>(:result);
         [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::wait<self::A>(<asy::Future<self::A>>[b, c]), :async_op_then, :async_op_error, :async_op) in null;
-        core::List<self::A> result2 = :result;
+        core::List<self::A> result2 = _in::unsafeCast<core::List<self::A>>(:result);
         core::List<self::A> list = result;
         list = result2;
       }
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.direct.transformed.expect
index 8c8c294..dfe5531 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class Foo extends core::Object {
   field core::int bar = 42;
@@ -39,7 +40,7 @@
               while (true) {
                 dynamic #t1 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
                 [yield] let dynamic #t2 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-                if(:result) {
+                if(_in::unsafeCast<core::bool>(:result)) {
                   dynamic i = :for-iterator.{asy::_StreamIterator::current};
                   {
                     core::int x = i;
@@ -98,7 +99,7 @@
               while (true) {
                 dynamic #t4 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
                 [yield] let dynamic #t5 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-                if(:result) {
+                if(_in::unsafeCast<core::bool>(:result)) {
                   dynamic i = :for-iterator.{asy::_StreamIterator::current};
                   {
                     core::int x = i;
@@ -159,7 +160,7 @@
             while (true) {
               dynamic #t7 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t8 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic x = :for-iterator.{asy::_StreamIterator::current};
                 {
                   core::String y = x;
@@ -184,7 +185,7 @@
             while (true) {
               dynamic #t10 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t11 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic x = :for-iterator.{asy::_StreamIterator::current};
                 {
                   core::String y = x;
@@ -209,7 +210,7 @@
             while (true) {
               dynamic #t13 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t14 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 core::String x = :for-iterator.{asy::_StreamIterator::current};
                 {
                   core::String y = x;
@@ -235,7 +236,7 @@
             while (true) {
               dynamic #t16 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t17 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final dynamic #t18 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   z = #t18;
@@ -262,7 +263,7 @@
             while (true) {
               dynamic #t20 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t21 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 self::Foo x = :for-iterator.{asy::_StreamIterator::current};
                 {
                   dynamic y = x;
@@ -288,7 +289,7 @@
             while (true) {
               dynamic #t23 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t24 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 self::Foo x = :for-iterator.{asy::_StreamIterator::current};
                 {
                   dynamic y = x;
@@ -314,7 +315,7 @@
             while (true) {
               dynamic #t26 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t27 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic x = :for-iterator.{asy::_StreamIterator::current};
                 {
                   core::String y = x;
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
index ac769ba..0f133b8 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class Foo extends core::Object {
   field core::int bar = 42;
@@ -39,7 +40,7 @@
               while (true) {
                 dynamic #t1 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
                 [yield] let dynamic #t2 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-                if(:result) {
+                if(_in::unsafeCast<core::bool>(:result)) {
                   core::String i = :for-iterator.{asy::_StreamIterator::current};
                   {
                     core::int x = let<BottomType> _ = null in let final dynamic #t3 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:17:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
@@ -101,7 +102,7 @@
               while (true) {
                 dynamic #t6 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
                 [yield] let dynamic #t7 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-                if(:result) {
+                if(_in::unsafeCast<core::bool>(:result)) {
                   self::Baz::T i = :for-iterator.{asy::_StreamIterator::current};
                   {
                     core::int x = let<BottomType> _ = null in let final dynamic #t8 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:25:44: Error: A value of type 'test::Baz::T' can't be assigned to a variable of type 'dart.core::int'.
@@ -165,7 +166,7 @@
             while (true) {
               dynamic #t11 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t12 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 self::Foo x = :for-iterator.{asy::_StreamIterator::current};
                 {
                   core::String y = let<BottomType> _ = null in let final dynamic #t13 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:38:45: Error: A value of type 'test::Foo' can't be assigned to a variable of type 'dart.core::String'.
@@ -193,7 +194,7 @@
             while (true) {
               dynamic #t16 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t17 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic x = :for-iterator.{asy::_StreamIterator::current};
                 {
                   core::String y = x as{TypeError} core::String;
@@ -218,7 +219,7 @@
             while (true) {
               dynamic #t19 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t20 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final self::Foo #t21 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   core::String x = let<BottomType> _ = null in let final dynamic #t22 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:45:21: Error: A value of type 'test::Foo' can't be assigned to a variable of type 'dart.core::String'.
@@ -248,7 +249,7 @@
             while (true) {
               dynamic #t25 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t26 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final self::Foo #t27 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   z = #t27;
@@ -275,7 +276,7 @@
             while (true) {
               dynamic #t29 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t30 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final dynamic #t31 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   self::Foo x = #t31 as{TypeError} self::Foo;
@@ -302,7 +303,7 @@
             while (true) {
               dynamic #t33 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t34 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final dynamic #t35 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   self::Foo x = #t35 as{TypeError} self::Foo;
@@ -331,7 +332,7 @@
             while (true) {
               dynamic #t39 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t40 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 dynamic x = :for-iterator.{asy::_StreamIterator::current};
                 {
                   core::String y = x as{TypeError} core::String;
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.direct.transformed.expect
index 3eefc91..547f641 100644
--- a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method test() → dynamic /* originally async */ {
   final asy::Completer<dynamic> :async_completer = asy::Completer::sync<dynamic>();
@@ -32,7 +33,7 @@
             while (true) {
               dynamic #t1 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t2 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 core::int x = :for-iterator.{asy::_StreamIterator::current};
                 {}
               }
@@ -59,7 +60,7 @@
             while (true) {
               dynamic #t5 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t6 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final dynamic #t7 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   y = #t7;
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect
index 002d2e6..93a1ee8 100644
--- a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 static method test() → dynamic /* originally async */ {
   final asy::Completer<dynamic> :async_completer = asy::Completer::sync<dynamic>();
@@ -37,7 +38,7 @@
             while (true) {
               dynamic #t6 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t7 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final dynamic #t8 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   core::int x = #t8 as{TypeError} core::int;
@@ -70,7 +71,7 @@
             while (true) {
               dynamic #t15 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t16 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final dynamic #t17 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   y = #t17 as{TypeError} core::int;
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.direct.transformed.expect
index 1c7200b..c914a79 100644
--- a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.direct.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class A extends core::Object {
   synthetic constructor •() → void
@@ -49,7 +50,7 @@
             while (true) {
               dynamic #t2 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t3 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final self::A #t4 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   a = #t4;
@@ -77,7 +78,7 @@
             while (true) {
               dynamic #t7 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t8 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final self::A #t9 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   b = #t9;
@@ -105,7 +106,7 @@
             while (true) {
               dynamic #t12 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t13 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final self::A #t14 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   i = #t14;
@@ -133,7 +134,7 @@
             while (true) {
               dynamic #t17 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t18 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final dynamic #t19 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   a = #t19;
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect
index ba7388f..6183231 100644
--- a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
+import "dart:_internal" as _in;
 
 class A extends core::Object {
   synthetic constructor •() → void
@@ -49,7 +50,7 @@
             while (true) {
               dynamic #t2 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t3 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final self::A #t4 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   a = #t4;
@@ -77,7 +78,7 @@
             while (true) {
               dynamic #t7 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t8 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final self::A #t9 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   b = #t9 as{TypeError} self::B;
@@ -108,7 +109,7 @@
             while (true) {
               dynamic #t14 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t15 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final self::A #t16 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   i = let<BottomType> _ = null in let final dynamic #t17 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart:27:61: Error: A value of type 'test::A' can't be assigned to a variable of type 'dart.core::int'.
@@ -139,7 +140,7 @@
             while (true) {
               dynamic #t21 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
               [yield] let dynamic #t22 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
-              if(:result) {
+              if(_in::unsafeCast<core::bool>(:result)) {
                 final self::A #t23 = :for-iterator.{asy::_StreamIterator::current};
                 {
                   a = #t23;
diff --git a/pkg/kernel/bin/transform.dart b/pkg/kernel/bin/transform.dart
index 9523e33..e3db3b5 100755
--- a/pkg/kernel/bin/transform.dart
+++ b/pkg/kernel/bin/transform.dart
@@ -86,7 +86,8 @@
   final hierarchy = new ClassHierarchy(component);
   switch (options['transformation']) {
     case 'continuation':
-      component = cont.transformComponent(coreTypes, component, syncAsync);
+      component =
+          cont.transformComponent(coreTypes, hierarchy, component, syncAsync);
       break;
     case 'resolve-mixins':
       mix.transformLibraries(
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index 485074d..0d71623 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -106,6 +106,8 @@
   Field _pragmaName;
   Field _pragmaOptions;
 
+  Procedure _unsafeCast;
+
   CoreTypes(Component component)
       : index = new LibraryIndex.coreLibraries(component);
 
@@ -230,6 +232,11 @@
         index.getMember('dart:_internal', 'ExternalName', '');
   }
 
+  Procedure get unsafeCast {
+    return _unsafeCast ??=
+        index.getMember('dart:_internal', '::', 'unsafeCast');
+  }
+
   Class get functionClass {
     return _functionClass ??= index.getClass('dart:core', 'Function');
   }
diff --git a/pkg/kernel/lib/transformations/async.dart b/pkg/kernel/lib/transformations/async.dart
index 7977045..4050e07 100644
--- a/pkg/kernel/lib/transformations/async.dart
+++ b/pkg/kernel/lib/transformations/async.dart
@@ -111,11 +111,36 @@
     return result;
   }
 
+  // If expression [from] has a non-dynamic static type then ensure that
+  // expression [to] would have the same static type by wrapping it into
+  // an appropriate unsafeCast.
+  Expression assignType(Expression to, Expression from) {
+    final fromType = from.getStaticType(continuationRewriter.helper.env);
+    if (fromType == null || fromType == const DynamicType()) {
+      return to;
+    }
+
+    return new StaticInvocation(continuationRewriter.helper.unsafeCast,
+        new Arguments(<Expression>[to], types: <DartType>[fromType]));
+  }
+
+  // Store a value into a temporary variable, dropping unnecessary unsafeCast
+  // if present (because all temporaries are of dynamic type).
+  VariableSet storeTemporary(VariableDeclaration v, Expression value) {
+    assert(v.type == const DynamicType());
+    Expression unwrapped = value;
+    if (value is StaticInvocation &&
+        value.target == continuationRewriter.helper.unsafeCast) {
+      unwrapped = value.arguments.positional.first;
+    }
+    return new VariableSet(v, unwrapped);
+  }
+
   // Name an expression by emitting an assignment to a temporary variable.
-  VariableGet name(Expression expr) {
+  Expression name(Expression expr) {
     VariableDeclaration temp = allocateTemporary(nameIndex);
-    statements.add(new ExpressionStatement(new VariableSet(temp, expr)));
-    return new VariableGet(temp);
+    statements.add(new ExpressionStatement(storeTemporary(temp, expr)));
+    return assignType(new VariableGet(temp), expr);
   }
 
   VariableDeclaration allocateTemporary(int index) {
@@ -153,11 +178,12 @@
   // Getting a final or const variable is not an effect so it can be evaluated
   // after an await to its right.
   TreeNode visitVariableGet(VariableGet expr) {
+    Expression result = expr;
     if (seenAwait && !expr.variable.isFinal && !expr.variable.isConst) {
-      expr = name(expr);
+      result = name(expr);
       ++nameIndex;
     }
-    return expr;
+    return result;
   }
 
   // Transform an expression given an action to transform the children.  For
@@ -394,9 +420,9 @@
     var thenBody = blockOf(thenStatements);
     var otherwiseBody = blockOf(otherwiseStatements);
     thenBody.addStatement(
-        new ExpressionStatement(new VariableSet(result, expr.then)));
+        new ExpressionStatement(storeTemporary(result, expr.then)));
     otherwiseBody.addStatement(
-        new ExpressionStatement(new VariableSet(result, expr.otherwise)));
+        new ExpressionStatement(storeTemporary(result, expr.otherwise)));
     var branch = new IfStatement(expr.condition, thenBody, otherwiseBody);
     statements.add(branch);
 
@@ -405,14 +431,14 @@
 
     ++nameIndex;
     seenAwait = seenAwait || thenAwait || otherwiseAwait;
-    return new VariableGet(result);
+    return assignType(new VariableGet(result), expr);
   }
 
   // Others.
   TreeNode visitAwaitExpression(AwaitExpression expr) {
     final R = continuationRewriter;
     var shouldName = seenAwait;
-    var result = new VariableGet(asyncResult);
+    var result = assignType(new VariableGet(asyncResult), expr);
 
     // The statements are in reverse order, so name the result first if
     // necessary and then add the two other statements in reverse.
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
index 723c78d..fd06825 100644
--- a/pkg/kernel/lib/transformations/continuation.dart
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -7,7 +7,9 @@
 import 'dart:math' as math;
 
 import '../ast.dart';
-import '../core_types.dart';
+import '../class_hierarchy.dart' show ClassHierarchy;
+import '../core_types.dart' show CoreTypes;
+import '../type_environment.dart' show TypeEnvironment;
 import '../visitor.dart';
 
 import 'async.dart';
@@ -23,25 +25,25 @@
   static String stackTraceVar(int depth) => ':stack_trace$depth';
 }
 
-void transformLibraries(
-    CoreTypes coreTypes, List<Library> libraries, bool syncAsync) {
-  var helper = new HelperNodes.fromCoreTypes(coreTypes);
+void transformLibraries(CoreTypes coreTypes, ClassHierarchy hierarchy,
+    List<Library> libraries, bool syncAsync) {
+  var helper = new HelperNodes.fromCoreTypes(coreTypes, hierarchy);
   var rewriter = new RecursiveContinuationRewriter(helper, syncAsync);
   for (var library in libraries) {
     rewriter.rewriteLibrary(library);
   }
 }
 
-Component transformComponent(
-    CoreTypes coreTypes, Component component, bool syncAsync) {
-  var helper = new HelperNodes.fromCoreTypes(coreTypes);
+Component transformComponent(CoreTypes coreTypes, ClassHierarchy hierarchy,
+    Component component, bool syncAsync) {
+  var helper = new HelperNodes.fromCoreTypes(coreTypes, hierarchy);
   var rewriter = new RecursiveContinuationRewriter(helper, syncAsync);
   return rewriter.rewriteComponent(component);
 }
 
-Procedure transformProcedure(
-    CoreTypes coreTypes, Procedure procedure, bool syncAsync) {
-  var helper = new HelperNodes.fromCoreTypes(coreTypes);
+Procedure transformProcedure(CoreTypes coreTypes, ClassHierarchy hierarchy,
+    Procedure procedure, bool syncAsync) {
+  var helper = new HelperNodes.fromCoreTypes(coreTypes, hierarchy);
   var rewriter = new RecursiveContinuationRewriter(helper, syncAsync);
   return rewriter.visitProcedure(procedure);
 }
@@ -69,7 +71,23 @@
   }
 
   visitProcedure(Procedure node) {
-    return node.isAbstract ? node : super.visitProcedure(node);
+    try {
+      if (!node.isStatic) {
+        helper.env.thisType = node.enclosingClass?.thisType;
+      }
+      return node.isAbstract ? node : super.visitProcedure(node);
+    } finally {
+      helper.env.thisType = null;
+    }
+  }
+
+  visitConstructor(Constructor node) {
+    try {
+      helper.env.thisType = node.enclosingClass.thisType;
+      return super.visitConstructor(node);
+    } finally {
+      helper.env.thisType = null;
+    }
   }
 
   visitFunctionNode(FunctionNode node) {
@@ -1180,6 +1198,9 @@
   final Member syncIteratorYieldEachIterable;
   final Class boolClass;
   final Member boolFromEnvironment;
+  final Procedure unsafeCast;
+
+  final TypeEnvironment env;
 
   HelperNodes._(
       this.asyncErrorWrapper,
@@ -1223,9 +1244,12 @@
       this.syncIteratorCurrent,
       this.syncIteratorYieldEachIterable,
       this.boolClass,
-      this.boolFromEnvironment);
+      this.boolFromEnvironment,
+      this.unsafeCast,
+      this.env);
 
-  factory HelperNodes.fromCoreTypes(CoreTypes coreTypes) {
+  factory HelperNodes.fromCoreTypes(
+      CoreTypes coreTypes, ClassHierarchy hierarchy) {
     return new HelperNodes._(
         coreTypes.asyncErrorWrapperHelperProcedure,
         coreTypes.asyncLibrary,
@@ -1268,6 +1292,8 @@
         coreTypes.syncIteratorCurrent,
         coreTypes.syncIteratorYieldEachIterable,
         coreTypes.boolClass,
-        coreTypes.boolFromEnvironment);
+        coreTypes.boolFromEnvironment,
+        coreTypes.unsafeCast,
+        new TypeEnvironment(coreTypes, hierarchy, strongMode: true));
   }
 }
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index 0889b46..f67260e 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -66,7 +66,8 @@
     logger?.call("Transformed mixin applications");
 
     // TODO(kmillikin): Make this run on a per-method basis.
-    transformAsync.transformLibraries(coreTypes, libraries, flags.syncAsync);
+    transformAsync.transformLibraries(
+        coreTypes, hierarchy, libraries, flags.syncAsync);
     logger?.call("Transformed async methods");
 
     callSiteAnnotator.transformLibraries(
@@ -78,7 +79,8 @@
   void performTransformationsOnProcedure(
       CoreTypes coreTypes, ClassHierarchy hierarchy, Procedure procedure,
       {void logger(String msg)}) {
-    transformAsync.transformProcedure(coreTypes, procedure, flags.syncAsync);
+    transformAsync.transformProcedure(
+        coreTypes, hierarchy, procedure, flags.syncAsync);
     logger?.call("Transformed async functions");
   }
 
diff --git a/pkg/vm/testcases/bytecode/async.dart.expect b/pkg/vm/testcases/bytecode/async.dart.expect
index 361bdc4..4dbdd29 100644
--- a/pkg/vm/testcases/bytecode/async.dart.expect
+++ b/pkg/vm/testcases/bytecode/async.dart.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
+import "dart:_internal" as _in;
 
 [@vm.bytecode=
 Bytecode {
@@ -264,7 +265,7 @@
       #L1:
       {
         [yield] let dynamic #t1 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
-        :result;
+        _in::unsafeCast<core::int>(:result);
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
@@ -741,7 +742,7 @@
         [yield] let dynamic #t2 = asy::_awaitHelper(a, :async_op_then, :async_op_error, :async_op) in null;
         :async_temporary_0 = :result;
         [yield] let dynamic #t3 = asy::_awaitHelper(b, :async_op_then, :async_op_error, :async_op) in null;
-        :return_value = :async_temporary_0.{core::num::+}(:result);
+        :return_value = _in::unsafeCast<core::int>(:async_temporary_0).{core::num::+}(_in::unsafeCast<core::int>(:result));
         break #L3;
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -1171,7 +1172,7 @@
             :async_temporary_1 = sum;
             :async_temporary_0 = i.{core::num::+}(j);
             [yield] let dynamic #t4 = asy::_awaitHelper(self::foo(), :async_op_then, :async_op_error, :async_op) in null;
-            sum = :async_temporary_1.{core::num::+}(:async_temporary_0.{core::num::+}(:result));
+            sum = _in::unsafeCast<core::int>(:async_temporary_1).{core::num::+}(_in::unsafeCast<core::int>(:async_temporary_0).{core::num::+}(_in::unsafeCast<core::int>(:result)));
           }
         }
         for (core::int k = 0; k.{core::num::<}(10); k = k.{core::num::+}(1)) {
@@ -1829,7 +1830,7 @@
           try {
             :async_temporary_0 = x;
             [yield] let dynamic #t5 = asy::_awaitHelper(a, :async_op_then, :async_op_error, :async_op) in null;
-            x = :async_temporary_0.{core::num::+}(:result);
+            x = _in::unsafeCast<core::int>(:async_temporary_0).{core::num::+}(_in::unsafeCast<core::int>(:result));
           }
           on dynamic catch(final dynamic e) {
             if(e is core::Error) {
@@ -1838,14 +1839,14 @@
             }
             :async_temporary_0 = x;
             [yield] let dynamic #t6 = asy::_awaitHelper(b, :async_op_then, :async_op_error, :async_op) in null;
-            x = :async_temporary_0.{core::num::+}(:result);
+            x = _in::unsafeCast<core::int>(:async_temporary_0).{core::num::+}(_in::unsafeCast<core::int>(:result));
             rethrow;
           }
         finally {
           core::print("fin");
           :async_temporary_0 = x;
           [yield] let dynamic #t7 = asy::_awaitHelper(c, :async_op_then, :async_op_error, :async_op) in null;
-          x = :async_temporary_0.{core::num::+}(:result);
+          x = _in::unsafeCast<core::int>(:async_temporary_0).{core::num::+}(_in::unsafeCast<core::int>(:result));
           :return_value = x;
           break #L5;
         }
@@ -2233,7 +2234,7 @@
           try {
             x = 5;
             [yield] let dynamic #t8 = asy::_awaitHelper(a, :async_op_then, :async_op_error, :async_op) in null;
-            y = :result;
+            y = _in::unsafeCast<core::int>(:result);
             :return_value = x.{core::num::+}(y);
             break #L6;
           }
@@ -2502,7 +2503,7 @@
       {
         assert {
           [yield] let dynamic #t9 = asy::_awaitHelper(a, :async_op_then, :async_op_error, :async_op) in null;
-          assert(:result.{core::num::==}(42));
+          assert(_in::unsafeCast<core::int>(:result).{core::num::==}(42));
         }
         :return_value = 7;
         break #L7;
diff --git a/runtime/tests/vm/dart/async_transform_types_preservation_test.dart b/runtime/tests/vm/dart/async_transform_types_preservation_test.dart
new file mode 100644
index 0000000..c0a774c
--- /dev/null
+++ b/runtime/tests/vm/dart/async_transform_types_preservation_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2018, 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.
+
+// Verify that async transformer produces correct Kernel ASTs and does
+// not cause crashes in subsequent transformations.
+
+import 'dart:async';
+
+import 'package:expect/expect.dart';
+
+bool global = false;
+
+class Foo<T> {
+  final T Function(int) wrap;
+  final int Function(T) unwrap;
+
+  Foo(this.wrap, this.unwrap);
+
+  FutureOr<List<T>> get f => [wrap(21), wrap(20), wrap(1)];
+  FutureOr<List<T>> get g => [wrap(-21), wrap(20), wrap(1)];
+
+  Future<int> get one async =>
+      (global ? await f : await g).map(unwrap).reduce((int a, int b) => a + b);
+
+  Future<int> get two async =>
+      (await f).map(unwrap).reduce((int a, int b) => a + b);
+}
+
+class Bar {
+  final int value;
+  Bar(this.value);
+}
+
+void main() async {
+  final wrap = (int v) => new Bar(v);
+  final unwrap = (Bar b) => b.value;
+
+  Expect.equals(0, await new Foo<Bar>(wrap, unwrap).one);
+  Expect.equals(42, await new Foo<Bar>(wrap, unwrap).two);
+}