Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Unified Diff: runtime/vm/object.cc

Issue 1580643004: Fix finalization of recursive type graph with bounds (issue 25389). (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 8e3284f3020ddb2e84329e0df43cb0984cd0afb6..b5e035f54a88920ce69eb5d807840ae5d063cbe6 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -3876,6 +3876,12 @@ bool Class::TypeTestNonRecursive(const Class& cls,
if (!interface.IsFinalized()) {
// We may be checking bounds at finalization time and can encounter
// a still unfinalized interface.
+ if (interface.IsBeingFinalized()) {
+ // Interface is part of a still unfinalized recursive type graph.
+ // Skip it. The caller will create a bounded type to be checked at
+ // runtime if this type test returns false at compile time.
+ continue;
+ }
ClassFinalizer::FinalizeType(
thsi, interface, ClassFinalizer::kCanonicalize);
interfaces.SetAt(i, interface);
@@ -15513,8 +15519,8 @@ RawString* AbstractType::BuildName(NameVisibility name_visibility) const {
} else if (bound.IsType()) {
const Class& cls = Class::Handle(zone, Type::Cast(bound).type_class());
bound_name = cls.Name();
+ pieces.Add(bound_name);
if (Type::Cast(bound).arguments() != TypeArguments::null()) {
- pieces.Add(bound_name);
pieces.Add(Symbols::OptimizedOut());
}
} else {
@@ -15727,6 +15733,11 @@ bool AbstractType::TypeTest(TypeTestKind test_kind,
if (Equals(other)) {
return true;
}
+ // Redundant check if other type is equal to the upper bound of this type.
+ if (IsBoundedType() &&
+ AbstractType::Handle(BoundedType::Cast(*this).bound()).Equals(other)) {
+ return true;
+ }
return false; // TODO(regis): We should return "maybe after instantiation".
}
// Type parameters cannot be handled by Class::TypeTest().
@@ -16144,6 +16155,13 @@ bool Type::IsEquivalent(const Instance& other, TrailPtr trail) const {
for (intptr_t i = 0; i < from_index; i++) {
type_arg = type_args.TypeAt(i);
other_type_arg = other_type_args.TypeAt(i);
+ // Ignore bounds of bounded types.
+ while (type_arg.IsBoundedType()) {
+ type_arg = BoundedType::Cast(type_arg).type();
+ }
+ while (other_type_arg.IsBoundedType()) {
+ other_type_arg = BoundedType::Cast(other_type_arg).type();
+ }
ASSERT(type_arg.IsEquivalent(other_type_arg, trail));
}
}
@@ -16973,13 +16991,20 @@ RawAbstractType* BoundedType::InstantiateFrom(
// Instantiated upper_bound may not be finalized. See comment above.
}
if (bound_error->IsNull()) {
- if (!type_param.CheckBound(bounded_type, upper_bound, bound_error) &&
- bound_error->IsNull()) {
+ if (bounded_type.IsBeingFinalized() ||
+ upper_bound.IsBeingFinalized() ||
+ (!type_param.CheckBound(bounded_type, upper_bound, bound_error) &&
+ bound_error->IsNull())) {
// We cannot determine yet whether the bounded_type is below the
- // upper_bound, because one or both of them is still uninstantiated.
- ASSERT(!bounded_type.IsInstantiated() || !upper_bound.IsInstantiated());
- // Postpone bound check by returning a new BoundedType with partially
- // instantiated bounded_type and upper_bound, but keeping type_param.
+ // upper_bound, because one or both of them is still being finalized or
+ // uninstantiated.
+ ASSERT(bounded_type.IsBeingFinalized() ||
+ upper_bound.IsBeingFinalized() ||
+ !bounded_type.IsInstantiated() ||
+ !upper_bound.IsInstantiated());
+ // Postpone bound check by returning a new BoundedType with unfinalized
+ // or partially instantiated bounded_type and upper_bound, but keeping
+ // type_param.
bounded_type = BoundedType::New(bounded_type, upper_bound, type_param);
}
}
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698