diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index c3b52ba162c..d53c037a2d8 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -3851,10 +3851,10 @@ bool Class::TypeTestNonRecursive(const Class& cls, Isolate* isolate = thread->isolate(); Class& this_class = Class::Handle(zone, cls.raw()); while (true) { - // Check for DynamicType. // Each occurrence of DynamicType in type T is interpreted as the dynamic - // type, a supertype of all types. - if (other.IsDynamicClass()) { + // type, a supertype of all types. So are Object and void types. + if (other.IsDynamicClass() || other.IsObjectClass() || + other.IsVoidClass()) { return true; } // Check for NullType, which, as of Dart 1.5, is a subtype of (and is more @@ -3880,11 +3880,6 @@ bool Class::TypeTestNonRecursive(const Class& cls, if (this_class.IsDynamicClass()) { return !isolate->strong() && (test_kind == Class::kIsSubtypeOf); } - // Check for ObjectType. Any type that is not NullType or DynamicType - // (already checked above), is more specific than ObjectType/VoidType. - if (other.IsObjectClass() || other.IsVoidClass()) { - return true; - } // If other is neither Object, dynamic or void, then ObjectType/VoidType // can't be a subtype of other. if (this_class.IsObjectClass() || this_class.IsVoidClass()) { @@ -3902,7 +3897,7 @@ bool Class::TypeTestNonRecursive(const Class& cls, // below), we only check a subvector of the proper length. // Check for covariance. if (other_type_arguments.IsNull() || - other_type_arguments.IsRaw(from_index, num_type_params)) { + other_type_arguments.IsTopTypes(from_index, num_type_params)) { return true; } if (type_arguments.IsNull() || @@ -4025,8 +4020,7 @@ bool Class::FutureOrTypeTest(Zone* zone, } const AbstractType& other_type_arg = AbstractType::Handle(zone, other_type_arguments.TypeAt(0)); - if (other_type_arg.IsObjectType() || other_type_arg.IsDynamicType() || - other_type_arg.IsVoidType()) { + if (other_type_arg.IsTopType()) { return true; } if (!type_arguments.IsNull() && IsFutureClass()) { @@ -4798,6 +4792,18 @@ bool TypeArguments::IsDynamicTypes(bool raw_instantiated, return true; } +bool TypeArguments::IsTopTypes(intptr_t from_index, intptr_t len) const { + ASSERT(Length() >= (from_index + len)); + AbstractType& type = AbstractType::Handle(); + for (intptr_t i = 0; i < len; i++) { + type = TypeAt(from_index + i); + if (type.IsNull() || !type.IsTopType()) { + return false; + } + } + return true; +} + bool TypeArguments::TypeTest(TypeTestKind test_kind, const TypeArguments& other, intptr_t from_index, @@ -6609,7 +6615,7 @@ bool Function::TestParameterType(TypeTestKind test_kind, if (Isolate::Current()->strong()) { const AbstractType& param_type = AbstractType::Handle(ParameterTypeAt(parameter_position)); - if (param_type.IsDynamicType()) { + if (param_type.IsTopType()) { return true; } const AbstractType& other_param_type = @@ -15759,7 +15765,7 @@ bool Instance::IsInstanceOf( Isolate* isolate = thread->isolate(); const Class& cls = Class::Handle(zone, clazz()); if (cls.IsClosureClass()) { - if (other.IsObjectType() || other.IsDartFunctionType() || + if (other.IsTopType() || other.IsDartFunctionType() || other.IsDartClosureType()) { return true; } @@ -15776,9 +15782,7 @@ bool Instance::IsInstanceOf( if (instantiated_other.IsTypeRef()) { instantiated_other = TypeRef::Cast(instantiated_other).type(); } - if (instantiated_other.IsDynamicType() || - instantiated_other.IsObjectType() || - instantiated_other.IsVoidType() || + if (instantiated_other.IsTopType() || instantiated_other.IsDartFunctionType()) { return true; } @@ -15834,8 +15838,7 @@ bool Instance::IsInstanceOf( if (instantiated_other.IsTypeRef()) { instantiated_other = TypeRef::Cast(instantiated_other).type(); } - if (instantiated_other.IsDynamicType() || - instantiated_other.IsObjectType() || instantiated_other.IsVoidType()) { + if (instantiated_other.IsTopType()) { return true; } } @@ -15899,8 +15902,7 @@ bool Instance::IsFutureOrInstanceOf(Zone* zone, TypeArguments::Handle(zone, other.arguments()); const AbstractType& other_type_arg = AbstractType::Handle(zone, other_type_arguments.TypeAt(0)); - if (other_type_arg.IsObjectType() || other_type_arg.IsDynamicType() || - other_type_arg.IsVoidType()) { + if (other_type_arg.IsTopType()) { return true; } if (Class::Handle(zone, clazz()).IsFutureClass()) { @@ -16474,70 +16476,88 @@ bool AbstractType::IsDynamicType() const { } bool AbstractType::IsVoidType() const { + // The void type is always canonical, because void is a keyword. return raw() == Object::void_type().raw(); } +bool AbstractType::IsObjectType() const { + return HasResolvedTypeClass() && (type_class_id() == kInstanceCid); +} + +bool AbstractType::IsTopType() const { + if (IsVoidType()) { + return true; + } + if (!HasResolvedTypeClass()) { + return false; + } + classid_t cid = type_class_id(); + return (cid == kDynamicCid) || (cid == kInstanceCid); +} + bool AbstractType::IsNullType() const { - return !IsFunctionType() && HasResolvedTypeClass() && + return HasResolvedTypeClass() && (type_class() == Isolate::Current()->object_store()->null_class()); } bool AbstractType::IsBoolType() const { - return !IsFunctionType() && HasResolvedTypeClass() && + return HasResolvedTypeClass() && (type_class() == Isolate::Current()->object_store()->bool_class()); } bool AbstractType::IsIntType() const { - return !IsFunctionType() && HasResolvedTypeClass() && + return HasResolvedTypeClass() && (type_class() == Type::Handle(Type::IntType()).type_class()); } bool AbstractType::IsInt64Type() const { - return !IsFunctionType() && HasResolvedTypeClass() && + return HasResolvedTypeClass() && (type_class() == Type::Handle(Type::Int64Type()).type_class()); } bool AbstractType::IsDoubleType() const { - return !IsFunctionType() && HasResolvedTypeClass() && + return HasResolvedTypeClass() && (type_class() == Type::Handle(Type::Double()).type_class()); } bool AbstractType::IsFloat32x4Type() const { - return !IsFunctionType() && HasResolvedTypeClass() && + return HasResolvedTypeClass() && (type_class() == Type::Handle(Type::Float32x4()).type_class()); } bool AbstractType::IsFloat64x2Type() const { - return !IsFunctionType() && HasResolvedTypeClass() && + return HasResolvedTypeClass() && (type_class() == Type::Handle(Type::Float64x2()).type_class()); } bool AbstractType::IsInt32x4Type() const { - return !IsFunctionType() && HasResolvedTypeClass() && + return HasResolvedTypeClass() && (type_class() == Type::Handle(Type::Int32x4()).type_class()); } bool AbstractType::IsNumberType() const { - return !IsFunctionType() && HasResolvedTypeClass() && + return HasResolvedTypeClass() && (type_class() == Type::Handle(Type::Number()).type_class()); } bool AbstractType::IsSmiType() const { - return !IsFunctionType() && HasResolvedTypeClass() && + return HasResolvedTypeClass() && (type_class() == Type::Handle(Type::SmiType()).type_class()); } bool AbstractType::IsStringType() const { - return !IsFunctionType() && HasResolvedTypeClass() && + return HasResolvedTypeClass() && (type_class() == Type::Handle(Type::StringType()).type_class()); } bool AbstractType::IsDartFunctionType() const { - return !IsFunctionType() && HasResolvedTypeClass() && + return HasResolvedTypeClass() && (type_class() == Type::Handle(Type::DartFunctionType()).type_class()); } bool AbstractType::IsDartClosureType() const { + // Non-typedef function types have '_Closure' class as type class, but are not + // the Dart '_Closure' type. return !IsFunctionType() && HasResolvedTypeClass() && (type_class() == Isolate::Current()->object_store()->closure_class()); } @@ -16580,8 +16600,7 @@ bool AbstractType::TypeTest(TypeTestKind test_kind, // comparing function-types). // As of Dart 1.5, the Null type is a subtype of (and is more specific than) // any type. - if (other.IsObjectType() || other.IsDynamicType() || other.IsVoidType() || - IsNullType()) { + if (other.IsTopType() || IsNullType()) { return true; } Thread* thread = Thread::Current(); @@ -16746,8 +16765,7 @@ bool AbstractType::FutureOrTypeTest(Zone* zone, TypeArguments::Handle(zone, other.arguments()); const AbstractType& other_type_arg = AbstractType::Handle(zone, other_type_arguments.TypeAt(0)); - if (other_type_arg.IsObjectType() || other_type_arg.IsDynamicType() || - other_type_arg.IsVoidType()) { + if (other_type_arg.IsTopType()) { return true; } // Retry the TypeTest function after unwrapping type arg of FutureOr. @@ -17127,7 +17145,7 @@ bool Type::IsEquivalent(const Instance& other, TrailPtr trail) const { if (IsMalbounded() != other_type.IsMalbounded()) { return false; // Do not drop bound error. } - if (type_class() != other_type.type_class()) { + if (type_class_id() != other_type.type_class_id()) { return false; } if (!IsFinalized() || !other_type.IsFinalized()) { @@ -17435,13 +17453,11 @@ RawAbstractType* Type::Canonicalize(TrailPtr trail) const { // Since void is a keyword, we never have to canonicalize the void type after // it is canonicalized once by the vm isolate. The parser does the mapping. - ASSERT((type_class() != Object::void_class()) || - (isolate == Dart::vm_isolate())); + ASSERT((type_class_id() != kVoidCid) || (isolate == Dart::vm_isolate())); // Since dynamic is not a keyword, the parser builds a type that requires // canonicalization. - if ((type_class() == Object::dynamic_class()) && - (isolate != Dart::vm_isolate())) { + if ((type_class_id() == kDynamicCid) && (isolate != Dart::vm_isolate())) { ASSERT(Object::dynamic_type().IsCanonical()); return Object::dynamic_type().raw(); } @@ -17549,7 +17565,7 @@ bool Type::CheckIsCanonical(Thread* thread) const { if (IsMalformed() || IsRecursive()) { return true; } - if (type_class() == Object::dynamic_class()) { + if (type_class_id() == kDynamicCid) { return (raw() == Object::dynamic_type().raw()); } Zone* zone = thread->zone(); @@ -17615,7 +17631,7 @@ intptr_t Type::ComputeHash() const { ASSERT(IsFinalized()); uint32_t result = 1; if (IsMalformed()) return result; - result = CombineHashes(result, Class::Handle(type_class()).id()); + result = CombineHashes(result, type_class_id()); result = CombineHashes(result, TypeArguments::Handle(arguments()).Hash()); if (IsFunctionType()) { const Function& sig_fun = Function::Handle(signature()); diff --git a/runtime/vm/object.h b/runtime/vm/object.h index 9da8f8c9de8..5b9fdea8bb4 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -5665,6 +5665,11 @@ class TypeArguments : public Instance { return IsDynamicTypes(true, 0, len); } + // Check if the subvector of length 'len' starting at 'from_index' of this + // type argument vector consists solely of DynamicType, ObjectType, or + // VoidType. + bool IsTopTypes(intptr_t from_index, intptr_t len) const; + // Check the subtype relationship, considering only a subvector of length // 'len' starting at 'from_index'. bool IsSubtypeOf(const TypeArguments& other, @@ -5985,10 +5990,12 @@ class AbstractType : public Instance { // Check if this type represents the 'Null' type. bool IsNullType() const; - bool IsObjectType() const { - return !IsFunctionType() && HasResolvedTypeClass() && - Class::Handle(type_class()).IsObjectClass(); - } + // Check if this type represents the 'Object' type. + bool IsObjectType() const; + + // Check if this type represents a top type, i.e. 'dynamic', 'Object', or + // 'void' type. + bool IsTopType() const; // Check if this type represents the 'bool' type. bool IsBoolType() const; @@ -6265,6 +6272,9 @@ class TypeRef : public AbstractType { } RawAbstractType* type() const { return raw_ptr()->type_; } void set_type(const AbstractType& value) const; + virtual classid_t type_class_id() const { + return AbstractType::Handle(type()).type_class_id(); + } virtual RawClass* type_class() const { return AbstractType::Handle(type()).type_class(); } @@ -6440,6 +6450,9 @@ class BoundedType : public AbstractType { virtual bool HasResolvedTypeClass() const { return AbstractType::Handle(type()).HasResolvedTypeClass(); } + virtual classid_t type_class_id() const { + return AbstractType::Handle(type()).type_class_id(); + } virtual RawClass* type_class() const { return AbstractType::Handle(type()).type_class(); } diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status index 30ccbe777b4..074fb061e73 100644 --- a/tests/corelib_2/corelib_2.status +++ b/tests/corelib_2/corelib_2.status @@ -420,15 +420,11 @@ bigint_test: Pass, Timeout # Please triage. [ $compiler == dartk && $runtime == vm && $strong ] apply3_test: CompileTimeError # Issue 31402 (Invocation arguments) bool_from_environment2_test/03: MissingCompileTimeError -collection_removes_test: RuntimeError compare_to2_test: RuntimeError -hash_set_test/01: RuntimeError -hash_set_test/none: RuntimeError int_modulo_arith_test/modPow: CompileTimeError # Issue 31402 (Assert statement) int_modulo_arith_test/none: CompileTimeError # Issue 31402 (Assert statement) iterable_empty_test: RuntimeError iterable_fold_test/02: RuntimeError -iterable_mapping_test/none: RuntimeError iterable_reduce_test/01: CompileTimeError # Issue 31533 iterable_reduce_test/none: RuntimeError iterable_to_list_test/01: RuntimeError @@ -438,9 +434,7 @@ list_replace_range_test: RuntimeError list_set_all_test: RuntimeError null_nosuchmethod_test/01: CompileTimeError # Issue 31402 (Invocation arguments) null_nosuchmethod_test/none: CompileTimeError # Issue 31402 (Invocation arguments) -set_test: RuntimeError splay_tree_from_iterable_test: RuntimeError -splay_tree_test/none: RuntimeError string_case_test/01: RuntimeError string_from_environment3_test/03: MissingCompileTimeError string_trimlr_test/02: RuntimeError @@ -459,15 +453,11 @@ unicode_test: RuntimeError # ===== dartkp + dart_precompiled status lines ===== [ $compiler == dartkp && $runtime == dart_precompiled && $strong ] bool_from_environment2_test/03: MissingCompileTimeError -collection_removes_test: RuntimeError compare_to2_test: RuntimeError -hash_set_test/01: RuntimeError -hash_set_test/none: RuntimeError int_modulo_arith_test/modPow: CompileTimeError # Issue 31402 (Assert statement) int_modulo_arith_test/none: CompileTimeError # Issue 31402 (Assert statement) iterable_empty_test: RuntimeError iterable_fold_test/02: RuntimeError -iterable_mapping_test/none: RuntimeError iterable_reduce_test/01: CompileTimeError # Issue 31533 iterable_reduce_test/none: RuntimeError iterable_to_list_test/01: RuntimeError @@ -478,9 +468,7 @@ list_set_all_test: RuntimeError null_nosuchmethod_test/01: CompileTimeError # Issue 31402 (Invocation arguments) null_nosuchmethod_test/none: CompileTimeError # Issue 31402 (Invocation arguments) regexp/stack-overflow_test: RuntimeError -set_test: RuntimeError splay_tree_from_iterable_test: RuntimeError -splay_tree_test/none: RuntimeError string_case_test/01: RuntimeError string_from_environment3_test/03: MissingCompileTimeError string_trimlr_test/02: RuntimeError diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status index 88b177b6b81..d20b686473e 100644 --- a/tests/language_2/language_2_kernel.status +++ b/tests/language_2/language_2_kernel.status @@ -643,7 +643,6 @@ generic_function_type_as_type_argument_test/02: Pass # For the wrong reason, iss generic_function_type_as_type_argument_test/02: MissingCompileTimeError, OK # No type inference generic_function_typedef2_test/04: MissingCompileTimeError generic_instanceof2_test: RuntimeError -generic_instanceof_test: RuntimeError generic_is_check_test: RuntimeError generic_list_checked_test: CompileTimeError # Issue 31402 (Variable declaration) generic_method_types_test/02: RuntimeError @@ -682,7 +681,6 @@ import_self_test/01: MissingCompileTimeError initializing_formal_final_test: MissingCompileTimeError initializing_formal_type_annotation_test/01: MissingCompileTimeError initializing_formal_type_annotation_test/02: MissingCompileTimeError -instanceof2_test: RuntimeError instantiate_tearoff_after_contravariance_check_test: CompileTimeError instantiate_tearoff_of_call_test: CompileTimeError instantiate_tearoff_test: CompileTimeError @@ -798,7 +796,6 @@ malformed_test/22: MissingCompileTimeError malformed_test/23: MissingCompileTimeError malformed_test/24: MissingCompileTimeError malformed_type_test: MissingCompileTimeError -many_generic_instanceof_test: RuntimeError map_literal3_test/01: MissingCompileTimeError map_literal3_test/02: MissingCompileTimeError map_literal3_test/03: MissingCompileTimeError @@ -1875,7 +1872,6 @@ generic_function_typedef2_test/04: MissingCompileTimeError generic_function_typedef_test/01: Pass generic_function_typedef_test/01: RuntimeError generic_instanceof2_test: RuntimeError -generic_instanceof_test: RuntimeError generic_is_check_test: RuntimeError generic_list_checked_test: RuntimeError generic_list_checked_test: CompileTimeError # Issue 31402 (Variable declaration) @@ -1949,7 +1945,6 @@ initializing_formal_final_test: MissingCompileTimeError initializing_formal_type_annotation_test/01: MissingCompileTimeError initializing_formal_type_annotation_test/02: MissingCompileTimeError instance_creation_in_function_annotation_test: SkipByDesign -instanceof2_test: RuntimeError instanceof4_test/01: RuntimeError instanceof4_test/01: Pass instanceof4_test/none: Pass @@ -2073,7 +2068,6 @@ malformed_test/22: MissingCompileTimeError malformed_test/23: MissingCompileTimeError malformed_test/24: MissingCompileTimeError malformed_type_test: MissingCompileTimeError -many_generic_instanceof_test: RuntimeError many_overridden_no_such_method_test: SkipByDesign map_literal3_test/01: MissingCompileTimeError map_literal3_test/02: MissingCompileTimeError diff --git a/tests/language_2/vm/type_vm_test.dart b/tests/language_2/vm/type_vm_test.dart index a5aa7785e12..cd3059f53b4 100644 --- a/tests/language_2/vm/type_vm_test.dart +++ b/tests/language_2/vm/type_vm_test.dart @@ -127,7 +127,7 @@ class TypeTest { { var a = new List(5); List a0 = a; - List ao = a; //# 29: runtime error + List ao = a; // No error. List ai = a; //# 30: runtime error List an = a; //# 31: runtime error List as = a; //# 32: runtime error diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status index 315dbeb4cb2..e0d2623990c 100644 --- a/tests/lib_2/lib_2_kernel.status +++ b/tests/lib_2/lib_2_kernel.status @@ -124,7 +124,6 @@ mirrors/empty_test: Crash mirrors/empty_test: RuntimeError mirrors/enum_test: CompileTimeError # Issue 31402 (Invocation arguments) mirrors/equality_test: RuntimeError -mirrors/fake_function_without_call_test: RuntimeError mirrors/function_type_mirror_test: RuntimeError mirrors/generic_bounded_by_type_parameter_test/02: MissingCompileTimeError mirrors/generic_bounded_test/01: MissingCompileTimeError @@ -284,13 +283,7 @@ async/timer_cancel_test: RuntimeError async/timer_isActive_test: RuntimeError async/timer_repeat_test: RuntimeError async/zone_run_unary_test: RuntimeError -convert/chunked_conversion_json_decode1_test: RuntimeError -convert/json_chunk_test: RuntimeError -convert/json_test: RuntimeError convert/json_toEncodable_reviver_test: CompileTimeError -convert/json_utf8_chunk_test: RuntimeError -convert/streamed_conversion_json_encode1_test: RuntimeError -convert/streamed_conversion_json_utf8_encode_test: RuntimeError isolate/count_test: Timeout isolate/cross_isolate_message_test: RuntimeError isolate/illegal_msg_function_test: RuntimeError @@ -331,7 +324,6 @@ mirrors/class_mirror_type_variables_test: RuntimeError mirrors/closures_test: RuntimeError mirrors/constructors_test: RuntimeError mirrors/fake_function_with_call_test: RuntimeError -mirrors/function_apply_test: RuntimeError mirrors/generic_bounded_by_type_parameter_test/none: RuntimeError mirrors/generic_bounded_test/none: RuntimeError mirrors/generic_class_declaration_test: RuntimeError @@ -354,7 +346,6 @@ mirrors/instantiate_abstract_class_test: RuntimeError mirrors/intercepted_class_test: RuntimeError mirrors/invocation_fuzz_test/smi: Pass mirrors/invoke_closurization2_test: RuntimeError -mirrors/invoke_named_test/none: RuntimeError mirrors/library_declarations_test/01: RuntimeError mirrors/library_imports_bad_metadata_test/none: RuntimeError mirrors/metadata_const_map_test: Crash @@ -372,7 +363,6 @@ mirrors/reflected_type_test/01: MissingCompileTimeError mirrors/reflected_type_test/02: MissingCompileTimeError mirrors/reflected_type_test/03: MissingCompileTimeError mirrors/regress_16321_test/none: Crash -mirrors/regress_19731_test: RuntimeError mirrors/return_type_test: RuntimeError mirrors/top_level_accessors_test/01: MissingCompileTimeError mirrors/type_argument_is_type_variable_test: RuntimeError @@ -442,13 +432,7 @@ async/timer_not_available_test: RuntimeError async/timer_repeat_test: CompileTimeError # Issue 31402 (Invocation arguments) async/timer_test: CompileTimeError # Issue 31402 (Invocation arguments) async/zone_run_unary_test: CompileTimeError # Issue 31537 -convert/chunked_conversion_json_decode1_test: RuntimeError -convert/json_chunk_test: RuntimeError -convert/json_test: RuntimeError convert/json_toEncodable_reviver_test: CompileTimeError -convert/json_utf8_chunk_test: RuntimeError -convert/streamed_conversion_json_encode1_test: RuntimeError -convert/streamed_conversion_json_utf8_encode_test: RuntimeError html/*: SkipByDesign # dart:html not supported on VM. isolate/compile_time_error_test/01: Crash isolate/compile_time_error_test/01: MissingCompileTimeError diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status index c92612e6010..678a68810f9 100644 --- a/tests/standalone_2/standalone_2.status +++ b/tests/standalone_2/standalone_2.status @@ -104,7 +104,6 @@ io/http_proxy_advanced_test: CompileTimeError io/http_redirect_test: RuntimeError io/http_reuse_server_port_test: RuntimeError io/http_server_response_test: RuntimeError -io/http_session_test: RuntimeError io/regress_10026_test: RuntimeError io/skipping_dart2js_compilations_test: CompileTimeError io/socket_upgrade_to_secure_test: RuntimeError