Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1053)

Unified Diff: runtime/vm/parser.cc

Issue 2057903003: Capture instantiator in async function when required to check result type. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/language/regress_26668_test.dart » ('j') | tests/language/regress_26668_test.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 6b4aa4e506659530ba4fd185da49dec49bd357a1..6a89bd0eeffadb3e15b2cae7b8bfbf4ff4aeb173 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -10134,24 +10134,28 @@ AstNode* Parser::ParseStatement() {
ConsumeToken();
if (CurrentToken() != Token::kSEMICOLON) {
const TokenPosition expr_pos = TokenPos();
+ const int function_level = FunctionLevel();
if (current_function().IsGenerativeConstructor() &&
- (FunctionLevel() == 0)) {
+ (function_level == 0)) {
ReportError(expr_pos,
"return of a value is not allowed in constructors");
} else if (current_function().IsGeneratorClosure() &&
- (FunctionLevel() == 0)) {
+ (function_level == 0)) {
ReportError(expr_pos, "generator functions may not return a value");
}
AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
if (I->type_checks() &&
- current_function().IsAsyncClosure() && (FunctionLevel() == 0)) {
+ (((function_level == 0) && current_function().IsAsyncClosure()) ||
+ ((function_level > 0) && current_function().IsAsyncFunction()))) {
// In checked mode, when the declared result type is Future<T>, verify
// that the returned expression is of type T or Future<T> as follows:
// return temp = expr, temp is Future ? temp as Future<T> : temp as T;
// In case of a mismatch, we need a TypeError and not a CastError, so
// we do not actually implement an "as" test, but an "assignable" test.
- const Function& async_func =
- Function::Handle(Z, current_function().parent_function());
+ Function& async_func = Function::Handle(Z, current_function().raw());
+ if (function_level == 0) {
+ async_func = async_func.parent_function();
+ }
const AbstractType& result_type =
AbstractType::ZoneHandle(Z, async_func.result_type());
const Class& future_class =
@@ -10163,32 +10167,41 @@ AstNode* Parser::ParseStatement() {
if (!result_type_args.IsNull() && (result_type_args.Length() == 1)) {
const AbstractType& result_type_arg =
AbstractType::ZoneHandle(Z, result_type_args.TypeAt(0));
- LetNode* checked_expr = new(Z) LetNode(expr_pos);
- LocalVariable* temp = checked_expr->AddInitializer(expr);
- temp->set_is_final();
- const AbstractType& future_type =
- AbstractType::ZoneHandle(Z, future_class.RareType());
- AstNode* is_future = new(Z) LoadLocalNode(expr_pos, temp);
- is_future = new(Z) ComparisonNode(expr_pos,
- Token::kIS,
- is_future,
- new(Z) TypeNode(expr_pos,
- future_type));
- AstNode* as_future_t = new(Z) LoadLocalNode(expr_pos, temp);
- as_future_t = new(Z) AssignableNode(expr_pos,
- as_future_t,
- result_type,
- Symbols::FunctionResult());
- AstNode* as_t = new(Z) LoadLocalNode(expr_pos, temp);
- as_t = new(Z) AssignableNode(expr_pos,
- as_t,
- result_type_arg,
- Symbols::FunctionResult());
- checked_expr->AddNode(new(Z) ConditionalExprNode(expr_pos,
- is_future,
- as_future_t,
- as_t));
- expr = checked_expr;
+ if (function_level == 0) {
+ // Parsing and generating code for async closure.
+ LetNode* checked_expr = new(Z) LetNode(expr_pos);
+ LocalVariable* temp = checked_expr->AddInitializer(expr);
+ temp->set_is_final();
+ const AbstractType& future_type =
+ AbstractType::ZoneHandle(Z, future_class.RareType());
+ AstNode* is_future = new(Z) LoadLocalNode(expr_pos, temp);
+ is_future = new(Z) ComparisonNode(expr_pos,
+ Token::kIS,
+ is_future,
+ new(Z) TypeNode(expr_pos,
+ future_type));
+ AstNode* as_future_t = new(Z) LoadLocalNode(expr_pos, temp);
+ as_future_t = new(Z) AssignableNode(expr_pos,
+ as_future_t,
+ result_type,
+ Symbols::FunctionResult());
+ AstNode* as_t = new(Z) LoadLocalNode(expr_pos, temp);
+ as_t = new(Z) AssignableNode(expr_pos,
+ as_t,
+ result_type_arg,
+ Symbols::FunctionResult());
+ checked_expr->AddNode(new(Z) ConditionalExprNode(expr_pos,
+ is_future,
+ as_future_t,
+ as_t));
+ expr = checked_expr;
+ } else {
+ // Parsing async function, but not generating async closure code.
+ if (!result_type_arg.IsInstantiated()) {
+ // Make sure that the instantiator is captured.
+ CaptureInstantiator();
+ }
+ }
}
}
}
« no previous file with comments | « no previous file | tests/language/regress_26668_test.dart » ('j') | tests/language/regress_26668_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698