Skip to content

Commit b41888a

Browse files
committed
AST: Add SubstitutionMap::subst()
This will replace Substitution::subst().
1 parent 61b6cc8 commit b41888a

File tree

3 files changed

+51
-9
lines changed

3 files changed

+51
-9
lines changed

include/swift/AST/SubstitutionMap.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,15 @@ class SubstitutionMap {
9393
/// Query whether any replacement type sin the map contain dynamic Self.
9494
bool hasDynamicSelf() const;
9595

96+
/// Apply a substitution to all replacement types in the map. Does not
97+
/// change keys.
98+
SubstitutionMap subst(const SubstitutionMap &subMap) const;
99+
100+
/// Apply a substitution to all replacement types in the map. Does not
101+
/// change keys.
102+
SubstitutionMap subst(TypeSubstitutionFn subs,
103+
LookupConformanceFn conformances) const;
104+
96105
/// Create a substitution map for a protocol conformance.
97106
static SubstitutionMap
98107
getProtocolSubstitutions(ProtocolDecl *protocol,

lib/AST/ProtocolConformance.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@ ProtocolConformance::subst(Type substType,
638638
subMap = genericSig->getSubstitutionMap(
639639
[&](SubstitutableType *t) -> Type {
640640
return genericEnv->mapTypeIntoContext(
641-
t).subst(subs, conformances);
641+
t).subst(subs, conformances, SubstFlags::UseErrorType);
642642
},
643643
[&](CanType origType, Type substType, ProtocolType *protoType)
644644
-> Optional<ProtocolConformanceRef> {
@@ -675,14 +675,15 @@ ProtocolConformance::subst(Type substType,
675675
case ProtocolConformanceKind::Specialized: {
676676
// Substitute the substitutions in the specialized conformance.
677677
auto spec = cast<SpecializedProtocolConformance>(this);
678-
SmallVector<Substitution, 8> newSubs;
679-
newSubs.reserve(spec->getGenericSubstitutions().size());
680-
for (auto &sub : spec->getGenericSubstitutions())
681-
newSubs.push_back(sub.subst(subs, conformances));
682-
678+
auto genericConformance
679+
= cast<SpecializedProtocolConformance>(this)->getGenericConformance();
680+
auto subMap =
681+
genericConformance->getGenericSignature()
682+
->getSubstitutionMap(spec->getGenericSubstitutions());
683+
683684
return substType->getASTContext()
684-
.getSpecializedConformance(substType, spec->getGenericConformance(),
685-
newSubs);
685+
.getSpecializedConformance(substType, genericConformance,
686+
subMap.subst(subs, conformances));
686687
}
687688
}
688689
llvm_unreachable("bad ProtocolConformanceKind");
@@ -713,7 +714,7 @@ ProtocolConformance::getInheritedConformance(ProtocolDecl *protocol) const {
713714
&& "substitution didn't produce conformance for same type?!");
714715
return r;
715716
}
716-
717+
717718
case ProtocolConformanceKind::Inherited: {
718719
auto classInherited = cast<InheritedProtocolConformance>(this);
719720
auto protoInherited = classInherited->getInheritedConformance()

lib/AST/SubstitutionMap.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,38 @@ addParent(CanType type, CanType parent, AssociatedTypeDecl *assocType) {
222222
parentMap[type.getPointer()].push_back(std::make_pair(parent, assocType));
223223
}
224224

225+
226+
SubstitutionMap SubstitutionMap::subst(const SubstitutionMap &subMap) const {
227+
return subst(QuerySubstitutionMap{subMap},
228+
LookUpConformanceInSubstitutionMap(subMap));
229+
}
230+
231+
SubstitutionMap SubstitutionMap::subst(TypeSubstitutionFn subs,
232+
LookupConformanceFn conformances) const {
233+
SubstitutionMap result(*this);
234+
235+
for (auto iter = result.subMap.begin(),
236+
end = result.subMap.end();
237+
iter != end; ++iter) {
238+
iter->second = iter->second.subst(subs, conformances,
239+
SubstFlags::UseErrorType);
240+
}
241+
242+
for (auto iter = result.conformanceMap.begin(),
243+
end = result.conformanceMap.end();
244+
iter != end; ++iter) {
245+
auto origType = Type(iter->first).subst(
246+
*this, SubstFlags::UseErrorType);
247+
for (auto citer = iter->second.begin(),
248+
cend = iter->second.end();
249+
citer != cend; ++citer) {
250+
*citer = citer->subst(origType, subs, conformances);
251+
}
252+
}
253+
254+
return result;
255+
}
256+
225257
SubstitutionMap
226258
SubstitutionMap::getProtocolSubstitutions(ProtocolDecl *protocol,
227259
Type selfType,

0 commit comments

Comments
 (0)