Skip to content

Commit 5577f27

Browse files
committed
AST: Opened existential environments store outer substitutions
1 parent b434c9f commit 5577f27

File tree

12 files changed

+87
-91
lines changed

12 files changed

+87
-91
lines changed

include/swift/AST/GenericEnvironment.h

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,18 @@ class QueryInterfaceTypeSubstitutions {
5858
/// Extra data in a generic environment for an opaque type.
5959
struct OpaqueEnvironmentData {
6060
OpaqueTypeDecl *decl;
61-
SubstitutionMap subMap;
6261
};
6362

6463
/// Extra data in a generic environment for an opened existential.
6564
struct OpenedExistentialEnvironmentData {
6665
Type existential;
67-
GenericSignature parentSig;
6866
UUID uuid;
6967
};
7068

7169
/// Extra data in a generic environment for an opened pack element.
7270
struct OpenedElementEnvironmentData {
7371
UUID uuid;
7472
CanGenericTypeParamType shapeClass;
75-
SubstitutionMap outerSubstitutions;
7673
};
7774

7875
/// Describes the mapping between archetypes and interface types for the
@@ -86,6 +83,7 @@ struct OpenedElementEnvironmentData {
8683
class alignas(1 << DeclAlignInBits) GenericEnvironment final
8784
: private llvm::TrailingObjects<
8885
GenericEnvironment,
86+
SubstitutionMap,
8987
OpaqueEnvironmentData,
9088
OpenedExistentialEnvironmentData,
9189
OpenedElementEnvironmentData,
@@ -114,6 +112,7 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
114112
friend TrailingObjects;
115113
friend OpaqueTypeArchetypeType;
116114

115+
size_t numTrailingObjects(OverloadToken<SubstitutionMap>) const;
117116
size_t numTrailingObjects(OverloadToken<OpaqueEnvironmentData>) const;
118117
size_t numTrailingObjects(OverloadToken<OpenedExistentialEnvironmentData>) const;
119118
size_t numTrailingObjects(OverloadToken<OpenedElementEnvironmentData>) const;
@@ -147,8 +146,7 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
147146

148147
/// Private constructor for opened existential environments.
149148
explicit GenericEnvironment(
150-
GenericSignature signature,
151-
Type existential, GenericSignature parentSig, UUID uuid);
149+
GenericSignature signature, Type existential, SubstitutionMap subs, UUID uuid);
152150

153151
/// Private constructor for opened element environments.
154152
explicit GenericEnvironment(GenericSignature signature,
@@ -185,20 +183,16 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
185183
/// Retrieve the UUID for an opened existential environment.
186184
UUID getOpenedExistentialUUID() const;
187185

188-
/// Retrieve the parent signature for an opened existential environment.
189-
GenericSignature getOpenedExistentialParentSignature() const;
190-
191186
/// Retrieve the opaque type declaration for a generic environment describing
192187
/// opaque types.
193188
OpaqueTypeDecl *getOpaqueTypeDecl() const;
194189

195-
/// Retrieve the substitutions applied to an opaque type declaration to
196-
/// create a generic environment.
197-
SubstitutionMap getOpaqueSubstitutions() const;
198-
199-
/// Retrieve the substitutions for the outer generic parameters of an
200-
/// opened pack element generic environment.
201-
SubstitutionMap getPackElementContextSubstitutions() const;
190+
/// Retrieve the outer substitutions for an opaque or local environment.
191+
///
192+
/// Applying a substitution map to a local or opaque archetype outputs
193+
/// an archetype with the same interface type, and composed outer
194+
/// substitutions.
195+
SubstitutionMap getOuterSubstitutions() const;
202196

203197
/// Retrieve the shape equivalence class for an opened element environment.
204198
/// This is always a pack parameter.
@@ -238,10 +232,11 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
238232
/// Create a new generic environment for an opened existential.
239233
///
240234
/// \param existential The subject existential type
241-
/// \param parentSig The signature of the context where this existential type is being opened
235+
/// \param outerSubs The substitution map containing archetypes from the
236+
/// outer generic context
242237
/// \param uuid The unique identifier for this opened existential
243238
static GenericEnvironment *
244-
forOpenedExistential(Type existential, GenericSignature parentSig, UUID uuid);
239+
forOpenedExistential(Type existential, SubstitutionMap outerSubs, UUID uuid);
245240

246241
/// Create a new generic environment for an opened element.
247242
///
@@ -251,7 +246,7 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
251246
/// \param uuid The unique identifier for this opened element
252247
/// \param shapeClass The shape equivalence class for the originating packs
253248
/// \param outerSubs The substitution map containing archetypes from the
254-
/// outer generic context.
249+
/// outer generic context
255250
static GenericEnvironment *
256251
forOpenedElement(GenericSignature signature,
257252
UUID uuid, CanGenericTypeParamType shapeClass,
@@ -271,9 +266,6 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
271266
/// substitutions.
272267
Type maybeApplyOuterContextSubstitutions(Type type) const;
273268

274-
/// Compute the canonical interface type within this environment.
275-
Type getCanonicalInterfaceType(Type interfaceType);
276-
277269
/// Map an interface type to a contextual type.
278270
static Type mapTypeIntoContext(GenericEnvironment *genericEnv,
279271
Type type);

include/swift/SIL/SILCloner.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2870,7 +2870,7 @@ void SILCloner<ImplClass>::visitOpenPackElementInst(
28702870

28712871
// Substitute the contextual substitutions.
28722872
auto newContextSubs =
2873-
getOpSubstitutionMap(origEnv->getPackElementContextSubstitutions());
2873+
getOpSubstitutionMap(origEnv->getOuterSubstitutions());
28742874

28752875
// The opened shape class is a parameter of the original signature,
28762876
// which is unchanged.

lib/AST/ASTContext.cpp

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,8 @@ struct ASTContext::Implementation {
606606
void dump(llvm::raw_ostream &out) const;
607607
};
608608

609+
using OpenedExistentialKey = std::pair<SubstitutionMap, UUID>;
610+
609611
llvm::DenseMap<ModuleDecl*, ModuleType*> ModuleTypes;
610612
llvm::DenseMap<std::pair<unsigned, unsigned>, GenericTypeParamType *>
611613
GenericParamTypes;
@@ -618,7 +620,8 @@ struct ASTContext::Implementation {
618620
llvm::DenseMap<BuiltinIntegerWidth, BuiltinIntegerType*> IntegerTypes;
619621
llvm::FoldingSet<BuiltinVectorType> BuiltinVectorTypes;
620622
llvm::FoldingSet<DeclName::CompoundDeclName> CompoundNames;
621-
llvm::DenseMap<UUID, GenericEnvironment *> OpenedExistentialEnvironments;
623+
llvm::DenseMap<OpenedExistentialKey, GenericEnvironment *>
624+
OpenedExistentialEnvironments;
622625
llvm::DenseMap<UUID, GenericEnvironment *> OpenedElementEnvironments;
623626
llvm::FoldingSet<IndexSubset> IndexSubsets;
624627
llvm::FoldingSet<AutoDiffDerivativeFunctionIdentifier>
@@ -5295,7 +5298,7 @@ OpaqueTypeArchetypeType *OpaqueTypeArchetypeType::getNew(
52955298
ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
52965299
LayoutConstraint layout) {
52975300
auto properties = getOpaqueTypeArchetypeProperties(
5298-
environment->getOpaqueSubstitutions());
5301+
environment->getOuterSubstitutions());
52995302
auto arena = getArena(properties);
53005303
auto size = OpaqueTypeArchetypeType::totalSizeToAlloc<
53015304
ProtocolDecl *, Type, LayoutConstraint>(
@@ -5353,7 +5356,7 @@ CanOpenedArchetypeType OpenedArchetypeType::get(CanType existential,
53535356

53545357
auto *genericEnv =
53555358
GenericEnvironment::forOpenedExistential(
5356-
existential, GenericSignature(), *knownID);
5359+
existential, SubstitutionMap(), *knownID);
53575360

53585361
// Map the interface type into that environment.
53595362
auto result = genericEnv->mapTypeIntoContext(interfaceType)
@@ -5508,10 +5511,11 @@ GenericEnvironment *GenericEnvironment::forPrimary(GenericSignature signature) {
55085511

55095512
// Allocate and construct the new environment.
55105513
unsigned numGenericParams = signature.getGenericParams().size();
5511-
size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
5514+
size_t bytes = totalSizeToAlloc<SubstitutionMap,
5515+
OpaqueEnvironmentData,
55125516
OpenedExistentialEnvironmentData,
55135517
OpenedElementEnvironmentData, Type>(
5514-
0, 0, 0, numGenericParams);
5518+
0, 0, 0, 0, numGenericParams);
55155519
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
55165520
return new (mem) GenericEnvironment(signature);
55175521
}
@@ -5537,10 +5541,11 @@ GenericEnvironment *GenericEnvironment::forOpaqueType(
55375541
// Allocate and construct the new environment.
55385542
auto signature = opaque->getOpaqueInterfaceGenericSignature();
55395543
unsigned numGenericParams = signature.getGenericParams().size();
5540-
size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
5544+
size_t bytes = totalSizeToAlloc<SubstitutionMap,
5545+
OpaqueEnvironmentData,
55415546
OpenedExistentialEnvironmentData,
55425547
OpenedElementEnvironmentData, Type>(
5543-
1, 0, 0, numGenericParams);
5548+
1, 1, 0, 0, numGenericParams);
55445549
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment), arena);
55455550
env = new (mem) GenericEnvironment(signature, opaque, subs);
55465551

@@ -5553,7 +5558,7 @@ GenericEnvironment *GenericEnvironment::forOpaqueType(
55535558
/// Create a new generic environment for an opened archetype.
55545559
GenericEnvironment *
55555560
GenericEnvironment::forOpenedExistential(
5556-
Type existential, GenericSignature parentSig, UUID uuid) {
5561+
Type existential, SubstitutionMap subs, UUID uuid) {
55575562
assert(existential->isExistentialType());
55585563
// FIXME: Opened archetypes can't be transformed because the
55595564
// the identity of the archetype has to be preserved. This
@@ -5567,32 +5572,36 @@ GenericEnvironment::forOpenedExistential(
55675572

55685573
auto &ctx = existential->getASTContext();
55695574

5575+
auto key = std::make_pair(subs, uuid);
5576+
55705577
auto &openedExistentialEnvironments =
55715578
ctx.getImpl().OpenedExistentialEnvironments;
5572-
auto found = openedExistentialEnvironments.find(uuid);
5579+
auto found = openedExistentialEnvironments.find(key);
55735580

55745581
if (found != openedExistentialEnvironments.end()) {
55755582
auto *existingEnv = found->second;
55765583
assert(existingEnv->getOpenedExistentialType()->isEqual(existential));
5577-
assert(existingEnv->getOpenedExistentialParentSignature().getPointer() == parentSig.getPointer());
5584+
assert(existingEnv->getOuterSubstitutions() == subs);
55785585
assert(existingEnv->getOpenedExistentialUUID() == uuid);
55795586

55805587
return existingEnv;
55815588
}
55825589

5590+
auto parentSig = subs.getGenericSignature().getCanonicalSignature();
55835591
auto signature = ctx.getOpenedExistentialSignature(existential, parentSig);
55845592

55855593
// Allocate and construct the new environment.
55865594
unsigned numGenericParams = signature.getGenericParams().size();
5587-
size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
5595+
size_t bytes = totalSizeToAlloc<SubstitutionMap,
5596+
OpaqueEnvironmentData,
55885597
OpenedExistentialEnvironmentData,
55895598
OpenedElementEnvironmentData, Type>(
5590-
0, 1, 0, numGenericParams);
5599+
1, 0, 1, 0, numGenericParams);
55915600
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
55925601
auto *genericEnv =
5593-
new (mem) GenericEnvironment(signature, existential, parentSig, uuid);
5602+
new (mem) GenericEnvironment(signature, existential, subs, uuid);
55945603

5595-
openedExistentialEnvironments[uuid] = genericEnv;
5604+
openedExistentialEnvironments[key] = genericEnv;
55965605

55975606
return genericEnv;
55985607
}
@@ -5621,11 +5630,12 @@ GenericEnvironment::forOpenedElement(GenericSignature signature,
56215630
// Allocate and construct the new environment.
56225631
unsigned numGenericParams = signature.getGenericParams().size();
56235632
unsigned numOpenedParams = signature.getInnermostGenericParams().size();
5624-
size_t bytes = totalSizeToAlloc<OpaqueEnvironmentData,
5633+
size_t bytes = totalSizeToAlloc<SubstitutionMap,
5634+
OpaqueEnvironmentData,
56255635
OpenedExistentialEnvironmentData,
56265636
OpenedElementEnvironmentData,
56275637
Type>(
5628-
0, 0, 1, numGenericParams + numOpenedParams);
5638+
1, 0, 0, 1, numGenericParams + numOpenedParams);
56295639
void *mem = ctx.Allocate(bytes, alignof(GenericEnvironment));
56305640
auto *genericEnv = new (mem) GenericEnvironment(signature,
56315641
uuid, shapeClass,

lib/AST/ASTPrinter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6955,7 +6955,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
69556955
// the generic signature of the contextual substitution map in the
69566956
// opened element environment.
69576957
auto env = T->getGenericEnvironment();
6958-
auto subs = env->getPackElementContextSubstitutions();
6958+
auto subs = env->getOuterSubstitutions();
69596959
auto sig = subs.getGenericSignature();
69606960
auto params = sig.getGenericParams();
69616961

lib/AST/GenericEnvironment.cpp

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@
2424

2525
using namespace swift;
2626

27+
size_t GenericEnvironment::numTrailingObjects(
28+
OverloadToken<SubstitutionMap>) const {
29+
switch (getKind()) {
30+
case Kind::Primary:
31+
return 0;
32+
33+
case Kind::OpenedExistential:
34+
case Kind::OpenedElement:
35+
case Kind::Opaque:
36+
return 1;
37+
}
38+
}
39+
2740
size_t GenericEnvironment::numTrailingObjects(
2841
OverloadToken<OpaqueEnvironmentData>) const {
2942
switch (getKind()) {
@@ -104,21 +117,14 @@ GenericEnvironment::getGenericParams() const {
104117
return getGenericSignature().getGenericParams();
105118
}
106119

107-
OpaqueTypeDecl *GenericEnvironment::getOpaqueTypeDecl() const {
108-
assert(getKind() == Kind::Opaque);
109-
return getTrailingObjects<OpaqueEnvironmentData>()->decl;
120+
SubstitutionMap GenericEnvironment::getOuterSubstitutions() const {
121+
assert(getKind() != Kind::Primary);
122+
return *getTrailingObjects<SubstitutionMap>();
110123
}
111124

112-
SubstitutionMap GenericEnvironment::getOpaqueSubstitutions() const {
125+
OpaqueTypeDecl *GenericEnvironment::getOpaqueTypeDecl() const {
113126
assert(getKind() == Kind::Opaque);
114-
return getTrailingObjects<OpaqueEnvironmentData>()->subMap;
115-
}
116-
117-
SubstitutionMap
118-
GenericEnvironment::getPackElementContextSubstitutions() const {
119-
assert(getKind() == Kind::OpenedElement);
120-
auto environmentData = getTrailingObjects<OpenedElementEnvironmentData>();
121-
return environmentData->outerSubstitutions;
127+
return getTrailingObjects<OpaqueEnvironmentData>()->decl;
122128
}
123129

124130
CanGenericTypeParamType
@@ -138,12 +144,6 @@ UUID GenericEnvironment::getOpenedExistentialUUID() const {
138144
return getTrailingObjects<OpenedExistentialEnvironmentData>()->uuid;
139145
}
140146

141-
GenericSignature
142-
GenericEnvironment::getOpenedExistentialParentSignature() const {
143-
assert(getKind() == Kind::OpenedExistential);
144-
return getTrailingObjects<OpenedExistentialEnvironmentData>()->parentSig;
145-
}
146-
147147
UUID GenericEnvironment::getOpenedElementUUID() const {
148148
assert(getKind() == Kind::OpenedElement);
149149
return getTrailingObjects<OpenedElementEnvironmentData>()->uuid;
@@ -212,11 +212,12 @@ GenericEnvironment::GenericEnvironment(GenericSignature signature)
212212

213213
GenericEnvironment::GenericEnvironment(
214214
GenericSignature signature,
215-
Type existential, GenericSignature parentSig, UUID uuid)
215+
Type existential, SubstitutionMap subs, UUID uuid)
216216
: SignatureAndKind(signature, Kind::OpenedExistential)
217217
{
218+
*getTrailingObjects<SubstitutionMap>() = subs;
218219
new (getTrailingObjects<OpenedExistentialEnvironmentData>())
219-
OpenedExistentialEnvironmentData{ existential, parentSig, uuid };
220+
OpenedExistentialEnvironmentData{ existential, uuid };
220221

221222
// Clear out the memory that holds the context types.
222223
std::uninitialized_fill(getContextTypes().begin(), getContextTypes().end(),
@@ -227,8 +228,9 @@ GenericEnvironment::GenericEnvironment(
227228
GenericSignature signature, OpaqueTypeDecl *opaque, SubstitutionMap subs)
228229
: SignatureAndKind(signature, Kind::Opaque)
229230
{
231+
*getTrailingObjects<SubstitutionMap>() = subs;
230232
new (getTrailingObjects<OpaqueEnvironmentData>())
231-
OpaqueEnvironmentData{opaque, subs};
233+
OpaqueEnvironmentData{opaque};
232234

233235
// Clear out the memory that holds the context types.
234236
std::uninitialized_fill(getContextTypes().begin(), getContextTypes().end(),
@@ -241,8 +243,9 @@ GenericEnvironment::GenericEnvironment(GenericSignature signature,
241243
SubstitutionMap outerSubs)
242244
: SignatureAndKind(signature, Kind::OpenedElement)
243245
{
246+
*getTrailingObjects<SubstitutionMap>() = outerSubs;
244247
new (getTrailingObjects<OpenedElementEnvironmentData>())
245-
OpenedElementEnvironmentData{uuid, shapeClass, outerSubs};
248+
OpenedElementEnvironmentData{uuid, shapeClass};
246249

247250
// Clear out the memory that holds the context types.
248251
std::uninitialized_fill(getContextTypes().begin(), getContextTypes().end(),
@@ -337,20 +340,12 @@ GenericEnvironment::maybeApplyOuterContextSubstitutions(Type type) const {
337340
case Kind::OpenedExistential:
338341
return type;
339342

340-
case Kind::OpenedElement: {
343+
case Kind::OpenedElement:
344+
case Kind::Opaque: {
341345
auto packElements = getGenericSignature().getInnermostGenericParams();
342346
auto elementDepth = packElements.front()->getDepth();
343347
SubstituteOuterFromSubstitutionMap replacer{
344-
getPackElementContextSubstitutions(), elementDepth};
345-
return type.subst(replacer, replacer);
346-
}
347-
348-
case Kind::Opaque: {
349-
// Substitute outer generic parameters of an opaque archetype environment.
350-
unsigned opaqueDepth =
351-
getOpaqueTypeDecl()->getOpaqueGenericParams().front()->getDepth();
352-
SubstituteOuterFromSubstitutionMap replacer{
353-
getOpaqueSubstitutions(), opaqueDepth};
348+
getOuterSubstitutions(), elementDepth};
354349
return type.subst(replacer, replacer);
355350
}
356351
}
@@ -686,7 +681,7 @@ GenericEnvironment::mapPackTypeIntoElementContext(Type type) const {
686681
// Get a contextual type in the original generic environment, not the
687682
// substituted one, which is what mapContextualPackTypeIntoElementContext()
688683
// expects.
689-
auto contextualType = getPackElementContextSubstitutions()
684+
auto contextualType = getOuterSubstitutions()
690685
.getGenericSignature().getGenericEnvironment()->mapTypeIntoContext(type);
691686

692687
contextualType = mapContextualPackTypeIntoElementContext(contextualType);

lib/AST/Type.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3569,7 +3569,7 @@ OpaqueTypeDecl *OpaqueTypeArchetypeType::getDecl() const {
35693569
}
35703570

35713571
SubstitutionMap OpaqueTypeArchetypeType::getSubstitutions() const {
3572-
return Environment->getOpaqueSubstitutions();
3572+
return Environment->getOuterSubstitutions();
35733573
}
35743574

35753575
OpenedArchetypeType::OpenedArchetypeType(

0 commit comments

Comments
 (0)