Skip to content

Commit eec96f9

Browse files
mralephcommit-bot@chromium.org
authored andcommitted
[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: #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>
1 parent bf4facd commit eec96f9

File tree

53 files changed

+316
-166
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+316
-166
lines changed

pkg/front_end/testcases/async_function.dart.direct.transformed.expect

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ library;
22
import self as self;
33
import "dart:async" as asy;
44
import "dart:core" as core;
5+
import "dart:_internal" as _in;
56

67
static field core::List<core::String> stringList = <dynamic>["bar"];
78
static method asyncString() → asy::Future<core::String> /* originally async */ {
@@ -118,7 +119,7 @@ static method asyncStarString() → asy::Stream<core::String> /* originally asyn
118119
else
119120
[yield] null;
120121
[yield] let dynamic #t1 = asy::_awaitHelper(self::asyncString(), :async_op_then, :async_op_error, :async_op) in null;
121-
if(:controller.{asy::_AsyncStarStreamController::add}(:result))
122+
if(:controller.{asy::_AsyncStarStreamController::add}(_in::unsafeCast<core::String>(:result)))
122123
return null;
123124
else
124125
[yield] null;
@@ -187,7 +188,7 @@ static method main() → dynamic /* originally async */ {
187188
#L5:
188189
{
189190
[yield] let dynamic #t2 = asy::_awaitHelper(self::asyncString(), :async_op_then, :async_op_error, :async_op) in null;
190-
core::String str = :result;
191+
core::String str = _in::unsafeCast<core::String>(:result);
191192
}
192193
asy::_completeOnAsyncReturn(:async_completer, :return_value);
193194
return;

pkg/front_end/testcases/async_nested.dart.direct.transformed.expect

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ library;
22
import self as self;
33
import "dart:core" as core;
44
import "dart:async" as asy;
5+
import "dart:_internal" as _in;
56

67
class Node extends core::Object {
78
final field core::List<self::Node> nested;
@@ -43,7 +44,7 @@ static method main() → void /* originally async */ {
4344
[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;
4445
:async_temporary_0 = :result;
4546
[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;
46-
self::Node node = new self::Node::•("1", <dynamic>[:async_temporary_2, :async_temporary_0, :result]);
47+
self::Node node = new self::Node::•("1", <dynamic>[_in::unsafeCast<self::Node>(:async_temporary_2), :async_temporary_0, :result]);
4748
core::String actual = node.toSimpleString();
4849
core::print(actual);
4950
if(!actual.==(expected)) {

pkg/front_end/testcases/async_nested.dart.strong.transformed.expect

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ library;
22
import self as self;
33
import "dart:core" as core;
44
import "dart:async" as asy;
5+
import "dart:_internal" as _in;
56

67
class Node extends core::Object {
78
final field core::List<self::Node> nested;
@@ -34,16 +35,16 @@ static method main() → void /* originally async */ {
3435
core::String expected = "1 2 3 4 5 6 7 8 9 10";
3536
:async_temporary_2 = new self::Node::•("2", <self::Node>[]);
3637
[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;
37-
[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;
38+
[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;
3839
:async_temporary_1 = :result;
3940
[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;
4041
:async_temporary_0 = :result;
4142
[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;
42-
[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;
43-
[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;
43+
[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;
44+
[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;
4445
:async_temporary_0 = :result;
4546
[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;
46-
self::Node node = new self::Node::•("1", <self::Node>[:async_temporary_2, :async_temporary_0, :result]);
47+
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)]);
4748
core::String actual = node.{self::Node::toSimpleString}() as{TypeError} core::String;
4849
core::print(actual);
4950
if(!actual.{core::String::==}(expected)) {

pkg/front_end/testcases/await.dart.direct.transformed.expect

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ library;
22
import self as self;
33
import "dart:async" as asy;
44
import "dart:core" as core;
5+
import "dart:_internal" as _in;
56

67
static method main() → dynamic /* originally async */ {
78
final asy::Completer<dynamic> :async_completer = asy::Completer::sync<dynamic>();
@@ -17,7 +18,7 @@ static method main() → dynamic /* originally async */ {
1718
#L1:
1819
{
1920
[yield] let dynamic #t1 = asy::_awaitHelper("Hello, World!", :async_op_then, :async_op_error, :async_op) in null;
20-
core::print(:result);
21+
core::print(_in::unsafeCast<core::String>(:result));
2122
}
2223
asy::_completeOnAsyncReturn(:async_completer, :return_value);
2324
return;

pkg/front_end/testcases/bug33206.dart.direct.transformed.expect

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ library;
22
import self as self;
33
import "dart:core" as core;
44
import "dart:async" as asy;
5+
import "dart:_internal" as _in;
56

67
class X extends core::Object {
78
final field dynamic x;
@@ -89,10 +90,10 @@ static method foo() → asy::Future<self::X> /* originally async */ {
8990
{
9091
final dynamic #t1 = new self::Y::•();
9192
[yield] let dynamic #t2 = asy::_awaitHelper(self::f1(), :async_op_then, :async_op_error, :async_op) in null;
92-
final dynamic #t3 = #t1.f(:result);
93+
final dynamic #t3 = #t1.f(_in::unsafeCast<core::List<core::Object>>(:result));
9394
final dynamic #t4 = #t1.f(self::f2());
9495
[yield] let dynamic #t5 = asy::_awaitHelper(self::f3(), :async_op_then, :async_op_error, :async_op) in null;
95-
:return_value = new self::X::•(#t1, :result);
96+
:return_value = new self::X::•(#t1, _in::unsafeCast<core::Object>(:result));
9697
break #L3;
9798
}
9899
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -121,7 +122,7 @@ static method main() → asy::Future<void> /* originally async */ {
121122
#L4:
122123
{
123124
[yield] let dynamic #t6 = asy::_awaitHelper(self::foo(), :async_op_then, :async_op_error, :async_op) in null;
124-
core::print(:result);
125+
core::print(_in::unsafeCast<self::X>(:result));
125126
}
126127
asy::_completeOnAsyncReturn(:async_completer, :return_value);
127128
return;

pkg/front_end/testcases/bug33206.dart.strong.transformed.expect

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ library;
22
import self as self;
33
import "dart:core" as core;
44
import "dart:async" as asy;
5+
import "dart:_internal" as _in;
56

67
class X extends core::Object {
78
final field dynamic x;
@@ -89,10 +90,10 @@ static method foo() → asy::Future<self::X> /* originally async */ {
8990
{
9091
final self::Y #t1 = new self::Y::•();
9192
[yield] let dynamic #t2 = asy::_awaitHelper(self::f1(), :async_op_then, :async_op_error, :async_op) in null;
92-
final dynamic #t3 = #t1.{self::Y::f}(:result);
93+
final dynamic #t3 = #t1.{self::Y::f}(_in::unsafeCast<core::List<core::Object>>(:result));
9394
final dynamic #t4 = #t1.{self::Y::f}(self::f2());
9495
[yield] let dynamic #t5 = asy::_awaitHelper(self::f3(), :async_op_then, :async_op_error, :async_op) in null;
95-
:return_value = new self::X::•(#t1, :result);
96+
:return_value = new self::X::•(#t1, _in::unsafeCast<core::Object>(:result));
9697
break #L3;
9798
}
9899
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -121,7 +122,7 @@ static method main() → asy::Future<void> /* originally async */ {
121122
#L4:
122123
{
123124
[yield] let dynamic #t6 = asy::_awaitHelper(self::foo(), :async_op_then, :async_op_error, :async_op) in null;
124-
core::print(:result);
125+
core::print(_in::unsafeCast<self::X>(:result));
125126
}
126127
asy::_completeOnAsyncReturn(:async_completer, :return_value);
127128
return;

pkg/front_end/testcases/inference/async_await.dart.direct.transformed.expect

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ library test;
22
import self as self;
33
import "dart:core" as core;
44
import "dart:async" as asy;
5+
import "dart:_internal" as _in;
56

67
abstract class MyFuture extends core::Object implements asy::Future<core::int> {
78
synthetic constructor •() → void
@@ -302,25 +303,25 @@ static method test() → void /* originally async */ {
302303
return :async_completer.{asy::Completer::future};
303304
}
304305
[yield] let dynamic #t1 = asy::_awaitHelper(x0, :async_op_then, :async_op_error, :async_op) in null;
305-
dynamic y0 = :result;
306+
dynamic y0 = _in::unsafeCast<core::int>(:result);
306307
[yield] let dynamic #t2 = asy::_awaitHelper(x1, :async_op_then, :async_op_error, :async_op) in null;
307-
dynamic y1 = :result;
308+
dynamic y1 = _in::unsafeCast<core::int>(:result);
308309
[yield] let dynamic #t3 = asy::_awaitHelper(x2, :async_op_then, :async_op_error, :async_op) in null;
309-
dynamic y2 = :result;
310+
dynamic y2 = _in::unsafeCast<asy::Future<core::int>>(:result);
310311
[yield] let dynamic #t4 = asy::_awaitHelper(x3, :async_op_then, :async_op_error, :async_op) in null;
311-
dynamic y3 = :result;
312+
dynamic y3 = _in::unsafeCast<asy::FutureOr<core::int>>(:result);
312313
[yield] let dynamic #t5 = asy::_awaitHelper(x4, :async_op_then, :async_op_error, :async_op) in null;
313-
dynamic y4 = :result;
314+
dynamic y4 = _in::unsafeCast<self::MyFuture>(:result);
314315
[yield] let dynamic #t6 = asy::_awaitHelper(x5, :async_op_then, :async_op_error, :async_op) in null;
315-
dynamic y5 = :result;
316+
dynamic y5 = _in::unsafeCast<core::int>(:result);
316317
[yield] let dynamic #t7 = asy::_awaitHelper(x6, :async_op_then, :async_op_error, :async_op) in null;
317-
dynamic y6 = :result;
318+
dynamic y6 = _in::unsafeCast<asy::Future<core::int>>(:result);
318319
[yield] let dynamic #t8 = asy::_awaitHelper(x7, :async_op_then, :async_op_error, :async_op) in null;
319-
dynamic y7 = :result;
320+
dynamic y7 = _in::unsafeCast<asy::FutureOr<core::int>>(:result);
320321
[yield] let dynamic #t9 = asy::_awaitHelper(x8, :async_op_then, :async_op_error, :async_op) in null;
321-
dynamic y8 = :result;
322+
dynamic y8 = _in::unsafeCast<self::MyFuture>(:result);
322323
[yield] let dynamic #t10 = asy::_awaitHelper(x9, :async_op_then, :async_op_error, :async_op) in null;
323-
dynamic y9 = :result;
324+
dynamic y9 = _in::unsafeCast<core::int>(:result);
324325
}
325326
asy::_completeOnAsyncReturn(:async_completer, :return_value);
326327
return;

pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ library test;
22
import self as self;
33
import "dart:core" as core;
44
import "dart:async" as asy;
5+
import "dart:_internal" as _in;
56

67
abstract class MyFuture extends core::Object implements asy::Future<core::int> {
78
synthetic constructor •() → void
@@ -302,25 +303,25 @@ static method test() → void /* originally async */ {
302303
return :async_completer.{asy::Completer::future};
303304
}
304305
[yield] let dynamic #t1 = asy::_awaitHelper(x0, :async_op_then, :async_op_error, :async_op) in null;
305-
core::int y0 = :result;
306+
core::int y0 = _in::unsafeCast<core::int>(:result);
306307
[yield] let dynamic #t2 = asy::_awaitHelper(x1, :async_op_then, :async_op_error, :async_op) in null;
307-
core::int y1 = :result;
308+
core::int y1 = _in::unsafeCast<core::int>(:result);
308309
[yield] let dynamic #t3 = asy::_awaitHelper(x2, :async_op_then, :async_op_error, :async_op) in null;
309-
asy::Future<core::int> y2 = :result;
310+
asy::Future<core::int> y2 = _in::unsafeCast<asy::Future<core::int>>(:result);
310311
[yield] let dynamic #t4 = asy::_awaitHelper(x3, :async_op_then, :async_op_error, :async_op) in null;
311-
asy::FutureOr<core::int> y3 = :result;
312+
asy::FutureOr<core::int> y3 = _in::unsafeCast<asy::FutureOr<core::int>>(:result);
312313
[yield] let dynamic #t5 = asy::_awaitHelper(x4, :async_op_then, :async_op_error, :async_op) in null;
313-
self::MyFuture y4 = :result;
314+
self::MyFuture y4 = _in::unsafeCast<self::MyFuture>(:result);
314315
[yield] let dynamic #t6 = asy::_awaitHelper(x5, :async_op_then, :async_op_error, :async_op) in null;
315-
core::int y5 = :result;
316+
core::int y5 = _in::unsafeCast<core::int>(:result);
316317
[yield] let dynamic #t7 = asy::_awaitHelper(x6, :async_op_then, :async_op_error, :async_op) in null;
317-
asy::Future<core::int> y6 = :result;
318+
asy::Future<core::int> y6 = _in::unsafeCast<asy::Future<core::int>>(:result);
318319
[yield] let dynamic #t8 = asy::_awaitHelper(x7, :async_op_then, :async_op_error, :async_op) in null;
319-
asy::FutureOr<core::int> y7 = :result;
320+
asy::FutureOr<core::int> y7 = _in::unsafeCast<asy::FutureOr<core::int>>(:result);
320321
[yield] let dynamic #t9 = asy::_awaitHelper(x8, :async_op_then, :async_op_error, :async_op) in null;
321-
self::MyFuture y8 = :result;
322+
self::MyFuture y8 = _in::unsafeCast<self::MyFuture>(:result);
322323
[yield] let dynamic #t10 = asy::_awaitHelper(x9, :async_op_then, :async_op_error, :async_op) in null;
323-
core::int y9 = :result;
324+
core::int y9 = _in::unsafeCast<core::int>(:result);
324325
}
325326
asy::_completeOnAsyncReturn(:async_completer, :return_value);
326327
return;

pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ library test;
22
import self as self;
33
import "dart:async" as asy;
44
import "dart:core" as core;
5+
import "dart:_internal" as _in;
56

67
static method main() → dynamic /* originally async */ {
78
final asy::Completer<dynamic> :async_completer = asy::Completer::sync<dynamic>();
@@ -46,7 +47,7 @@ static method main() → dynamic /* originally async */ {
4647
asy::Future<dynamic> y = f.call();
4748
asy::Future<core::String> z = f.call();
4849
[yield] let dynamic #t1 = asy::_awaitHelper(f.call(), :async_op_then, :async_op_error, :async_op) in null;
49-
core::String s = :result;
50+
core::String s = _in::unsafeCast<core::Null>(:result);
5051
}
5152
asy::_completeOnAsyncReturn(:async_completer, :return_value);
5253
return;

pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ library test;
22
import self as self;
33
import "dart:async" as asy;
44
import "dart:core" as core;
5+
import "dart:_internal" as _in;
56

67
static method main() → dynamic /* originally async */ {
78
final asy::Completer<dynamic> :async_completer = asy::Completer::sync<dynamic>();
@@ -54,7 +55,7 @@ static method main() → dynamic /* originally async */ {
5455
asy::Stream<dynamic> y = f.call();
5556
asy::Stream<core::String> z = f.call();
5657
[yield] let dynamic #t1 = asy::_awaitHelper(f.call().{asy::Stream::first}, :async_op_then, :async_op_error, :async_op) in null;
57-
core::String s = :result;
58+
core::String s = _in::unsafeCast<core::Null>(:result);
5859
}
5960
asy::_completeOnAsyncReturn(:async_completer, :return_value);
6061
return;

0 commit comments

Comments
 (0)