@@ -4138,22 +4138,6 @@ class SILTypeSubstituter :
4138
4138
return substSILFunctionType (origType, false );
4139
4139
}
4140
4140
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
-
4157
4141
SubstitutionMap substOpaqueTypes (SubstitutionMap subs) {
4158
4142
if (!typeExpansionContext.shouldLookThroughOpaqueTypeArchetypes ())
4159
4143
return subs;
@@ -4572,6 +4556,54 @@ class SILTypeSubstituter :
4572
4556
substType);
4573
4557
}
4574
4558
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
+
4575
4607
CanType substASTType (CanType origType) {
4576
4608
SubstOptions substOptions (None);
4577
4609
if (shouldSubstituteOpaqueArchetypes)
@@ -4582,43 +4614,32 @@ class SILTypeSubstituter :
4582
4614
return origType.subst (Subst, Conformances, substOptions)
4583
4615
->getCanonicalType ();
4584
4616
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;
4622
4643
}
4623
4644
4624
4645
PackExpansion *getActivePackExpansion (CanType dependentType) {
0 commit comments