| Index: runtime/vm/class_finalizer.cc
|
| ===================================================================
|
| --- runtime/vm/class_finalizer.cc (revision 30381)
|
| +++ runtime/vm/class_finalizer.cc (working copy)
|
| @@ -286,13 +286,9 @@
|
| }
|
| if (factory.is_const()) {
|
| type = factory.RedirectionType();
|
| - if (type.IsMalformed()) {
|
| - ReportError(Error::Handle(type.malformed_error()));
|
| + if (type.IsMalformedOrMalbounded()) {
|
| + ReportError(Error::Handle(type.error()));
|
| }
|
| - Error& error = Error::Handle();
|
| - if (type.IsMalboundedWithError(&error)) {
|
| - ReportError(error);
|
| - }
|
| }
|
| }
|
| }
|
| @@ -320,7 +316,7 @@
|
| // Check if target is already resolved.
|
| Type& type = Type::Handle(factory.RedirectionType());
|
| Function& target = Function::Handle(factory.RedirectionTarget());
|
| - if (type.IsMalformed() || (type.IsResolved() && type.IsMalbounded())) {
|
| + if (type.IsMalformedOrMalbounded()) {
|
| // Already resolved to a malformed or malbounded type. Will throw on usage.
|
| ASSERT(target.IsNull());
|
| return;
|
| @@ -338,7 +334,7 @@
|
| ResolveType(cls, type, kCanonicalize);
|
| type ^= FinalizeType(cls, type, kCanonicalize);
|
| factory.SetRedirectionType(type);
|
| - if (type.IsMalformed() || type.IsMalbounded()) {
|
| + if (type.IsMalformedOrMalbounded()) {
|
| ASSERT(factory.RedirectionTarget() == Function::null());
|
| return;
|
| }
|
| @@ -814,7 +810,7 @@
|
| // Specifying no type arguments indicates a raw type, which is not an error.
|
| // However, type parameter bounds are checked below, even for a raw type.
|
| if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) {
|
| - // Wrong number of type arguments. The type is malformed.
|
| + // Wrong number of type arguments. The type is mapped to the raw type.
|
| if (FLAG_error_on_bad_type) {
|
| const Script& script = Script::Handle(cls.script());
|
| const String& type_class_name = String::Handle(type_class.Name());
|
| @@ -919,18 +915,17 @@
|
| FinalizeTypesInClass(type_class);
|
| }
|
|
|
| - // If a bound error occurred, return a BoundedType with a malformed bound.
|
| - // The malformed bound will be ignored in production mode.
|
| + // If a bound error occurred, mark the type as malbounded.
|
| + // The bound error will be ignored in production mode.
|
| if (!bound_error.IsNull()) {
|
| // No compile-time error during finalization.
|
| const String& parameterized_type_name = String::Handle(
|
| parameterized_type.UserVisibleName());
|
| - const Type& malformed_bound = Type::Handle(
|
| - NewFinalizedMalformedType(bound_error,
|
| - Script::Handle(cls.script()),
|
| - parameterized_type.token_pos(),
|
| - "type '%s' has an out of bound type argument",
|
| - parameterized_type_name.ToCString()));
|
| + FinalizeMalboundedType(bound_error,
|
| + Script::Handle(cls.script()),
|
| + parameterized_type,
|
| + "type '%s' has an out of bound type argument",
|
| + parameterized_type_name.ToCString());
|
|
|
| if (FLAG_trace_type_finalization) {
|
| OS::Print("Done finalizing malbounded type '%s' with bound error: %s\n",
|
| @@ -938,9 +933,7 @@
|
| bound_error.ToCString());
|
| }
|
|
|
| - return BoundedType::New(parameterized_type,
|
| - malformed_bound,
|
| - TypeParameter::Handle());
|
| + return parameterized_type.raw();;
|
| }
|
|
|
| if (FLAG_trace_type_finalization) {
|
| @@ -1163,18 +1156,18 @@
|
| (field.value() != Object::sentinel().raw())) {
|
| // The parser does not preset the value if the type is a type parameter or
|
| // is parameterized unless the value is null.
|
| - Error& malformed_error = Error::Handle();
|
| - if (type.IsMalformed()) {
|
| - malformed_error = type.malformed_error();
|
| + Error& error = Error::Handle();
|
| + if (type.IsMalformedOrMalbounded()) {
|
| + error = type.error();
|
| } else {
|
| ASSERT(type.IsInstantiated());
|
| }
|
| const Instance& const_value = Instance::Handle(field.value());
|
| - if (!malformed_error.IsNull() ||
|
| + if (!error.IsNull() ||
|
| (!type.IsDynamicType() &&
|
| !const_value.IsInstanceOf(type,
|
| AbstractTypeArguments::Handle(),
|
| - &malformed_error))) {
|
| + &error))) {
|
| if (FLAG_error_on_bad_type) {
|
| const AbstractType& const_value_type = AbstractType::Handle(
|
| const_value.GetType());
|
| @@ -1182,7 +1175,7 @@
|
| const_value_type.UserVisibleName());
|
| const String& type_name = String::Handle(type.UserVisibleName());
|
| const Script& script = Script::Handle(cls.script());
|
| - ReportError(malformed_error, script, field.token_pos(),
|
| + ReportError(error, script, field.token_pos(),
|
| "error initializing static %s field '%s': "
|
| "type '%s' is not a subtype of type '%s'",
|
| field.is_const() ? "const" : "final",
|
| @@ -2410,8 +2403,8 @@
|
|
|
| // Resolve super type. Failures lead to a longjmp.
|
| ResolveType(cls, super_type, kCanonicalizeWellFormed);
|
| - if (super_type.IsMalformed()) {
|
| - ReportError(Error::Handle(super_type.malformed_error()));
|
| + if (super_type.IsMalformedOrMalbounded()) {
|
| + ReportError(Error::Handle(super_type.error()));
|
| }
|
| if (super_type.IsDynamicType()) {
|
| const Script& script = Script::Handle(cls.script());
|
| @@ -2488,8 +2481,9 @@
|
| interface ^= super_interfaces.At(i);
|
| ResolveType(cls, interface, kCanonicalizeWellFormed);
|
| ASSERT(!interface.IsTypeParameter()); // Should be detected by parser.
|
| + // A malbounded interface is only reported when involved in a type test.
|
| if (interface.IsMalformed()) {
|
| - ReportError(Error::Handle(interface.malformed_error()));
|
| + ReportError(Error::Handle(interface.error()));
|
| }
|
| if (interface.IsDynamicType()) {
|
| const Script& script = Script::Handle(cls.script());
|
| @@ -2622,7 +2616,7 @@
|
| if (FLAG_error_on_bad_type) {
|
| ReportError(error);
|
| }
|
| - type.set_malformed_error(error);
|
| + type.set_error(error);
|
| // Make the type raw, since it may not be possible to
|
| // properly finalize its type arguments.
|
| type.set_type_class(Class::Handle(Object::dynamic_class()));
|
| @@ -2669,6 +2663,29 @@
|
| }
|
|
|
|
|
| +void ClassFinalizer::FinalizeMalboundedType(const Error& prev_error,
|
| + const Script& script,
|
| + const Type& type,
|
| + const char* format, ...) {
|
| + va_list args;
|
| + va_start(args, format);
|
| + LanguageError& error = LanguageError::Handle(
|
| + LanguageError::NewFormattedV(
|
| + prev_error, script, type.token_pos(),
|
| + LanguageError::kMalboundedType, Heap::kOld,
|
| + format, args));
|
| + va_end(args);
|
| + if (FLAG_error_on_bad_type) {
|
| + ReportError(error);
|
| + }
|
| + type.set_error(error);
|
| + if (!type.IsFinalized()) {
|
| + type.SetIsFinalized();
|
| + // Do not canonicalize malbounded types.
|
| + }
|
| +}
|
| +
|
| +
|
| void ClassFinalizer::ReportError(const Error& error) {
|
| Isolate::Current()->long_jump_base()->Jump(1, error);
|
| UNREACHABLE();
|
|
|