@@ -4138,22 +4138,6 @@ class SILTypeSubstituter :
41384138 return substSILFunctionType (origType, false );
41394139 }
41404140
4141- SubstitutionMap substSubstitutions (SubstitutionMap subs) {
4142- // Substitute the substitutions.
4143- SubstOptions options = None;
4144- if (shouldSubstituteOpaqueArchetypes)
4145- options |= SubstFlags::SubstituteOpaqueArchetypes;
4146-
4147- // Expand substituted type according to the expansion context.
4148- auto newSubs = subs.subst (Subst, Conformances, options);
4149-
4150- // If we need to look through opaque types in this context, re-substitute
4151- // according to the expansion context.
4152- newSubs = substOpaqueTypes (newSubs);
4153-
4154- return newSubs;
4155- }
4156-
41574141 SubstitutionMap substOpaqueTypes (SubstitutionMap subs) {
41584142 if (!typeExpansionContext.shouldLookThroughOpaqueTypeArchetypes ())
41594143 return subs;
@@ -4572,6 +4556,54 @@ class SILTypeSubstituter :
45724556 substType);
45734557 }
45744558
4559+ struct SubstRespectingExpansions {
4560+ SILTypeSubstituter *_this;
4561+ SubstRespectingExpansions (SILTypeSubstituter *_this) : _this(_this) {}
4562+
4563+ Type operator ()(SubstitutableType *origType) const {
4564+ auto substType = _this->Subst (origType);
4565+ if (!substType) return substType;
4566+ auto substPackType = dyn_cast<PackType>(substType->getCanonicalType ());
4567+ if (!substPackType) return substType;
4568+ auto activeExpansion = _this->getActivePackExpansion (CanType (origType));
4569+ if (!activeExpansion) return substType;
4570+ auto substEltType =
4571+ substPackType.getElementType (activeExpansion->Index );
4572+ auto substExpansion = dyn_cast<PackExpansionType>(substEltType);
4573+ assert ((bool ) substExpansion ==
4574+ (bool ) activeExpansion->SubstPackExpansionCount );
4575+ if (substExpansion) {
4576+ assert (_this->hasSameShape (substExpansion.getCountType (),
4577+ activeExpansion->SubstPackExpansionCount ));
4578+ return substExpansion.getPatternType ();
4579+ }
4580+ return substEltType;
4581+ }
4582+ };
4583+
4584+ struct SubstConformanceRespectingExpansions {
4585+ SILTypeSubstituter *_this;
4586+ SubstConformanceRespectingExpansions (SILTypeSubstituter *_this)
4587+ : _this(_this) {}
4588+
4589+ ProtocolConformanceRef operator ()(CanType dependentType,
4590+ Type conformingReplacementType,
4591+ ProtocolDecl *conformingProtocol) const {
4592+ auto conformance = _this->Conformances (dependentType,
4593+ conformingReplacementType,
4594+ conformingProtocol);
4595+ if (!conformance || !conformance.isPack ()) return conformance;
4596+ auto activeExpansion = _this->getActivePackExpansion (dependentType);
4597+ if (!activeExpansion) return conformance;
4598+ auto pack = conformance.getPack ();
4599+ auto substEltConf =
4600+ pack->getPatternConformances ()[activeExpansion->Index ];
4601+ // There isn't currently a ProtocolConformanceExpansion that
4602+ // we would need to look through here.
4603+ return substEltConf;
4604+ };
4605+ };
4606+
45754607 CanType substASTType (CanType origType) {
45764608 SubstOptions substOptions (None);
45774609 if (shouldSubstituteOpaqueArchetypes)
@@ -4582,43 +4614,32 @@ class SILTypeSubstituter :
45824614 return origType.subst (Subst, Conformances, substOptions)
45834615 ->getCanonicalType ();
45844616
4585- return origType.subst (
4586- [&](SubstitutableType *origType) -> Type {
4587- auto substType = Subst (origType);
4588- if (!substType) return substType;
4589- auto substPackType = dyn_cast<PackType>(substType->getCanonicalType ());
4590- if (!substPackType) return substType;
4591- auto activeExpansion = getActivePackExpansion (CanType (origType));
4592- if (!activeExpansion) return substType;
4593- auto substEltType =
4594- substPackType.getElementType (activeExpansion->Index );
4595- auto substExpansion = dyn_cast<PackExpansionType>(substEltType);
4596- assert ((bool ) substExpansion ==
4597- (bool ) activeExpansion->SubstPackExpansionCount );
4598- if (substExpansion) {
4599- assert (hasSameShape (substExpansion.getCountType (),
4600- activeExpansion->SubstPackExpansionCount ));
4601- return substExpansion.getPatternType ();
4602- }
4603- return substEltType;
4604- },
4605- [&](CanType dependentType,
4606- Type conformingReplacementType,
4607- ProtocolDecl *conformingProtocol) -> ProtocolConformanceRef {
4608- auto conformance = Conformances (dependentType,
4609- conformingReplacementType,
4610- conformingProtocol);
4611- if (!conformance || !conformance.isPack ()) return conformance;
4612- auto activeExpansion = getActivePackExpansion (dependentType);
4613- if (!activeExpansion) return conformance;
4614- auto pack = conformance.getPack ();
4615- auto substEltConf =
4616- pack->getPatternConformances ()[activeExpansion->Index ];
4617- // There isn't currently a ProtocolConformanceExpansion that
4618- // we would need to look through here.
4619- return substEltConf;
4620- },
4621- substOptions)->getCanonicalType ();
4617+ return origType.subst (SubstRespectingExpansions (this ),
4618+ SubstConformanceRespectingExpansions (this ),
4619+ substOptions)->getCanonicalType ();
4620+ }
4621+
4622+ SubstitutionMap substSubstitutions (SubstitutionMap subs) {
4623+ // Substitute the substitutions.
4624+ SubstOptions options = None;
4625+ if (shouldSubstituteOpaqueArchetypes)
4626+ options |= SubstFlags::SubstituteOpaqueArchetypes;
4627+
4628+ // Expand substituted type according to the expansion context.
4629+ SubstitutionMap newSubs;
4630+
4631+ if (ActivePackExpansions.empty ())
4632+ newSubs = subs.subst (Subst, Conformances, options);
4633+ else
4634+ newSubs = subs.subst (SubstRespectingExpansions (this ),
4635+ SubstConformanceRespectingExpansions (this ),
4636+ options);
4637+
4638+ // If we need to look through opaque types in this context, re-substitute
4639+ // according to the expansion context.
4640+ newSubs = substOpaqueTypes (newSubs);
4641+
4642+ return newSubs;
46224643 }
46234644
46244645 PackExpansion *getActivePackExpansion (CanType dependentType) {
0 commit comments