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

Side by Side Diff: runtime/vm/parser.cc

Issue 1847953002: Report wrong async function result type as type error in checked mode (Fixes #26133). (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: different approach Created 4 years, 7 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 unified diff | Download patch
« no previous file with comments | « runtime/vm/ast.h ('k') | tests/language/async_return_types_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/parser.h" 5 #include "vm/parser.h"
6 #include "vm/flags.h" 6 #include "vm/flags.h"
7 7
8 #ifndef DART_PRECOMPILED_RUNTIME 8 #ifndef DART_PRECOMPILED_RUNTIME
9 9
10 #include "lib/invocation_mirror.h" 10 #include "lib/invocation_mirror.h"
(...skipping 10010 matching lines...) Expand 10 before | Expand all | Expand 10 after
10021 const TokenPosition expr_pos = TokenPos(); 10021 const TokenPosition expr_pos = TokenPos();
10022 if (current_function().IsGenerativeConstructor() && 10022 if (current_function().IsGenerativeConstructor() &&
10023 (current_block_->scope->function_level() == 0)) { 10023 (current_block_->scope->function_level() == 0)) {
10024 ReportError(expr_pos, 10024 ReportError(expr_pos,
10025 "return of a value is not allowed in constructors"); 10025 "return of a value is not allowed in constructors");
10026 } else if (current_function().IsGeneratorClosure() && 10026 } else if (current_function().IsGeneratorClosure() &&
10027 (current_block_->scope->function_level() == 0)) { 10027 (current_block_->scope->function_level() == 0)) {
10028 ReportError(expr_pos, "generator functions may not return a value"); 10028 ReportError(expr_pos, "generator functions may not return a value");
10029 } 10029 }
10030 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); 10030 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
10031 if (I->type_checks() &&
10032 current_function().IsAsyncClosure() &&
10033 (current_block_->scope->function_level() == 0)) {
10034 // In checked mode, when the declared result type is Future<T>, verify
10035 // that the returned expression is of type T or Future<T> as follows:
10036 // return temp = expr, temp is Future ? temp as Future<T> : temp as T;
10037 // In case of a mismatch, we need a TypeError and not a CastError, so
10038 // we do not actually implement an "as" test, but an "assignable" test.
10039 const Function& async_func =
10040 Function::Handle(Z, current_function().parent_function());
10041 const AbstractType& result_type =
10042 AbstractType::ZoneHandle(Z, async_func.result_type());
10043 const Class& future_class =
10044 Class::ZoneHandle(Z, I->object_store()->future_class());
10045 ASSERT(!future_class.IsNull());
10046 if (result_type.type_class() == future_class.raw()) {
10047 const TypeArguments& result_type_args =
10048 TypeArguments::ZoneHandle(Z, result_type.arguments());
10049 if (!result_type_args.IsNull() && (result_type_args.Length() == 1)) {
10050 const AbstractType& result_type_arg =
10051 AbstractType::ZoneHandle(Z, result_type_args.TypeAt(0));
10052 LetNode* checked_expr = new(Z) LetNode(statement_pos);
hausner 2016/05/09 21:42:34 Should this point to the expression being returned
regis 2016/05/09 21:58:22 Good point! I replaced all occurrences of statemen
10053 LocalVariable* temp = checked_expr->AddInitializer(expr);
10054 temp->set_is_final();
10055 const AbstractType& future_type =
10056 AbstractType::ZoneHandle(Z, future_class.RareType());
10057 AstNode* is_future = new(Z) LoadLocalNode(statement_pos, temp);
10058 is_future = new(Z) ComparisonNode(statement_pos,
10059 Token::kIS,
10060 is_future,
10061 new(Z) TypeNode(statement_pos,
10062 future_type));
10063 AstNode* as_future_t = new(Z) LoadLocalNode(statement_pos, temp);
10064 as_future_t = new(Z) AssignableNode(statement_pos,
10065 as_future_t,
10066 result_type,
10067 Symbols::FunctionResult());
10068 AstNode* as_t = new(Z) LoadLocalNode(statement_pos, temp);
10069 as_t = new(Z) AssignableNode(statement_pos,
10070 as_t,
10071 result_type_arg,
10072 Symbols::FunctionResult());
10073 checked_expr->AddNode(new(Z) ConditionalExprNode(statement_pos,
10074 is_future,
10075 as_future_t,
10076 as_t));
10077 expr = checked_expr;
10078 }
10079 }
10080 }
10031 statement = new(Z) ReturnNode(statement_pos, expr); 10081 statement = new(Z) ReturnNode(statement_pos, expr);
10032 } else { 10082 } else {
10033 if (current_function().IsSyncGenClosure() && 10083 if (current_function().IsSyncGenClosure() &&
10034 (current_block_->scope->function_level() == 0)) { 10084 (current_block_->scope->function_level() == 0)) {
10035 // In a synchronous generator, return without an expression 10085 // In a synchronous generator, return without an expression
10036 // returns false, signaling that the iterator terminates and 10086 // returns false, signaling that the iterator terminates and
10037 // did not yield a value. 10087 // did not yield a value.
10038 statement = new(Z) ReturnNode(statement_pos, 10088 statement = new(Z) ReturnNode(statement_pos,
10039 new(Z) LiteralNode(return_pos, Bool::False())); 10089 new(Z) LiteralNode(return_pos, Bool::False()));
10040 } else { 10090 } else {
(...skipping 4444 matching lines...) Expand 10 before | Expand all | Expand 10 after
14485 const ArgumentListNode& function_args, 14535 const ArgumentListNode& function_args,
14486 const LocalVariable* temp_for_last_arg, 14536 const LocalVariable* temp_for_last_arg,
14487 bool is_super_invocation) { 14537 bool is_super_invocation) {
14488 UNREACHABLE(); 14538 UNREACHABLE();
14489 return NULL; 14539 return NULL;
14490 } 14540 }
14491 14541
14492 } // namespace dart 14542 } // namespace dart
14493 14543
14494 #endif // DART_PRECOMPILED_RUNTIME 14544 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« no previous file with comments | « runtime/vm/ast.h ('k') | tests/language/async_return_types_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698