Index: runtime/vm/parser.cc |
=================================================================== |
--- runtime/vm/parser.cc (revision 29086) |
+++ runtime/vm/parser.cc (working copy) |
@@ -6024,10 +6024,11 @@ |
// or any other class that does not override the == operator. |
// The expressions are compile-time constants and are thus in the form |
// of a LiteralNode. |
-void Parser::CheckCaseExpressions(const GrowableArray<LiteralNode*>& values) { |
+RawClass* Parser::CheckCaseExpressions( |
+ const GrowableArray<LiteralNode*>& values) { |
const intptr_t num_expressions = values.length(); |
if (num_expressions == 0) { |
- return; |
+ return Object::dynamic_class(); |
} |
const Instance& first_value = values[0]->literal(); |
for (intptr_t i = 0; i < num_expressions; i++) { |
@@ -6062,6 +6063,12 @@ |
} |
} |
} |
+ if (first_value.IsInteger()) { |
+ return Type::Handle(Type::IntType()).type_class(); |
+ } else if (first_value.IsString()) { |
+ return Type::Handle(Type::StringType()).type_class(); |
+ } |
+ return first_value.clazz(); |
} |
@@ -6160,11 +6167,18 @@ |
OpenBlock(); |
current_block_->scope->AddLabel(label); |
- // Store switch expression in temporary local variable. |
+ // Store switch expression in temporary local variable. The type of the |
+ // variable is set to dynamic. It will later be patched to match the |
+ // type of the case clause expressions. Therefore, we have to allocate |
+ // a new type representing dynamic and can't reuse the canonical |
+ // type object for dynamic. |
+ const Type& temp_var_type = |
+ Type::ZoneHandle(Type::New(Class::Handle(Object::dynamic_class()), |
+ TypeArguments::Handle(), |
+ expr_pos)); |
+ temp_var_type.SetIsFinalized(); |
LocalVariable* temp_variable = |
- new LocalVariable(expr_pos, |
- Symbols::SwitchExpr(), |
- Type::ZoneHandle(Type::DynamicType())); |
+ new LocalVariable(expr_pos, Symbols::SwitchExpr(), temp_var_type); |
current_block_->scope->AddVariable(temp_variable); |
AstNode* save_switch_expr = |
new StoreLocalNode(expr_pos, temp_variable, switch_expr); |
@@ -6217,8 +6231,11 @@ |
} |
// Check that all expressions in case clauses are of the same class, |
- // or implement int, double or String. |
- CheckCaseExpressions(case_expr_values); |
+ // or implement int, double or String. Patch the type of the temporary |
+ // variable holding the switch expression to match the type of the |
+ // case clause constants. |
+ temp_var_type.set_type_class( |
+ Class::Handle(CheckCaseExpressions(case_expr_values))); |
// Check for unresolved label references. |
SourceLabel* unresolved_label = |