[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);
+}