Skip to content

Commit

Permalink
[vm] Make Class::RareType() the instantiated to bounds type.
Browse files Browse the repository at this point in the history
Previously, Class::RareType() returned a Type where the type arguments
were null (e.g., all dynamic). However, this is an invalid type for
classes that have at least one type parameter with a bound that is not a
top type, and could mean that comparisons (such as subtyping) against
the "rare" type could return incorrect answers.

Instead, use TypeParameters::defaults() to get the canonicalized
instantiated to bounds type argument vector and use that instead.

TEST=ci

Cq-Include-Trybots: luci.dart.try:vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-linux-debug-x64-try,vm-linux-release-x64-try
Change-Id: Iea591e93102f53713265b481476f9670cfb81c93
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/312261
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
  • Loading branch information
sstrickl authored and Commit Queue committed Jul 3, 2023
1 parent a3e8416 commit 7cc005e
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 9 deletions.
6 changes: 2 additions & 4 deletions runtime/vm/compiler/backend/il.cc
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,9 @@ bool HierarchyInfo::CanUseSubtypeRangeCheckFor(const AbstractType& type) {
// arguments.
//
// This is e.g. true for "String" but also for "List<dynamic>". (A type for
// which the type arguments vector is filled with "dynamic" is known as a rare
// type)
// which the type arguments vector is instantiated to bounds is known as a
// rare type.)
if (type_class.IsGeneric()) {
// TODO(kustermann): We might want to consider extending this when the type
// arguments are not "dynamic" but instantiated-to-bounds.
const Type& rare_type = Type::Handle(zone, type_class.RareType());
if (!rare_type.IsSubtypeOf(type, Heap::kNew)) {
ASSERT(Type::Cast(type).arguments() != TypeArguments::null());
Expand Down
15 changes: 11 additions & 4 deletions runtime/vm/object.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3068,12 +3068,17 @@ bool Class::IsInFullSnapshot() const {
}

TypePtr Class::RareType() const {
if (!IsGeneric() && !IsClosureClass()) {
if (!IsGeneric()) {
return DeclarationType();
}
ASSERT(is_declaration_loaded());
Type& type = Type::Handle(Type::New(*this, Object::null_type_arguments(),
Nullability::kNonNullable));
Thread* const thread = Thread::Current();
Zone* const zone = thread->zone();
const auto& inst_to_bounds =
TypeArguments::Handle(zone, InstantiateToBounds(thread));
ASSERT(inst_to_bounds.ptr() != Object::empty_type_arguments().ptr());
auto& type = Type::Handle(
zone, Type::New(*this, inst_to_bounds, Nullability::kNonNullable));
type ^= ClassFinalizer::FinalizeType(type);
return type.ptr();
}
Expand Down Expand Up @@ -22768,12 +22773,14 @@ void Type::PrintName(NameVisibility name_visibility,
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const Class& cls = Class::Handle(zone, type_class());
const TypeParameters& params =
TypeParameters::Handle(zone, cls.type_parameters());
printer->AddString(cls.NameCString(name_visibility));
const TypeArguments& args = TypeArguments::Handle(zone, arguments());
intptr_t num_type_params = 0;
if (cls.is_declaration_loaded()) {
num_type_params = cls.NumTypeParameters(thread);
} else if (!args.IsNull()) {
} else if (!args.IsNull() || args.ptr() != params.defaults()) {
num_type_params = args.Length();
}
if (num_type_params == 0) {
Expand Down
3 changes: 2 additions & 1 deletion runtime/vm/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -1198,7 +1198,7 @@ class Class : public Object {

int32_t SourceFingerprint() const;

// Return the Type with type arguments filled in with dynamic.
// Return the Type with type arguments instantiated to bounds.
TypePtr RareType() const;

// Return the non-nullable Type whose arguments are the type parameters
Expand Down Expand Up @@ -8315,6 +8315,7 @@ class TypeParameters : public Object {
friend class FunctionType;
friend class Object;
friend class Precompiler;
friend class Type; // To determine whether to print type arguments.
};

// A TypeArguments is an array of AbstractType.
Expand Down

0 comments on commit 7cc005e

Please sign in to comment.