Skip to content

Commit de2f5f7

Browse files
committed
AST: Remove Substitution::subst()
I want to get rid of Substitution entirely, and now we have the right abstractions to do everything with SubstitutionMap.
1 parent 4c075ba commit de2f5f7

File tree

7 files changed

+37
-69
lines changed

7 files changed

+37
-69
lines changed

include/swift/AST/Substitution.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,6 @@ class Substitution {
5454
const PrintOptions &PO = PrintOptions()) const;
5555
void dump() const;
5656
void dump(llvm::raw_ostream &os, unsigned indent = 0) const;
57-
58-
/// Apply a substitution to this substitution's replacement type and
59-
/// conformances.
60-
Substitution subst(const SubstitutionMap &subMap) const;
61-
Substitution subst(TypeSubstitutionFn subs,
62-
LookupConformanceFn conformances) const;
63-
64-
private:
65-
friend class ProtocolConformance;
6657
};
6758

6859
} // end namespace swift

include/swift/AST/SubstitutionMap.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ class SubstitutionMap {
8787
/// Query whether any replacement types in the map contain archetypes.
8888
bool hasArchetypes() const;
8989

90+
/// Query whether any replacement types in the map contain an opened
91+
/// existential.
92+
bool hasOpenedExistential() const;
93+
9094
/// Query whether any replacement type sin the map contain dynamic Self.
9195
bool hasDynamicSelf() const;
9296

lib/AST/Substitution.cpp

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -42,44 +42,3 @@ Substitution::Substitution(Type Replacement,
4242
assert(Replacement->isMaterializable()
4343
&& "cannot substitute with a non-materializable type");
4444
}
45-
46-
Substitution Substitution::subst(const SubstitutionMap &subMap) const {
47-
return subst(QuerySubstitutionMap{subMap},
48-
LookUpConformanceInSubstitutionMap(subMap));
49-
}
50-
51-
Substitution Substitution::subst(TypeSubstitutionFn subs,
52-
LookupConformanceFn conformances) const {
53-
// Substitute the replacement.
54-
Type substReplacement = Replacement.subst(subs, conformances,
55-
SubstFlags::UseErrorType);
56-
assert(!substReplacement->hasError() &&
57-
"substitution replacement failed");
58-
59-
if (substReplacement->isEqual(Replacement))
60-
return *this;
61-
62-
if (Conformance.empty()) {
63-
return {substReplacement, Conformance};
64-
}
65-
66-
bool conformancesChanged = false;
67-
SmallVector<ProtocolConformanceRef, 4> substConformances;
68-
substConformances.reserve(Conformance.size());
69-
70-
for (auto c : Conformance) {
71-
auto newC = c.subst(Replacement, subs, conformances);
72-
if (c != newC)
73-
conformancesChanged = true;
74-
substConformances.push_back(newC);
75-
}
76-
assert(substConformances.size() == Conformance.size());
77-
78-
ArrayRef<ProtocolConformanceRef> substConfs;
79-
if (conformancesChanged)
80-
substConfs = Replacement->getASTContext().AllocateCopy(substConformances);
81-
else
82-
substConfs = Conformance;
83-
84-
return Substitution{substReplacement, substConfs};
85-
}

lib/AST/SubstitutionMap.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ bool SubstitutionMap::hasArchetypes() const {
3838
return false;
3939
}
4040

41+
bool SubstitutionMap::hasOpenedExistential() const {
42+
for (auto &entry : subMap)
43+
if (entry.second->hasOpenedExistential())
44+
return true;
45+
return false;
46+
}
47+
4148
bool SubstitutionMap::hasDynamicSelf() const {
4249
for (auto &entry : subMap)
4350
if (entry.second->hasDynamicSelfType())

lib/AST/Type.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2905,17 +2905,20 @@ static Type substType(Type derivedType,
29052905
if (boxTy->getGenericArgs().empty())
29062906
return Type(boxTy);
29072907

2908-
SmallVector<Substitution, 4> substArgs;
2909-
for (auto &arg : boxTy->getGenericArgs()) {
2910-
substArgs.push_back(arg.subst(substitutions, lookupConformances));
2911-
}
2912-
for (auto &arg : substArgs) {
2908+
auto subMap = boxTy->getLayout()->getGenericSignature()
2909+
->getSubstitutionMap(boxTy->getGenericArgs());
2910+
subMap = subMap.subst(substitutions, lookupConformances);
2911+
2912+
SmallVector<Substitution, 4> newSubs;
2913+
boxTy->getLayout()->getGenericSignature()
2914+
->getSubstitutions(subMap, newSubs);
2915+
for (auto &arg : newSubs) {
29132916
arg = Substitution(arg.getReplacement()->getCanonicalType(),
29142917
arg.getConformances());
29152918
}
29162919
return SILBoxType::get(boxTy->getASTContext(),
29172920
boxTy->getLayout(),
2918-
substArgs);
2921+
newSubs);
29192922
}
29202923

29212924
// We only substitute for substitutable types and dependent member types.

lib/SILGen/SILGenBridging.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,12 @@ emitBridgeNativeToObjectiveC(SILGenFunction &gen,
7979
GenericEnvironment *witnessEnv = witness.getSyntheticEnvironment();
8080
SubstitutionMap typeSubMap = witnessEnv
8181
->getSubstitutionMap(typeSubstitutions);
82-
for (auto sub : witnessSubstitutions) {
83-
substitutionsBuf.push_back(sub.subst(typeSubMap));
82+
SubstitutionMap witnessSubMap;
83+
if (auto *genericSig = cast<FuncDecl>(witness.getDecl())
84+
->getGenericSignature()) {
85+
witnessSubMap = genericSig->getSubstitutionMap(witnessSubstitutions);
86+
witnessSubMap = witnessSubMap.subst(typeSubMap);
87+
genericSig->getSubstitutions(witnessSubMap, substitutionsBuf);
8488
}
8589
substitutions = substitutionsBuf;
8690
}

lib/SILOptimizer/Transforms/PerformanceInliner.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -199,15 +199,14 @@ static bool calleeHasPartialApplyWithOpenedExistentials(FullApplySite AI) {
199199
auto PAISubs = PAI->getSubstitutions();
200200
if (PAISubs.empty())
201201
continue;
202+
202203
// Check if any of substitutions would contain open existentials
203204
// after inlining.
204-
for (auto PAISub : PAISubs) {
205-
if (!PAISub.getReplacement()->hasArchetype())
206-
continue;
207-
auto NewPAISub = PAISub.subst(SubsMap);
208-
if (NewPAISub.getReplacement()->hasOpenedExistential())
209-
return true;
210-
}
205+
auto PAISubMap = PAI->getOrigCalleeType()
206+
->getGenericSignature()->getSubstitutionMap(PAISubs);
207+
PAISubMap = PAISubMap.subst(SubsMap);
208+
if (PAISubMap.hasOpenedExistential())
209+
return true;
211210
}
212211
}
213212
}
@@ -405,11 +404,12 @@ bool SILPerformanceInliner::isProfitableToInline(FullApplySite AI,
405404

406405
// Create the list of substitutions as they will be after
407406
// inlining.
407+
auto Sig = FAI.getOrigCalleeType()->getGenericSignature();
408+
auto SubMap = Sig->getSubstitutionMap(Subs);
409+
SubMap = SubMap.subst(CalleeSubstMap);
410+
408411
SmallVector<Substitution, 4> NewSubs;
409-
for (auto Sub : Subs) {
410-
auto NewSub = Sub.subst(CalleeSubstMap);
411-
NewSubs.push_back(NewSub);
412-
}
412+
Sig->getSubstitutions(SubMap, NewSubs);
413413

414414
// Check if the call can be devirtualized.
415415
if (isa<ClassMethodInst>(def) || isa<WitnessMethodInst>(def) ||

0 commit comments

Comments
 (0)