Index: runtime/vm/class_finalizer.cc |
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc |
index d8434d9fd4d81fddde2495c494a87137a7a1c43d..9ca3731ef3d2728be12d3b23f7297196db9ae9ff 100644 |
--- a/runtime/vm/class_finalizer.cc |
+++ b/runtime/vm/class_finalizer.cc |
@@ -1269,7 +1269,8 @@ void ClassFinalizer::FinalizeUpperBounds(const Class& cls) { |
for (intptr_t i = 0; i < num_type_params; i++) { |
type_param ^= type_params.TypeAt(i); |
bound = type_param.bound(); |
- if (bound.IsFinalized() || bound.IsBeingFinalized()) { |
+ // Bound may be finalized, but not canonical yet. |
+ if (bound.IsCanonical() || bound.IsBeingFinalized()) { |
// A bound involved in F-bounded quantification may form a cycle. |
continue; |
} |
@@ -2231,7 +2232,10 @@ void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { |
FinalizeTypeParameters(cls); // May change super type. |
super_class = cls.SuperClass(); |
ASSERT(super_class.IsNull() || super_class.is_type_finalized()); |
- ResolveUpperBounds(cls); |
+ // Only resolving rather than finalizing the upper bounds here would result in |
+ // instantiated type parameters of the super type to temporarily have |
+ // unfinalized bounds. It is more efficient to finalize them early. |
+ FinalizeUpperBounds(cls); |
// Finalize super type. |
AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
if (!super_type.IsNull()) { |
@@ -2344,6 +2348,7 @@ void ClassFinalizer::FinalizeTypesInClass(const Class& cls) { |
void ClassFinalizer::FinalizeClass(const Class& cls) { |
Thread* thread = Thread::Current(); |
HANDLESCOPE(thread); |
+ ASSERT(cls.is_type_finalized()); |
if (cls.is_finalized()) { |
return; |
} |