Chromium Code Reviews| Index: runtime/vm/parser.cc |
| diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc |
| index 6a89bd0eeffadb3e15b2cae7b8bfbf4ff4aeb173..8e732b3fac21744a67c68d56a851a6ab5caa54e0 100644 |
| --- a/runtime/vm/parser.cc |
| +++ b/runtime/vm/parser.cc |
| @@ -6821,6 +6821,13 @@ RawFunction* Parser::OpenAsyncFunction(TokenPosition async_func_pos) { |
| OpenFunctionBlock(closure); |
| AddFormalParamsToScope(&closure_params, current_block_->scope); |
| async_temp_scope_ = current_block_->scope; |
| + |
| + // Capture instantiator in case it is needed to generate the type |
|
regis
2016/06/13 22:38:23
.. in case it may be needed ...
Since we now alway
|
| + // check of the return value. (C.f. handling of Token::kRETURN.) |
| + ASSERT(FunctionLevel() > 0); |
| + if (I->type_checks() && IsInstantiatorRequired()) { |
| + CaptureInstantiator(); |
| + } |
| return closure.raw(); |
| } |
| @@ -10145,17 +10152,14 @@ AstNode* Parser::ParseStatement() { |
| } |
| AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| if (I->type_checks() && |
| - (((function_level == 0) && current_function().IsAsyncClosure()) || |
| - ((function_level > 0) && current_function().IsAsyncFunction()))) { |
| + (((function_level == 0) && current_function().IsAsyncClosure()))) { |
| // 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. |
| - Function& async_func = Function::Handle(Z, current_function().raw()); |
| - if (function_level == 0) { |
| - async_func = async_func.parent_function(); |
| - } |
| + Function& async_func = |
| + Function::Handle(Z, current_function().parent_function()); |
| const AbstractType& result_type = |
| AbstractType::ZoneHandle(Z, async_func.result_type()); |
| const Class& future_class = |
| @@ -10167,41 +10171,32 @@ 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)); |
| - 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(); |
| - } |
| - } |
| + 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; |
| } |
| } |
| } |