Skip to content

Commit e1c3988

Browse files
committed
Fix the SIL substitution of SubstitutionMaps to respect expansions
1 parent 01dac33 commit e1c3988

File tree

1 file changed

+74
-53
lines changed

1 file changed

+74
-53
lines changed

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 74 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)