@@ -20121,12 +20121,27 @@ TypeParameterPtr TypeParameter::ToNullability(Nullability value,
2012120121bool TypeParameter::IsInstantiated(Genericity genericity,
2012220122 intptr_t num_free_fun_type_params,
2012320123 TrailPtr trail) const {
20124+ // Bounds of class type parameters are ignored in the VM.
2012420125 if (IsClassTypeParameter()) {
2012520126 return genericity == kFunctions;
2012620127 }
2012720128 ASSERT(IsFunctionTypeParameter());
2012820129 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;
2013020145}
2013120146
2013220147bool TypeParameter::IsEquivalent(const Instance& other,
@@ -20264,40 +20279,57 @@ AbstractTypePtr TypeParameter::InstantiateFrom(
2026420279 Heap::Space space,
2026520280 TrailPtr trail) const {
2026620281 ASSERT(IsFinalized());
20282+ AbstractType& result = AbstractType::Handle();
2026720283 if (IsFunctionTypeParameter()) {
2026820284 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());
2027120310 }
20272- if (function_type_arguments.IsNull()) {
20311+ } else {
20312+ ASSERT(IsClassTypeParameter());
20313+ if (instantiator_type_arguments.IsNull()) {
2027320314 return Type::DynamicType();
2027420315 }
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.
2029220329 }
20293- AbstractType& result =
20294- AbstractType::Handle(instantiator_type_arguments.TypeAt(index()));
2029520330 result = result.SetInstantiatedNullability(*this, space);
20331+ // Canonicalization is not part of instantiation.
2029620332 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.
2030120333}
2030220334
2030320335AbstractTypePtr TypeParameter::Canonicalize(TrailPtr trail) const {
0 commit comments