Index: runtime/vm/parser.cc |
=================================================================== |
--- runtime/vm/parser.cc (revision 29604) |
+++ runtime/vm/parser.cc (working copy) |
@@ -3748,12 +3748,12 @@ |
ConsumeToken(); // extends or = |
const intptr_t type_pos = TokenPos(); |
super_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
- if (super_type.IsDynamicType()) { |
- // The string 'dynamic' is not resolved yet at this point, but a malformed |
- // type mapped to dynamic can be encountered here. |
+ if (super_type.IsMalformed() || super_type.IsDynamicType()) { |
+ // Unlikely here, since super type is not resolved yet. |
ErrorMsg(type_pos, |
- "class '%s' may not extend a malformed type", |
- class_name.ToCString()); |
+ "class '%s' may not extend %s", |
+ class_name.ToCString(), |
+ super_type.IsMalformed() ? "a malformed type" : "'dynamic'"); |
} |
if (super_type.IsTypeParameter()) { |
ErrorMsg(type_pos, |
@@ -3761,6 +3761,7 @@ |
class_name.ToCString(), |
String::Handle(super_type.UserVisibleName()).ToCString()); |
} |
+ // The class finalizer will check whether the super type is malbounded. |
if (CurrentToken() == Token::kWITH) { |
super_type = ParseMixins(super_type); |
} |
@@ -7430,12 +7431,11 @@ |
CaptureInstantiator(); |
} |
right_operand = new TypeNode(type_pos, type); |
- // The type is never malformed (mapped to dynamic), but it can be |
- // malbounded in checked mode. |
- ASSERT(!type.IsMalformed()); |
+ // In production mode, the type may be malformed. |
+ // In checked mode, the type may be malformed or malbounded. |
if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT) || |
(op_kind == Token::kAS)) && |
- type.IsMalbounded()) { |
+ (type.IsMalformed() || type.IsMalbounded())) { |
// Note that a type error is thrown even if the tested value is null |
// in a type test or in a type cast. |
return ThrowTypeError(type_pos, type); |
@@ -9193,6 +9193,13 @@ |
// List literals take a single type argument. |
if (list_type_arguments.Length() == 1) { |
element_type = list_type_arguments.TypeAt(0); |
+ ASSERT(!element_type.IsMalformed()); // Would be mapped to dynamic. |
+ ASSERT(!element_type.IsMalbounded()); // No declared bound in List. |
+ if (is_const && !element_type.IsInstantiated()) { |
+ ErrorMsg(type_pos, |
+ "the type argument of a constant list literal cannot include " |
+ "a type variable"); |
+ } |
} else { |
if (FLAG_error_on_bad_type) { |
ErrorMsg(type_pos, |
@@ -9202,14 +9209,8 @@ |
// Ignore type arguments. |
list_type_arguments = AbstractTypeArguments::null(); |
} |
- if (is_const && !element_type.IsInstantiated()) { |
- ErrorMsg(type_pos, |
- "the type argument of a constant list literal cannot include " |
- "a type variable"); |
- } |
} |
- ASSERT((list_type_arguments.IsNull() && element_type.IsDynamicType()) || |
- ((list_type_arguments.Length() == 1) && !element_type.IsNull())); |
+ ASSERT(list_type_arguments.IsNull() || (list_type_arguments.Length() == 1)); |
const Class& array_class = Class::Handle( |
isolate()->object_store()->array_class()); |
Type& type = Type::ZoneHandle( |
@@ -9386,27 +9387,15 @@ |
if (map_type_arguments.Length() == 2) { |
key_type = map_type_arguments.TypeAt(0); |
value_type = map_type_arguments.TypeAt(1); |
+ // Malformed type arguments are mapped to dynamic. |
+ ASSERT(!key_type.IsMalformed() && !value_type.IsMalformed()); |
+ // No declared bounds in Map. |
+ ASSERT(!key_type.IsMalbounded() && !value_type.IsMalbounded()); |
if (is_const && !type_arguments.IsInstantiated()) { |
ErrorMsg(type_pos, |
"the type arguments of a constant map literal cannot include " |
"a type variable"); |
} |
- if (key_type.IsMalformed()) { |
- if (FLAG_error_on_bad_type) { |
- ErrorMsg(Error::Handle(key_type.malformed_error())); |
- } |
- // Map malformed key type to dynamic. |
- key_type = Type::DynamicType(); |
- map_type_arguments.SetTypeAt(0, key_type); |
- } |
- if (value_type.IsMalformed()) { |
- if (FLAG_error_on_bad_type) { |
- ErrorMsg(Error::Handle(value_type.malformed_error())); |
- } |
- // Map malformed value type to dynamic. |
- value_type = Type::DynamicType(); |
- map_type_arguments.SetTypeAt(1, value_type); |
- } |
} else { |
if (FLAG_error_on_bad_type) { |
ErrorMsg(type_pos, |
@@ -9417,10 +9406,7 @@ |
map_type_arguments = AbstractTypeArguments::null(); |
} |
} |
- ASSERT((map_type_arguments.IsNull() && |
- key_type.IsDynamicType() && value_type.IsDynamicType()) || |
- ((map_type_arguments.Length() == 2) && |
- !key_type.IsMalformed() && !value_type.IsMalformed())); |
+ ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
map_type_arguments ^= map_type_arguments.Canonicalize(); |
GrowableArray<AstNode*> kv_pairs_list; |
@@ -9604,8 +9590,10 @@ |
const intptr_t type_pos = TokenPos(); |
AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle( |
ParseTypeArguments(ClassFinalizer::kCanonicalize)); |
+ // Malformed type arguments are mapped to dynamic, so we will not encounter |
+ // them here. |
// Map and List interfaces do not declare bounds on their type parameters, so |
- // we should never see a malformed type argument mapped to dynamic here. |
+ // we will not see malbounded type arguments here. |
AstNode* primary = NULL; |
if ((CurrentToken() == Token::kLBRACK) || |
(CurrentToken() == Token::kINDEX)) { |