Skip to content

Commit a3c0e22

Browse files
authored
Merge pull request #76238 from slavapestov/existential-signature-rework-part-3
Allow type variables to appear inside opened existential archetypes
2 parents 736faac + b7af52f commit a3c0e22

24 files changed

+379
-209
lines changed

include/swift/AST/ASTContext.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,19 +1446,6 @@ class ASTContext final {
14461446
/// like `<T>`.
14471447
CanGenericSignature getSingleGenericParameterSignature() const;
14481448

1449-
/// Retrieve a generic signature with a single type parameter conforming
1450-
/// to the given protocol or composition type, like <T: P>.
1451-
///
1452-
/// The opened archetype may have a different set of conformances from the
1453-
/// corresponding existential. The opened archetype conformances are dictated
1454-
/// by the ABI for generic arguments, while the existential value conformances
1455-
/// are dictated by their layout (see \c Type::getExistentialLayout()). In
1456-
/// particular, the opened archetype signature does not have requirements for
1457-
/// conformances inherited from superclass constraints while existential
1458-
/// values do.
1459-
CanGenericSignature getOpenedExistentialSignature(Type type,
1460-
GenericSignature parentSig);
1461-
14621449
/// Retrieve a generic signature with a single type parameter conforming
14631450
/// to the given protocol or composition type, like <T: P>.
14641451
///

include/swift/AST/TypeTransform.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#ifndef SWIFT_AST_TYPETRANSFORM_H
1919
#define SWIFT_AST_TYPETRANSFORM_H
2020

21+
#include "swift/AST/GenericEnvironment.h"
2122
#include "swift/AST/SILLayout.h"
2223

2324
namespace swift {
@@ -136,7 +137,29 @@ case TypeKind::Id:
136137
newSubMap);
137138
}
138139

139-
case TypeKind::OpenedArchetype:
140+
case TypeKind::OpenedArchetype: {
141+
auto *local = cast<LocalArchetypeType>(base);
142+
if (auto result = asDerived().transformLocalArchetypeType(local, pos))
143+
return *result;
144+
145+
auto *env = local->getGenericEnvironment();
146+
147+
auto genericSig = env->getGenericSignature();
148+
auto existentialTy = env->getOpenedExistentialType();
149+
auto subMap = env->getOuterSubstitutions();
150+
auto uuid = env->getOpenedExistentialUUID();
151+
152+
auto newSubMap = asDerived().transformSubMap(subMap);
153+
if (newSubMap == subMap)
154+
return t;
155+
if (!newSubMap)
156+
return Type();
157+
158+
auto *newEnv = GenericEnvironment::forOpenedExistential(
159+
genericSig, existentialTy, newSubMap, uuid);
160+
return newEnv->mapTypeIntoContext(local->getInterfaceType());
161+
}
162+
140163
case TypeKind::ElementArchetype: {
141164
auto *local = cast<LocalArchetypeType>(base);
142165
if (auto result = asDerived().transformLocalArchetypeType(local, pos))

include/swift/AST/Types.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6785,15 +6785,6 @@ class OpenedArchetypeType final : public LocalArchetypeType,
67856785
ArrayRef<ProtocolDecl *> conformsTo, Type superclass,
67866786
LayoutConstraint layout);
67876787

6788-
public:
6789-
/// Compute the parameter that serves as the \c Self type for an opened
6790-
/// archetype from the given outer generic signature.
6791-
///
6792-
/// This type is a generic parameter one level deeper
6793-
/// than the deepest generic context depth.
6794-
static Type getSelfInterfaceTypeFromContext(GenericSignature parentSig,
6795-
ASTContext &ctx);
6796-
67976788
public:
67986789
/// Get or create an archetype that represents the opened type
67996790
/// of an existential value.
@@ -6814,9 +6805,6 @@ class OpenedArchetypeType final : public LocalArchetypeType,
68146805
/// \param existential The existential type or existential metatype to open.
68156806
static Type getAny(Type existential);
68166807

6817-
/// Retrieve the ID number of this opened existential.
6818-
UUID getOpenedExistentialID() const;
6819-
68206808
static bool classof(const TypeBase *T) {
68216809
return T->getKind() == TypeKind::OpenedArchetype;
68226810
}

include/swift/SIL/SILCloner.h

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
245245
/// Register a re-mapping for local archetypes such as opened existentials.
246246
void registerLocalArchetypeRemapping(GenericEnvironment *From,
247247
GenericEnvironment *To) {
248-
ASSERT(From->getGenericSignature()->getMaxDepth()
249-
== To->getGenericSignature()->getMaxDepth());
248+
ASSERT(From->getGenericSignature().getPointer()
249+
== To->getGenericSignature().getPointer());
250250

251251
auto result = Functor.LocalArchetypeSubs.insert(std::make_pair(From, To));
252252
assert(result.second);
@@ -380,14 +380,14 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
380380

381381
void remapRootOpenedType(CanOpenedArchetypeType archetypeTy) {
382382
auto *origEnv = archetypeTy->getGenericEnvironment();
383+
384+
auto genericSig = origEnv->getGenericSignature();
385+
auto existentialTy = origEnv->getOpenedExistentialType();
383386
auto subMap = origEnv->getOuterSubstitutions();
384-
ASSERT(!subMap && "Transform the substitution map!");
385-
auto origExistentialTy = origEnv->getOpenedExistentialType()
386-
->getCanonicalType();
387387

388-
auto substExistentialTy = getOpASTType(origExistentialTy);
389388
auto *newEnv = GenericEnvironment::forOpenedExistential(
390-
substExistentialTy, UUID::fromTime());
389+
genericSig, existentialTy, getOpSubstitutionMap(subMap),
390+
UUID::fromTime());
391391

392392
registerLocalArchetypeRemapping(origEnv, newEnv);
393393
}
@@ -2675,7 +2675,7 @@ template<typename ImplClass>
26752675
void
26762676
SILCloner<ImplClass>::visitOpenExistentialAddrInst(OpenExistentialAddrInst *Inst) {
26772677
// Create a new archetype for this opened existential type.
2678-
remapRootOpenedType(Inst->getType().castTo<OpenedArchetypeType>());
2678+
remapRootOpenedType(Inst->getDefinedOpenedArchetype());
26792679

26802680
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
26812681
recordClonedInstruction(
@@ -2688,7 +2688,7 @@ template <typename ImplClass>
26882688
void SILCloner<ImplClass>::visitOpenExistentialValueInst(
26892689
OpenExistentialValueInst *Inst) {
26902690
// Create a new archetype for this opened existential type.
2691-
remapRootOpenedType(Inst->getType().castTo<OpenedArchetypeType>());
2691+
remapRootOpenedType(Inst->getDefinedOpenedArchetype());
26922692

26932693
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
26942694
recordClonedInstruction(
@@ -2704,14 +2704,7 @@ template<typename ImplClass>
27042704
void
27052705
SILCloner<ImplClass>::
27062706
visitOpenExistentialMetatypeInst(OpenExistentialMetatypeInst *Inst) {
2707-
// Create a new archetype for this opened existential type.
2708-
auto openedType = Inst->getType().getASTType();
2709-
auto exType = Inst->getOperand()->getType().getASTType();
2710-
while (auto exMetatype = dyn_cast<ExistentialMetatypeType>(exType)) {
2711-
exType = exMetatype->getExistentialInstanceType()->getCanonicalType();
2712-
openedType = cast<MetatypeType>(openedType).getInstanceType();
2713-
}
2714-
remapRootOpenedType(cast<OpenedArchetypeType>(openedType));
2707+
remapRootOpenedType(Inst->getDefinedOpenedArchetype());
27152708

27162709
if (!Inst->getOperand()->getType().canUseExistentialRepresentation(
27172710
ExistentialRepresentation::Class)) {
@@ -2735,7 +2728,7 @@ void
27352728
SILCloner<ImplClass>::
27362729
visitOpenExistentialRefInst(OpenExistentialRefInst *Inst) {
27372730
// Create a new archetype for this opened existential type.
2738-
remapRootOpenedType(Inst->getType().castTo<OpenedArchetypeType>());
2731+
remapRootOpenedType(Inst->getDefinedOpenedArchetype());
27392732

27402733
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
27412734
recordClonedInstruction(
@@ -2752,7 +2745,7 @@ void
27522745
SILCloner<ImplClass>::
27532746
visitOpenExistentialBoxInst(OpenExistentialBoxInst *Inst) {
27542747
// Create a new archetype for this opened existential type.
2755-
remapRootOpenedType(Inst->getType().castTo<OpenedArchetypeType>());
2748+
remapRootOpenedType(Inst->getDefinedOpenedArchetype());
27562749

27572750
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
27582751
recordClonedInstruction(Inst, getBuilder().createOpenExistentialBox(
@@ -2766,7 +2759,7 @@ void
27662759
SILCloner<ImplClass>::
27672760
visitOpenExistentialBoxValueInst(OpenExistentialBoxValueInst *Inst) {
27682761
// Create a new archetype for this opened existential type.
2769-
remapRootOpenedType(Inst->getType().castTo<OpenedArchetypeType>());
2762+
remapRootOpenedType(Inst->getDefinedOpenedArchetype());
27702763

27712764
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
27722765
recordClonedInstruction(

lib/AST/ASTContext.cpp

Lines changed: 27 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -457,10 +457,6 @@ struct ASTContext::Implementation {
457457
/// The single-parameter generic signature with no constraints, <T>.
458458
CanGenericSignature SingleGenericParameterSignature;
459459

460-
/// The existential signature <T : P> for each P.
461-
llvm::DenseMap<std::pair<CanType, const GenericSignatureImpl *>, CanGenericSignature>
462-
ExistentialSignatures;
463-
464460
/// The element signature for a generic signature, which contains a clone
465461
/// of the context generic signature with new type parameters and requirements
466462
/// for opened pack elements in the given shape equivalence class.
@@ -851,7 +847,6 @@ void ASTContext::Implementation::dump(llvm::raw_ostream &os) const {
851847
SIZE_AND_BYTES(AssociativityCache);
852848
SIZE_AND_BYTES(DelayedConformanceDiags);
853849
SIZE_AND_BYTES(LazyContexts);
854-
SIZE_AND_BYTES(ExistentialSignatures);
855850
SIZE_AND_BYTES(ElementSignatures);
856851
SIZE_AND_BYTES(Overrides);
857852
SIZE_AND_BYTES(DefaultWitnesses);
@@ -5342,22 +5337,21 @@ CanTypeWrapper<OpenedArchetypeType> OpenedArchetypeType::getNew(
53425337

53435338
CanOpenedArchetypeType OpenedArchetypeType::get(CanType existential,
53445339
std::optional<UUID> knownID) {
5345-
assert(existential->isExistentialType());
5346-
assert(!existential->hasTypeParameter());
5347-
5348-
auto interfaceType = OpenedArchetypeType::getSelfInterfaceTypeFromContext(
5349-
GenericSignature(), existential->getASTContext());
5340+
auto &ctx = existential->getASTContext();
5341+
auto existentialSig = ctx.getOpenedExistentialSignature(existential);
53505342

53515343
if (!knownID)
53525344
knownID = UUID::fromTime();
53535345

53545346
auto *genericEnv = GenericEnvironment::forOpenedExistential(
5355-
existential, *knownID);
5347+
existentialSig.OpenedSig,
5348+
existentialSig.Shape,
5349+
existentialSig.Generalization,
5350+
*knownID);
53565351

5357-
// Map the interface type into that environment.
5358-
auto result = genericEnv->mapTypeIntoContext(interfaceType)
5359-
->castTo<OpenedArchetypeType>();
5360-
return CanOpenedArchetypeType(result);
5352+
return cast<OpenedArchetypeType>(
5353+
genericEnv->mapTypeIntoContext(existentialSig.SelfType)
5354+
->getCanonicalType());
53615355
}
53625356

53635357
Type OpenedArchetypeType::getAny(Type existential) {
@@ -5547,8 +5541,10 @@ GenericEnvironment *GenericEnvironment::forOpaqueType(
55475541
GenericEnvironment *
55485542
GenericEnvironment::forOpenedExistential(Type existential, UUID uuid) {
55495543
auto &ctx = existential->getASTContext();
5550-
auto signature = ctx.getOpenedExistentialSignature(existential, GenericSignature());
5551-
return forOpenedExistential(signature, existential, SubstitutionMap(), uuid);
5544+
auto existentialSig = ctx.getOpenedExistentialSignature(existential);
5545+
return forOpenedExistential(existentialSig.OpenedSig,
5546+
existentialSig.Shape,
5547+
existentialSig.Generalization, uuid);
55525548
}
55535549

55545550
/// Create a new generic environment for an opened archetype.
@@ -6136,83 +6132,51 @@ CanGenericSignature ASTContext::getSingleGenericParameterSignature() const {
61366132
return canonicalSig;
61376133
}
61386134

6139-
Type OpenedArchetypeType::getSelfInterfaceTypeFromContext(GenericSignature parentSig,
6140-
ASTContext &ctx) {
6141-
return GenericTypeParamType::get(/*isParameterPack=*/ false,
6142-
parentSig.getNextDepth(), /*index=*/ 0,
6143-
ctx);
6144-
}
6145-
6146-
CanGenericSignature
6147-
ASTContext::getOpenedExistentialSignature(Type type, GenericSignature parentSig) {
6148-
assert(type->isExistentialType());
6149-
6150-
if (auto existential = type->getAs<ExistentialType>())
6151-
type = existential->getConstraintType();
6152-
6153-
const CanType constraint = type->getCanonicalType();
6154-
6155-
auto canParentSig = parentSig.getCanonicalSignature();
6156-
auto key = std::make_pair(constraint, canParentSig.getPointer());
6157-
auto found = getImpl().ExistentialSignatures.find(key);
6158-
if (found != getImpl().ExistentialSignatures.end())
6159-
return found->second;
6160-
6161-
LocalArchetypeRequirementCollector collector(*this, canParentSig);
6162-
collector.addOpenedExistential(type);
6163-
auto genericSig = buildGenericSignature(
6164-
*this, collector.OuterSig, collector.Params, collector.Requirements,
6165-
/*allowInverses=*/true).getCanonicalSignature();
6166-
6167-
auto result = getImpl().ExistentialSignatures.insert(
6168-
std::make_pair(key, genericSig));
6169-
ASSERT(result.second);
6170-
6171-
return genericSig;
6172-
}
6173-
61746135
OpenedExistentialSignature
61756136
ASTContext::getOpenedExistentialSignature(Type type) {
61766137
assert(type->isExistentialType());
61776138

6178-
if (auto existential = type->getAs<ExistentialType>())
6179-
type = existential->getConstraintType();
6180-
6181-
const CanType constraint = type->getCanonicalType();
6139+
auto canType = type->getCanonicalType();
61826140

61836141
// The constraint type might contain type variables.
6184-
auto properties = constraint->getRecursiveProperties();
6142+
auto properties = canType->getRecursiveProperties();
61856143
auto arena = getArena(properties);
61866144

61876145
// Check the cache.
61886146
const auto &sigs = getImpl().getArena(arena).ExistentialSignatures;
6189-
auto found = sigs.find(constraint);
6147+
auto found = sigs.find(canType);
61906148
if (found != sigs.end())
61916149
return found->second;
61926150

61936151
OpenedExistentialSignature existentialSig;
61946152

61956153
// Generalize the existential type, to move type variables and primary
61966154
// archetypes into the substitution map.
6197-
auto gen = ExistentialTypeGeneralization::get(constraint);
6155+
auto gen = ExistentialTypeGeneralization::get(canType);
6156+
61986157
existentialSig.Shape = gen.Shape->getCanonicalType();
61996158
existentialSig.Generalization = gen.Generalization;
62006159

62016160
// Now, we have an existential type written with type parameters only.
62026161
// Open the generalization signature by adding a new generic parameter
62036162
// for `Self`.
62046163
auto parentSig = gen.Generalization.getGenericSignature();
6205-
existentialSig.OpenedSig =
6206-
getOpenedExistentialSignature(gen.Shape, parentSig);
6164+
auto canParentSig = parentSig.getCanonicalSignature();
6165+
6166+
LocalArchetypeRequirementCollector collector(*this, canParentSig);
6167+
collector.addOpenedExistential(gen.Shape);
6168+
existentialSig.OpenedSig = buildGenericSignature(
6169+
*this, collector.OuterSig, collector.Params, collector.Requirements,
6170+
/*allowInverses=*/true).getCanonicalSignature();
62076171

62086172
// Stash the `Self` type.
62096173
existentialSig.SelfType =
6210-
OpenedArchetypeType::getSelfInterfaceTypeFromContext(parentSig, *this)
6174+
existentialSig.OpenedSig.getGenericParams().back()
62116175
->getCanonicalType();
62126176

62136177
// Cache the result.
62146178
auto result = getImpl().getArena(arena).ExistentialSignatures.insert(
6215-
std::make_pair(constraint, existentialSig));
6179+
std::make_pair(canType, existentialSig));
62166180
ASSERT(result.second);
62176181

62186182
return existentialSig;

lib/AST/ASTDumper.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4219,10 +4219,13 @@ namespace {
42194219
void visitOpenedArchetypeType(OpenedArchetypeType *T, StringRef label) {
42204220
printArchetypeCommon(T, "opened_archetype_type", label);
42214221

4222-
printFieldQuoted(T->getOpenedExistentialID(), "opened_existential_id");
4222+
auto *env = T->getGenericEnvironment();
4223+
printFieldQuoted(env->getOpenedExistentialUUID(), "opened_existential_id");
42234224

42244225
printArchetypeCommonRec(T);
4225-
printRec(T->getGenericEnvironment()->getOpenedExistentialType(), "opened_existential");
4226+
printRec(env->getOpenedExistentialType(), "opened_existential");
4227+
if (auto subMap = env->getOuterSubstitutions())
4228+
printRec(subMap, "substitutions");
42264229

42274230
printFoot();
42284231
}

lib/AST/ASTPrinter.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6928,8 +6928,12 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
69286928

69296929
void visitOpenedArchetypeType(OpenedArchetypeType *T) {
69306930
if (Options.PrintForSIL) {
6931-
Printer << "@opened(\"" << T->getOpenedExistentialID() << "\", ";
6932-
visit(T->getGenericEnvironment()->getOpenedExistentialType());
6931+
auto *env = T->getGenericEnvironment();
6932+
6933+
Printer << "@opened(\"" << env->getOpenedExistentialUUID() << "\", ";
6934+
auto existentialTy = env->maybeApplyOuterContextSubstitutions(
6935+
env->getOpenedExistentialType());
6936+
visit(existentialTy);
69336937
Printer << ") ";
69346938

69356939
llvm::DenseMap<CanType, Identifier> newAlternativeTypeNames;

0 commit comments

Comments
 (0)