Skip to content

Commit 3e031ff

Browse files
committed
AST: Add "re-sugaring" to GenericEnvironment
Sugared GenericTypeParamTypes point to GenericTypeParamDecls, allowing the name of the parameter as written by the user to be recovered. Canonical GenericTypeParamTypes on the other hand only store a depth and index, without referencing the original declaration. When printing SIL, we wish to output the original generic parameter names, even though SIL only uses canonical types. Previously, we used to accomplish this by mapping the generic parameter to an archetype and printing the name of the archetype. This was not adequate if multiple generic parameters mapped to the same archetype, or if a generic parameter was mapped to a concrete type. The new approach preserves the original sugared types in the GenericEnvironment, adding a new GenericEnvironment::getSugaredType() method. There are also some other assorted simplifications made possible by this. Unfortunately this makes GenericEnvironments use a bit more memory, however I have more improvements coming that will offset the gains, in addition to making substitution lists smaller also.
1 parent a989e99 commit 3e031ff

18 files changed

+140
-134
lines changed

include/swift/AST/ArchetypeBuilder.h

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -254,21 +254,11 @@ class ArchetypeBuilder {
254254
GenericEnvironment *genericEnv,
255255
bool treatRequirementsAsExplicit = false);
256256

257-
/// \brief Get a generic signature based on the provided complete list
258-
/// of generic parameter types.
259-
///
260-
/// \returns a generic signature built from the provided list of
261-
/// generic parameter types.
262-
GenericSignature *
263-
getGenericSignature(ArrayRef<GenericTypeParamType *> genericParamsTypes);
257+
/// \brief Build the generic signature.
258+
GenericSignature *getGenericSignature();
264259

265-
/// \brief Get a generic context based on the complete list of generic
266-
/// parameter types.
267-
///
268-
/// \returns a generic context built from the provided list of
269-
/// generic parameter types.
270-
GenericEnvironment *getGenericEnvironment(
271-
ArrayRef<GenericTypeParamType *> genericParamsTypes);
260+
/// \brief Build the generic environment.
261+
GenericEnvironment *getGenericEnvironment();
272262

273263
/// Infer requirements from the given type, recursively.
274264
///

include/swift/AST/GenericEnvironment.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,15 @@ class GenericTypeParamType;
2828
/// Describes the mapping between archetypes and interface types for the
2929
/// generic parameters of a DeclContext.
3030
class GenericEnvironment final {
31+
SmallVector<GenericTypeParamType *, 4> GenericParams;
3132
TypeSubstitutionMap ArchetypeToInterfaceMap;
3233
TypeSubstitutionMap InterfaceToArchetypeMap;
3334

3435
public:
36+
ArrayRef<GenericTypeParamType *> getGenericParams() const {
37+
return GenericParams;
38+
}
39+
3540
const TypeSubstitutionMap &getArchetypeToInterfaceMap() const {
3641
return ArchetypeToInterfaceMap;
3742
}
@@ -40,10 +45,13 @@ class GenericEnvironment final {
4045
return InterfaceToArchetypeMap;
4146
}
4247

43-
explicit GenericEnvironment(TypeSubstitutionMap interfaceToArchetypeMap);
48+
GenericEnvironment(ArrayRef<GenericTypeParamType *> genericParamTypes,
49+
TypeSubstitutionMap interfaceToArchetypeMap);
4450

45-
static GenericEnvironment *get(ASTContext &ctx,
46-
TypeSubstitutionMap interfaceToArchetypeMap);
51+
static
52+
GenericEnvironment * get(ASTContext &ctx,
53+
ArrayRef<GenericTypeParamType *> genericParamTypes,
54+
TypeSubstitutionMap interfaceToArchetypeMap);
4755

4856
/// Make vanilla new/delete illegal.
4957
void *operator new(size_t Bytes) = delete;
@@ -62,6 +70,9 @@ class GenericEnvironment final {
6270
/// Map a generic parameter type to a contextual type.
6371
Type mapTypeIntoContext(GenericTypeParamType *type) const;
6472

73+
/// Get the sugared form of a generic parameter type.
74+
GenericTypeParamType *getSugaredType(GenericTypeParamType *type) const;
75+
6576
/// Derive a contextual type substitution map from a substitution array.
6677
/// This is just like GenericSignature::getSubstitutionMap(), except
6778
/// with contextual types instead of interface types.

lib/AST/ASTContext.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3559,8 +3559,10 @@ GenericSignature *GenericSignature::get(ArrayRef<GenericTypeParamType *> params,
35593559

35603560
GenericEnvironment *
35613561
GenericEnvironment::get(ASTContext &ctx,
3562+
ArrayRef<GenericTypeParamType *> genericParamTypes,
35623563
TypeSubstitutionMap interfaceToArchetypeMap) {
3563-
return new (ctx) GenericEnvironment(interfaceToArchetypeMap);
3564+
return new (ctx) GenericEnvironment(genericParamTypes,
3565+
interfaceToArchetypeMap);
35643566
}
35653567

35663568
void DeclName::CompoundDeclName::Profile(llvm::FoldingSetNodeID &id,

lib/AST/ASTDumper.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3082,4 +3082,7 @@ void GenericEnvironment::dump() const {
30823082
pair.first->dump();
30833083
pair.second->dump();
30843084
}
3085+
llvm::errs() << "Generic parameters:\n";
3086+
for (auto paramTy : getGenericParams())
3087+
paramTy->dump();
30853088
}

lib/AST/ASTPrinter.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3418,14 +3418,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
34183418
Printer.printTypePre(TypeLoc::withoutLoc(T));
34193419
SWIFT_DEFER { Printer.printTypePost(TypeLoc::withoutLoc(T)); };
34203420

3421-
// If we have an alternate name for this type, use it.
3422-
if (Options.AlternativeTypeNames) {
3423-
auto found = Options.AlternativeTypeNames->find(T.getCanonicalTypeOrNull());
3424-
if (found != Options.AlternativeTypeNames->end()) {
3425-
Printer << found->second.str();
3426-
return;
3427-
}
3428-
}
34293421
super::visit(T);
34303422
}
34313423

@@ -3992,6 +3984,14 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
39923984
Printer << ".";
39933985
}
39943986

3987+
if (Options.AlternativeTypeNames) {
3988+
auto found = Options.AlternativeTypeNames->find(T->getCanonicalType());
3989+
if (found != Options.AlternativeTypeNames->end()) {
3990+
Printer << found->second.str();
3991+
return;
3992+
}
3993+
}
3994+
39953995
if (T->getName().empty())
39963996
Printer << "<anonymous>";
39973997
else {
@@ -4012,9 +4012,21 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
40124012
}
40134013

40144014
void visitGenericTypeParamType(GenericTypeParamType *T) {
4015-
// Substitute a context archetype if we have context generic params.
4016-
if (Options.GenericEnv)
4017-
return visit(Options.GenericEnv->mapTypeIntoContext(T));
4015+
if (T->getDecl() == nullptr) {
4016+
// If we have an alternate name for this type, use it.
4017+
if (Options.AlternativeTypeNames) {
4018+
auto found = Options.AlternativeTypeNames->find(T->getCanonicalType());
4019+
if (found != Options.AlternativeTypeNames->end()) {
4020+
Printer << found->second.str();
4021+
return;
4022+
}
4023+
}
4024+
4025+
// When printing SIL types, use a generic environment to map them from
4026+
// canonical types to sugared types.
4027+
if (Options.GenericEnv)
4028+
T = Options.GenericEnv->getSugaredType(T);
4029+
}
40184030

40194031
auto Name = T->getName();
40204032
if (Name.empty())

lib/AST/ArchetypeBuilder.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,27 +2096,31 @@ static void collectRequirements(ArchetypeBuilder &builder,
20962096
});
20972097
}
20982098

2099-
GenericSignature *ArchetypeBuilder::getGenericSignature(
2100-
ArrayRef<GenericTypeParamType *> genericParamTypes) {
2099+
GenericSignature *ArchetypeBuilder::getGenericSignature() {
21012100
// Collect the requirements placed on the generic parameter types.
2101+
SmallVector<GenericTypeParamType *, 4> genericParamTypes;
2102+
for (auto pair : Impl->PotentialArchetypes) {
2103+
auto paramTy = pair.second->getGenericParam();
2104+
genericParamTypes.push_back(paramTy);
2105+
}
2106+
21022107
SmallVector<Requirement, 4> requirements;
21032108
collectRequirements(*this, genericParamTypes, requirements);
21042109

21052110
auto sig = GenericSignature::get(genericParamTypes, requirements);
21062111
return sig;
21072112
}
21082113

2109-
GenericEnvironment *ArchetypeBuilder::getGenericEnvironment(
2110-
ArrayRef<GenericTypeParamType *> genericParamTypes) {
2114+
GenericEnvironment *ArchetypeBuilder::getGenericEnvironment() {
2115+
SmallVector<GenericTypeParamType *, 4> genericParamTypes;
21112116
TypeSubstitutionMap interfaceToArchetypeMap;
21122117

2113-
for (auto paramTy : genericParamTypes) {
2114-
auto known = Impl->PotentialArchetypes.find(
2115-
GenericTypeParamKey::forType(paramTy));
2116-
assert(known != Impl->PotentialArchetypes.end());
2118+
for (auto pair : Impl->PotentialArchetypes) {
2119+
auto paramTy = pair.second->getGenericParam();
2120+
genericParamTypes.push_back(paramTy);
21172121

2118-
auto archetypeTy = known->second->getType(*this).getAsArchetype();
2119-
auto concreteTy = known->second->getType(*this).getAsConcreteType();
2122+
auto archetypeTy = pair.second->getType(*this).getAsArchetype();
2123+
auto concreteTy = pair.second->getType(*this).getAsConcreteType();
21202124
if (archetypeTy)
21212125
interfaceToArchetypeMap[paramTy] = archetypeTy;
21222126
else if (concreteTy)
@@ -2125,6 +2129,7 @@ GenericEnvironment *ArchetypeBuilder::getGenericEnvironment(
21252129
llvm_unreachable("broken generic parameter");
21262130
}
21272131

2128-
return GenericEnvironment::get(Context, interfaceToArchetypeMap);
2132+
return GenericEnvironment::get(Context, genericParamTypes,
2133+
interfaceToArchetypeMap);
21292134
}
21302135

lib/AST/Builtins.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ getBuiltinGenericFunction(Identifier Id,
205205
GenericSignature *Sig =
206206
GenericSignature::get(GenericParamTypes, requirements);
207207
GenericEnvironment *Env =
208-
GenericEnvironment::get(Context, InterfaceToArchetypeMap);
208+
GenericEnvironment::get(Context, GenericParamTypes,
209+
InterfaceToArchetypeMap);
209210

210211
Type InterfaceType = GenericFunctionType::get(Sig, ArgParamType, ResType,
211212
AnyFunctionType::ExtInfo());

lib/AST/GenericEnvironment.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@
2020
using namespace swift;
2121

2222
GenericEnvironment::GenericEnvironment(
23+
ArrayRef<GenericTypeParamType *> genericParamTypes,
2324
TypeSubstitutionMap interfaceToArchetypeMap) {
2425

2526
assert(!interfaceToArchetypeMap.empty());
2627

28+
for (auto *paramTy : genericParamTypes)
29+
GenericParams.push_back(paramTy);
30+
2731
// Build a mapping in both directions, making sure to canonicalize the
2832
// interface type where it is used as a key, so that substitution can
2933
// find them, and to preserve sugar otherwise, so that
@@ -74,6 +78,15 @@ Type GenericEnvironment::mapTypeIntoContext(GenericTypeParamType *type) const {
7478
return found->second;
7579
}
7680

81+
GenericTypeParamType *GenericEnvironment::getSugaredType(
82+
GenericTypeParamType *type) const {
83+
for (auto *sugaredType : GenericParams)
84+
if (sugaredType->isEqual(type))
85+
return sugaredType;
86+
87+
llvm_unreachable("missing generic parameter");
88+
}
89+
7790
ArrayRef<Substitution>
7891
GenericEnvironment::getForwardingSubstitutions(
7992
ModuleDecl *M, GenericSignature *sig) const {

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6860,8 +6860,8 @@ buildGenericSignature(GenericParamList *genericParams,
68606860
param->getDeclaredType()->castTo<GenericTypeParamType>());
68616861
}
68626862

6863-
auto *sig = builder.getGenericSignature(genericParamTypes);
6864-
auto *env = builder.getGenericEnvironment(genericParamTypes);
6863+
auto *sig = builder.getGenericSignature();
6864+
auto *env = builder.getGenericEnvironment();
68656865

68666866
return std::make_pair(sig, env);
68676867
}

lib/SIL/SILPrinter.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/SIL/SILVTable.h"
3131
#include "swift/AST/Decl.h"
3232
#include "swift/AST/Expr.h"
33+
#include "swift/AST/GenericEnvironment.h"
3334
#include "swift/AST/Module.h"
3435
#include "swift/AST/PrintOptions.h"
3536
#include "swift/AST/Types.h"
@@ -1835,21 +1836,25 @@ void SILFunction::print(SILPrintContext &PrintCtx) const {
18351836
llvm::SmallString<16> disambiguatedNameBuf;
18361837
unsigned disambiguatedNameCounter = 1;
18371838
for (auto *paramTy : sig->getGenericParams()) {
1838-
auto *archetypeTy = mapTypeIntoContext(paramTy)->getAs<ArchetypeType>();
1839-
if (!archetypeTy)
1840-
continue;
1841-
1842-
Identifier name = archetypeTy->getName();
1839+
auto sugaredTy = env->getSugaredType(paramTy);
1840+
Identifier name = sugaredTy->getName();
18431841
while (!UsedNames.insert(name).second) {
18441842
disambiguatedNameBuf.clear();
18451843
{
18461844
llvm::raw_svector_ostream names(disambiguatedNameBuf);
1847-
names << archetypeTy->getName() << disambiguatedNameCounter++;
1845+
names << sugaredTy->getName() << disambiguatedNameCounter++;
18481846
}
18491847
name = getASTContext().getIdentifier(disambiguatedNameBuf);
18501848
}
1851-
if (name != archetypeTy->getName())
1852-
Aliases[CanType(archetypeTy)] = name;
1849+
if (name != sugaredTy->getName()) {
1850+
Aliases[paramTy->getCanonicalType()] = name;
1851+
1852+
// Also for the archetype
1853+
auto archetypeTy = env->mapTypeIntoContext(paramTy)
1854+
->getAs<ArchetypeType>();
1855+
if (archetypeTy)
1856+
Aliases[archetypeTy->getCanonicalType()] = name;
1857+
}
18531858
}
18541859
}
18551860

0 commit comments

Comments
 (0)