@@ -20121,12 +20121,27 @@ TypeParameterPtr TypeParameter::ToNullability(Nullability value,
20121
20121
bool TypeParameter::IsInstantiated(Genericity genericity,
20122
20122
intptr_t num_free_fun_type_params,
20123
20123
TrailPtr trail) const {
20124
+ // Bounds of class type parameters are ignored in the VM.
20124
20125
if (IsClassTypeParameter()) {
20125
20126
return genericity == kFunctions;
20126
20127
}
20127
20128
ASSERT(IsFunctionTypeParameter());
20128
20129
ASSERT(IsFinalized());
20129
- return (genericity == kCurrentClass) || (index() >= num_free_fun_type_params);
20130
+ if ((genericity != kCurrentClass) && (index() < num_free_fun_type_params)) {
20131
+ return false;
20132
+ }
20133
+ // Although the type parameter is instantiated, its bound may not be.
20134
+ const AbstractType& upper_bound = AbstractType::Handle(bound());
20135
+ if (upper_bound.IsTypeParameter() ||
20136
+ upper_bound.arguments() != TypeArguments::null()) {
20137
+ // Use trail to break cycles created by bound referring to type parameter.
20138
+ if (!TestAndAddToTrail(&trail) &&
20139
+ !upper_bound.IsInstantiated(genericity, num_free_fun_type_params,
20140
+ trail)) {
20141
+ return false;
20142
+ }
20143
+ }
20144
+ return true;
20130
20145
}
20131
20146
20132
20147
bool TypeParameter::IsEquivalent(const Instance& other,
@@ -20264,40 +20279,57 @@ AbstractTypePtr TypeParameter::InstantiateFrom(
20264
20279
Heap::Space space,
20265
20280
TrailPtr trail) const {
20266
20281
ASSERT(IsFinalized());
20282
+ AbstractType& result = AbstractType::Handle();
20267
20283
if (IsFunctionTypeParameter()) {
20268
20284
if (index() >= num_free_fun_type_params) {
20269
- // Return uninstantiated type parameter unchanged.
20270
- return raw();
20285
+ // Do not instantiate the function type parameter, but possibly its bound.
20286
+ result = raw();
20287
+ AbstractType& upper_bound = AbstractType::Handle(bound());
20288
+ if (!upper_bound.IsInstantiated(kAny, num_free_fun_type_params,
20289
+ nullptr)) {
20290
+ // Use trail to break cycles created by bound referring to type param.
20291
+ if (OnlyBuddyInTrail(trail) == Object::null()) {
20292
+ AddOnlyBuddyToTrail(&trail, *this);
20293
+ upper_bound = upper_bound.InstantiateFrom(
20294
+ instantiator_type_arguments, function_type_arguments,
20295
+ num_free_fun_type_params, space, trail);
20296
+ if (upper_bound.raw() == Type::NeverType()) {
20297
+ // Normalize 'X extends Never' to 'Never'.
20298
+ result = Type::NeverType();
20299
+ } else if (upper_bound.raw() != bound()) {
20300
+ result ^= Object::Clone(result, space);
20301
+ TypeParameter::Cast(result).set_bound(upper_bound);
20302
+ }
20303
+ }
20304
+ }
20305
+ } else if (function_type_arguments.IsNull()) {
20306
+ return Type::DynamicType();
20307
+ } else {
20308
+ result = function_type_arguments.TypeAt(index());
20309
+ ASSERT(!result.IsTypeParameter());
20271
20310
}
20272
- if (function_type_arguments.IsNull()) {
20311
+ } else {
20312
+ ASSERT(IsClassTypeParameter());
20313
+ if (instantiator_type_arguments.IsNull()) {
20273
20314
return Type::DynamicType();
20274
20315
}
20275
- AbstractType& result =
20276
- AbstractType::Handle(function_type_arguments.TypeAt(index()));
20277
- result = result.SetInstantiatedNullability(*this, space);
20278
- return result.NormalizeFutureOrType(space);
20279
- }
20280
- ASSERT(IsClassTypeParameter());
20281
- if (instantiator_type_arguments.IsNull()) {
20282
- return Type::DynamicType();
20283
- }
20284
- if (instantiator_type_arguments.Length() <= index()) {
20285
- // InstantiateFrom can be invoked from a compilation pipeline with
20286
- // mismatching type arguments vector. This can only happen for
20287
- // a dynamically unreachable code - which compiler can't remove
20288
- // statically for some reason.
20289
- // To prevent crashes we return AbstractType::null(), understood by caller
20290
- // (see AssertAssignableInstr::Canonicalize).
20291
- return AbstractType::null();
20316
+ if (instantiator_type_arguments.Length() <= index()) {
20317
+ // InstantiateFrom can be invoked from a compilation pipeline with
20318
+ // mismatching type arguments vector. This can only happen for
20319
+ // a dynamically unreachable code - which compiler can't remove
20320
+ // statically for some reason.
20321
+ // To prevent crashes we return AbstractType::null(), understood by caller
20322
+ // (see AssertAssignableInstr::Canonicalize).
20323
+ return AbstractType::null();
20324
+ }
20325
+ result = instantiator_type_arguments.TypeAt(index());
20326
+ // Instantiating a class type parameter cannot result in a
20327
+ // function type parameter.
20328
+ // Bounds of class type parameters are ignored in the VM.
20292
20329
}
20293
- AbstractType& result =
20294
- AbstractType::Handle(instantiator_type_arguments.TypeAt(index()));
20295
20330
result = result.SetInstantiatedNullability(*this, space);
20331
+ // Canonicalization is not part of instantiation.
20296
20332
return result.NormalizeFutureOrType(space);
20297
- // There is no need to canonicalize the instantiated type parameter, since all
20298
- // type arguments are canonicalized at type finalization time. It would be too
20299
- // early to canonicalize the returned type argument here, since instantiation
20300
- // not only happens at run time, but also during type finalization.
20301
20333
}
20302
20334
20303
20335
AbstractTypePtr TypeParameter::Canonicalize(TrailPtr trail) const {
0 commit comments