Skip to content

Commit c522b49

Browse files
committed
AST: Introduce ASTContext::getExistentialSignature()
Given an existential type E, this creates a new canonical generic signature <T : E>. If E is a protocol composition containing members of protocol, class or AnyObject type, the resulting generic signature will split up the T : E requirement into a canonical and minimal set of conformance, superclass and layout requirements. If/when we implement generalized existentials, existential types will be defined in terms of an arbitrary set of generic requirements applied to a single generic parameter; at that point, this method will be replaced with a generic signature stored inside the type itself. For now, this will be used to simplify some logic in the SILOptimizer.
1 parent 6607058 commit c522b49

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

include/swift/AST/ASTContext.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,11 @@ class ASTContext {
866866
/// like `<T>`.
867867
CanGenericSignature getSingleGenericParameterSignature() const;
868868

869+
/// Retrieve a generic signature with a single type parameter conforming
870+
/// to the given existential type.
871+
CanGenericSignature getExistentialSignature(CanType existential,
872+
ModuleDecl *mod);
873+
869874
/// Whether our effective Swift version is in the Swift 3 family.
870875
bool isSwiftVersion3() const { return LangOpts.isSwiftVersion3(); }
871876

lib/AST/ASTContext.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ FOR_KNOWN_FOUNDATION_TYPES(CACHE_FOUNDATION_DECL)
261261
/// The single-parameter generic signature with no constraints, <T>.
262262
CanGenericSignature SingleGenericParameterSignature;
263263

264+
/// The existential signature <T : P> for each P.
265+
llvm::DenseMap<CanType, CanGenericSignature> ExistentialSignatures;
266+
264267
/// \brief Structure that captures data that is segregated into different
265268
/// arenas.
266269
struct Arena {
@@ -4509,6 +4512,35 @@ CanGenericSignature ASTContext::getSingleGenericParameterSignature() const {
45094512
return canonicalSig;
45104513
}
45114514

4515+
CanGenericSignature ASTContext::getExistentialSignature(CanType existential,
4516+
ModuleDecl *mod) {
4517+
auto found = Impl.ExistentialSignatures.find(existential);
4518+
if (found != Impl.ExistentialSignatures.end())
4519+
return found->second;
4520+
4521+
assert(existential.isExistentialType());
4522+
4523+
GenericSignatureBuilder builder(*this, LookUpConformanceInModule(mod));
4524+
4525+
auto genericParam = GenericTypeParamType::get(0, 0, *this);
4526+
builder.addGenericParameter(genericParam);
4527+
4528+
Requirement requirement(RequirementKind::Conformance, genericParam,
4529+
existential);
4530+
auto source =
4531+
GenericSignatureBuilder::FloatingRequirementSource::forAbstract();
4532+
builder.addRequirement(requirement, source, nullptr);
4533+
4534+
CanGenericSignature genericSig(builder.computeGenericSignature(SourceLoc()));
4535+
4536+
auto result = Impl.ExistentialSignatures.insert(
4537+
std::make_pair(existential, genericSig));
4538+
assert(result.second);
4539+
(void) result;
4540+
4541+
return genericSig;
4542+
}
4543+
45124544
SILLayout *SILLayout::get(ASTContext &C,
45134545
CanGenericSignature Generics,
45144546
ArrayRef<SILField> Fields) {

0 commit comments

Comments
 (0)