Skip to content

Commit f0300be

Browse files
authored
Merge pull request #7884 from slavapestov/remove-get-all-dependent-types
AST: Remove GenericSignature::getAllDependentTypes()
2 parents 9f62e55 + 0f4a7d2 commit f0300be

File tree

12 files changed

+151
-156
lines changed

12 files changed

+151
-156
lines changed

include/swift/AST/GenericEnvironment.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,8 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
242242

243243
SubstitutionList getForwardingSubstitutions() const;
244244

245+
void dump(raw_ostream &os) const;
246+
245247
void dump() const;
246248
};
247249

include/swift/AST/GenericSignature.h

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,6 @@ class alignas(1 << TypeAlignInBits) GenericSignature final
123123
return const_cast<GenericSignature *>(this)->getRequirementsBuffer();
124124
}
125125

126-
/// Check if the generic signature makes all generic parameters
127-
/// concrete.
128-
bool areAllParamsConcrete() const {
129-
auto iter = getAllDependentTypes();
130-
return iter.begin() == iter.end();
131-
}
132-
133126
/// Only allow allocation by doing a placement new.
134127
void *operator new(size_t Bytes, void *Mem) {
135128
assert(Mem);
@@ -174,11 +167,6 @@ class alignas(1 << TypeAlignInBits) GenericSignature final
174167
void getSubstitutions(const SubstitutionMap &subMap,
175168
SmallVectorImpl<Substitution> &result) const;
176169

177-
/// Return a range that iterates through all of the types that require
178-
/// substitution, which includes the generic parameter types as well as
179-
/// other dependent types that require additional conformances.
180-
SmallVector<Type, 4> getAllDependentTypes() const;
181-
182170
/// Enumerate all of the dependent types in the type signature that will
183171
/// occur in substitution lists (in order), along with the set of
184172
/// conformance requirements placed on that dependent type.
@@ -191,6 +179,33 @@ class alignas(1 << TypeAlignInBits) GenericSignature final
191179
bool enumeratePairedRequirements(
192180
llvm::function_ref<bool(Type, ArrayRef<Requirement>)> fn) const;
193181

182+
/// Return a vector of all generic parameters that are not subject to
183+
/// a concrete same-type constraint.
184+
SmallVector<GenericTypeParamType *, 2> getSubstitutableParams() const;
185+
186+
/// Check if the generic signature makes all generic parameters
187+
/// concrete.
188+
bool areAllParamsConcrete() const {
189+
return !enumeratePairedRequirements(
190+
[](Type, ArrayRef<Requirement>) -> bool {
191+
return true;
192+
});
193+
}
194+
195+
/// Return the size of a SubstitutionList built from this signature.
196+
///
197+
/// Don't add new calls of this -- the representation of SubstitutionList
198+
/// will be changing soon.
199+
unsigned getSubstitutionListSize() const {
200+
unsigned result = 0;
201+
enumeratePairedRequirements(
202+
[&](Type, ArrayRef<Requirement>) -> bool {
203+
result++;
204+
return false;
205+
});
206+
return result;
207+
}
208+
194209
/// Determines whether this GenericSignature is canonical.
195210
bool isCanonical() const;
196211

lib/AST/ASTDumper.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3117,13 +3117,17 @@ void TypeBase::dump(raw_ostream &os, unsigned indent) const {
31173117
Type(const_cast<TypeBase *>(this)).dump(os, indent);
31183118
}
31193119

3120-
void GenericEnvironment::dump() const {
3121-
llvm::errs() << "Generic environment:\n";
3120+
void GenericEnvironment::dump(raw_ostream &os) const {
3121+
os << "Generic environment:\n";
31223122
for (auto gp : getGenericParams()) {
3123-
gp->dump();
3124-
mapTypeIntoContext(gp)->dump();
3123+
gp->dump(os);
3124+
mapTypeIntoContext(gp)->dump(os);
31253125
}
3126-
llvm::errs() << "Generic parameters:\n";
3126+
os << "Generic parameters:\n";
31273127
for (auto paramTy : getGenericParams())
3128-
paramTy->dump();
3128+
paramTy->dump(os);
3129+
}
3130+
3131+
void GenericEnvironment::dump() const {
3132+
dump(llvm::errs());
31293133
}

lib/AST/GenericEnvironment.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -395,25 +395,27 @@ SubstitutionMap GenericEnvironment::
395395
getSubstitutionMap(SubstitutionList subs) const {
396396
SubstitutionMap result;
397397

398-
for (auto depTy : getGenericSignature()->getAllDependentTypes()) {
399-
400-
// Map the interface type to a context type.
401-
auto contextTy = depTy.subst(QueryInterfaceTypeSubstitutions(this),
402-
MakeAbstractConformanceForGenericType());
398+
getGenericSignature()->enumeratePairedRequirements(
399+
[&](Type depTy, ArrayRef<Requirement> reqts) -> bool {
400+
// Map the interface type to a context type.
401+
auto contextTy = depTy.subst(QueryInterfaceTypeSubstitutions(this),
402+
MakeAbstractConformanceForGenericType());
403403

404-
auto sub = subs.front();
405-
subs = subs.slice(1);
404+
auto sub = subs.front();
405+
subs = subs.slice(1);
406406

407-
// Record the replacement type and its conformances.
408-
if (auto *archetype = contextTy->getAs<ArchetypeType>()) {
409-
result.addSubstitution(CanArchetypeType(archetype), sub.getReplacement());
410-
for (auto conformance : sub.getConformances())
411-
result.addConformance(CanType(archetype), conformance);
412-
continue;
413-
}
407+
// Record the replacement type and its conformances.
408+
if (auto *archetype = contextTy->getAs<ArchetypeType>()) {
409+
result.addSubstitution(CanArchetypeType(archetype), sub.getReplacement());
410+
assert(reqts.size() == sub.getConformances().size());
411+
for (auto conformance : sub.getConformances())
412+
result.addConformance(CanType(archetype), conformance);
413+
return false;
414+
}
414415

415-
assert(contextTy->hasError());
416-
}
416+
assert(contextTy->hasError());
417+
return false;
418+
});
417419

418420
assert(subs.empty() && "did not use all substitutions?!");
419421

lib/AST/GenericSignature.cpp

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,20 @@ GenericSignature::getInnermostGenericParams() const {
7878
return params;
7979
}
8080

81+
82+
SmallVector<GenericTypeParamType *, 2>
83+
GenericSignature::getSubstitutableParams() const {
84+
SmallVector<GenericTypeParamType *, 2> result;
85+
86+
enumeratePairedRequirements([&](Type depTy, ArrayRef<Requirement>) -> bool {
87+
if (auto *paramTy = depTy->getAs<GenericTypeParamType>())
88+
result.push_back(paramTy);
89+
return false;
90+
});
91+
92+
return result;
93+
}
94+
8195
std::string GenericSignature::gatherGenericParamBindingsText(
8296
ArrayRef<Type> types, TypeSubstitutionFn substitutions) const {
8397
llvm::SmallPtrSet<GenericTypeParamType *, 2> knownGenericParams;
@@ -375,21 +389,21 @@ SubstitutionMap
375389
GenericSignature::getSubstitutionMap(SubstitutionList subs) const {
376390
SubstitutionMap result;
377391

378-
// An empty parameter list gives an empty map.
379-
if (subs.empty())
380-
assert(getGenericParams().empty() || areAllParamsConcrete());
392+
enumeratePairedRequirements(
393+
[&](Type depTy, ArrayRef<Requirement> reqts) -> bool {
394+
auto sub = subs.front();
395+
subs = subs.slice(1);
381396

382-
for (auto depTy : getAllDependentTypes()) {
383-
auto sub = subs.front();
384-
subs = subs.slice(1);
397+
auto canTy = depTy->getCanonicalType();
398+
if (isa<SubstitutableType>(canTy))
399+
result.addSubstitution(cast<SubstitutableType>(canTy),
400+
sub.getReplacement());
401+
assert(reqts.size() == sub.getConformances().size());
402+
for (auto conformance : sub.getConformances())
403+
result.addConformance(canTy, conformance);
385404

386-
auto canTy = depTy->getCanonicalType();
387-
if (isa<SubstitutableType>(canTy))
388-
result.addSubstitution(cast<SubstitutableType>(canTy),
389-
sub.getReplacement());
390-
for (auto conformance : sub.getConformances())
391-
result.addConformance(canTy, conformance);
392-
}
405+
return false;
406+
});
393407

394408
assert(subs.empty() && "did not use all substitutions?!");
395409
populateParentMap(result);
@@ -430,16 +444,6 @@ getSubstitutionMap(TypeSubstitutionFn subs,
430444
return subMap;
431445
}
432446

433-
SmallVector<Type, 4> GenericSignature::getAllDependentTypes() const {
434-
SmallVector<Type, 4> result;
435-
enumeratePairedRequirements([&](Type type, ArrayRef<Requirement>) {
436-
result.push_back(type);
437-
return false;
438-
});
439-
440-
return result;
441-
}
442-
443447
void GenericSignature::
444448
getSubstitutions(const TypeSubstitutionMap &subs,
445449
GenericSignature::LookupConformanceFn lookupConformance,

lib/Parse/ParseSIL.cpp

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,41 +1448,41 @@ bool getApplySubstitutionsFromParsed(
14481448

14491449
auto loc = parses[0].loc;
14501450

1451-
// Collect conformance requirements in a convenient form.
1452-
llvm::DenseMap<TypeBase *, SmallVector<ProtocolDecl *, 2>> conformsTo;
1453-
for (auto reqt : env->getGenericSignature()->getRequirements()) {
1454-
if (reqt.getKind() == RequirementKind::Conformance) {
1455-
auto canTy = reqt.getFirstType()->getCanonicalType();
1456-
auto nominal = reqt.getSecondType()->getAnyNominal();
1457-
conformsTo[canTy.getPointer()].push_back(cast<ProtocolDecl>(nominal));
1458-
}
1459-
}
1460-
14611451
// The replacement is for the corresponding dependent type by ordering.
1462-
for (auto depTy : env->getGenericSignature()->getAllDependentTypes()) {
1452+
auto result = env->getGenericSignature()->enumeratePairedRequirements(
1453+
[&](Type depTy, ArrayRef<Requirement> reqts) -> bool {
1454+
if (parses.empty()) {
1455+
SP.P.diagnose(loc, diag::sil_missing_substitutions);
1456+
return true;
1457+
}
1458+
auto parsed = parses.front();
1459+
parses = parses.slice(1);
1460+
1461+
SmallVector<ProtocolConformanceRef, 2> conformances;
1462+
SmallVector<ProtocolDecl *, 2> protocols;
1463+
for (auto reqt : reqts) {
1464+
protocols.push_back(reqt.getSecondType()
1465+
->castTo<ProtocolType>()->getDecl());
1466+
}
14631467

1464-
auto canTy = depTy->getCanonicalType().getPointer();
1468+
if (getConformancesForSubstitution(SP.P, protocols,
1469+
parsed.replacement,
1470+
parsed.loc, conformances))
1471+
return true;
14651472

1466-
if (parses.empty()) {
1467-
SP.P.diagnose(loc, diag::sil_missing_substitutions);
1468-
return true;
1469-
}
1470-
auto parsed = parses.front();
1471-
parses = parses.slice(1);
1473+
subs.push_back({parsed.replacement,
1474+
SP.P.Context.AllocateCopy(conformances)});
1475+
return false;
1476+
});
14721477

1473-
SmallVector<ProtocolConformanceRef, 2> conformances;
1474-
if (getConformancesForSubstitution(SP.P, conformsTo[canTy],
1475-
parsed.replacement,
1476-
parsed.loc, conformances))
1477-
return true;
1478+
if (result)
1479+
return true;
14781480

1479-
subs.push_back({parsed.replacement,
1480-
SP.P.Context.AllocateCopy(conformances)});
1481-
}
14821481
if (!parses.empty()) {
14831482
SP.P.diagnose(loc, diag::sil_too_many_substitutions);
14841483
return true;
14851484
}
1485+
14861486
return false;
14871487
}
14881488

lib/SIL/Mangle.cpp

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/AST/Mangle.h"
2222
#include "swift/AST/Module.h"
2323
#include "swift/AST/ProtocolConformance.h"
24+
#include "swift/AST/SubstitutionMap.h"
2425
#include "swift/Basic/Punycode.h"
2526
#include "swift/SIL/SILArgument.h"
2627
#include "swift/SIL/SILType.h"
@@ -44,33 +45,21 @@ using namespace Mangle;
4445
// Generic Specialization
4546
//===----------------------------------------------------------------------===//
4647

47-
static void mangleSubstitution(Mangler &M, Substitution Sub) {
48-
M.mangleType(Sub.getReplacement()->getCanonicalType(), 0);
49-
for (auto C : Sub.getConformances()) {
50-
if (C.isAbstract())
51-
return;
52-
M.mangleProtocolConformance(C.getConcrete());
53-
}
54-
}
55-
5648
void GenericSpecializationMangler::mangleSpecialization() {
5749
Mangler &M = getMangler();
5850
// This is a full specialization.
5951
SILFunctionType *FTy = Function->getLoweredFunctionType();
6052
CanGenericSignature Sig = FTy->getGenericSignature();
61-
62-
unsigned idx = 0;
63-
for (Type DepType : Sig->getAllDependentTypes()) {
64-
// It is sufficient to only mangle the substitutions of the "primary"
65-
// dependent types. As all other dependent types are just derived from the
66-
// primary types, this will give us unique symbol names.
67-
if (DepType->is<GenericTypeParamType>()) {
68-
mangleSubstitution(M, Subs[idx]);
69-
M.append('_');
53+
auto SubMap = Sig->getSubstitutionMap(Subs);
54+
for (Type DepType : Sig->getSubstitutableParams()) {
55+
M.mangleType(DepType.subst(SubMap)->getCanonicalType(), 0);
56+
for (auto C : SubMap.getConformances(DepType->getCanonicalType())) {
57+
if (C.isAbstract())
58+
return;
59+
M.mangleProtocolConformance(C.getConcrete());
7060
}
71-
++idx;
61+
M.append('_');
7262
}
73-
assert(idx == Subs.size() && "subs not parallel to dependent types");
7463
}
7564

7665
void PartialSpecializationMangler::mangleSpecialization() {

0 commit comments

Comments
 (0)