| 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;
|
| }
|
|
|