Skip to content

Commit ab44a07

Browse files
committedMar 8, 2022
Convert DeclContext Parameters to their Associated Generic Signatures Instead
1 parent 01d9d61 commit ab44a07

26 files changed

+148
-111
lines changed
 

‎include/swift/AST/ASTContext.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1308,7 +1308,7 @@ class ASTContext final {
13081308
/// conformances inherited from superclass constraints while existential
13091309
/// values do.
13101310
CanGenericSignature getOpenedArchetypeSignature(Type type,
1311-
const DeclContext *useDC);
1311+
GenericSignature parentSig);
13121312

13131313
GenericSignature getOverrideGenericSignature(const ValueDecl *base,
13141314
const ValueDecl *derived);

‎include/swift/AST/GenericEnvironment.h

+18-3
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,28 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
158158

159159
/// Create a new generic environment for an opened existential.
160160
///
161+
/// This function uses the provided parent signature to construct a new
162+
/// signature suitable for use with an opened archetype. If you have an
163+
/// existing generic signature from e.g. deserialization use
164+
/// \c GenericEnvironment::forOpenedArchetypeSignature instead.
165+
///
161166
/// \param existential The subject existential type
162-
/// \param useDC The decl context where this existential type is being opened
167+
/// \param parentSig The signature of the context where this existential type is being opened
163168
/// \param uuid The unique identifier for this opened existential
164169
static GenericEnvironment *
165-
forOpenedExistential(Type existential, const DeclContext *useDC, UUID uuid);
170+
forOpenedExistential(Type existential, GenericSignature parentSig, UUID uuid);
171+
172+
/// Create a new generic environment for an opened existential.
173+
///
174+
/// It is unlikely you want to use this function.
175+
/// Call \c GenericEnvironment::forOpenedExistential instead.
176+
///
177+
/// \param existential The subject existential type
178+
/// \param signature The signature of the opened archetype
179+
/// \param uuid The unique identifier for this opened existential
166180
static GenericEnvironment *
167-
forOpenedExistential(Type existential, GenericSignature signature, UUID uuid);
181+
forOpenedArchetypeSignature(Type existential,
182+
GenericSignature signature, UUID uuid);
168183

169184
/// Create a new generic environment for an opaque type with the given set of
170185
/// outer substitutions.

‎include/swift/AST/Types.h

+25-9
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ class alignas(1 << TypeAlignInBits) TypeBase
765765

766766
/// Opens an existential instance or meta-type and returns the opened type.
767767
Type openAnyExistentialType(OpenedArchetypeType *&opened,
768-
const DeclContext *useDC);
768+
GenericSignature parentSig);
769769

770770
/// Break an existential down into a set of constraints.
771771
ExistentialLayout getExistentialLayout();
@@ -5748,51 +5748,67 @@ class OpenedArchetypeType final : public ArchetypeType,
57485748

57495749
public:
57505750
/// Compute the parameter that serves as the \c Self type for an opened
5751-
/// archetype from the given declaration context.
5751+
/// archetype from the given outer generic signature.
57525752
///
5753-
/// For protocol extensions, this type is the context's \c Self type. For
5754-
/// all other contexts, this type is a generic parameter one level deeper
5753+
/// This type is a generic parameter one level deeper
57555754
/// than the deepest generic context depth.
5756-
static Type getSelfInterfaceTypeFromContext(const DeclContext *useDC);
5755+
static Type getSelfInterfaceTypeFromContext(GenericSignature parentSig,
5756+
ASTContext &ctx);
57575757

57585758
public:
57595759
/// Get or create an archetype that represents the opened type
57605760
/// of an existential value.
57615761
///
57625762
/// \param existential The existential type to open.
5763+
/// \param parentSig The generic signature of the context opening
5764+
/// this existential.
57635765
///
57645766
/// \param knownID When non-empty, the known ID of the archetype. When empty,
57655767
/// a fresh archetype with a unique ID will be opened.
57665768
static CanTypeWrapper<OpenedArchetypeType> get(CanType existential,
5767-
const DeclContext *useDC,
5769+
GenericSignature parentSig,
57685770
Optional<UUID> knownID = None);
57695771

57705772
/// Get or create an archetype that represents the opened type
57715773
/// of an existential value.
57725774
///
57735775
/// \param existential The existential type to open.
57745776
/// \param interfaceType The interface type represented by this archetype.
5777+
/// \param parentSig The generic signature of the context opening
5778+
/// this existential.
57755779
///
57765780
/// \param knownID When non-empty, the known ID of the archetype. When empty,
57775781
/// a fresh archetype with a unique ID will be opened.
57785782
static CanTypeWrapper<OpenedArchetypeType> get(CanType existential,
57795783
Type interfaceType,
5780-
const DeclContext *useDC,
5784+
GenericSignature parentSig,
57815785
Optional<UUID> knownID = None);
57825786

57835787
/// Create a new archetype that represents the opened type
57845788
/// of an existential value.
57855789
///
5790+
/// Use this function when you are unsure of whether the
5791+
/// \c existential type is a metatype or an instance type. This function
5792+
/// will unwrap any existential metatype containers.
5793+
///
57865794
/// \param existential The existential type or existential metatype to open.
57875795
/// \param interfaceType The interface type represented by this archetype.
5796+
/// \param parentSig The generic signature of the context opening
5797+
/// this existential.
57885798
static CanType getAny(CanType existential, Type interfaceType,
5789-
const DeclContext *useDC);
5799+
GenericSignature parentSig);
57905800

57915801
/// Create a new archetype that represents the opened type
57925802
/// of an existential value.
57935803
///
5804+
/// Use this function when you are unsure of whether the
5805+
/// \c existential type is a metatype or an instance type. This function
5806+
/// will unwrap any existential metatype containers.
5807+
///
57945808
/// \param existential The existential type or existential metatype to open.
5795-
static CanType getAny(CanType existential, const DeclContext *useDC);
5809+
/// \param parentSig The generic signature of the context opening
5810+
/// this existential.
5811+
static CanType getAny(CanType existential, GenericSignature parentSig);
57965812

57975813
/// Retrieve the ID number of this opened existential.
57985814
UUID getOpenedExistentialID() const;

‎include/swift/SIL/SILCloner.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
254254

255255
auto sig = archetypeTy->getGenericEnvironment()->getGenericSignature();
256256
auto existentialTy = archetypeTy->getExistentialType()->getCanonicalType();
257-
auto env = GenericEnvironment::forOpenedExistential(
257+
auto env = GenericEnvironment::forOpenedArchetypeSignature(
258258
getOpASTType(existentialTy), sig, UUID::fromTime());
259259
auto replacementTy =
260260
env->mapTypeIntoContext(archetypeTy->getInterfaceType())

‎include/swift/SIL/SILFunction.h

+4
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,10 @@ class SILFunction
10491049
GenericEnv = env;
10501050
}
10511051

1052+
/// Retrieve the generic signature from the generic environment of this
1053+
/// function, if any. Else returns the null \c GenericSignature.
1054+
GenericSignature getGenericSignature() const;
1055+
10521056
/// Map the given type, which is based on an interface SILFunctionType and may
10531057
/// therefore be dependent, to a type based on the context archetypes of this
10541058
/// SILFunction.

‎lib/AST/ASTContext.cpp

+36-51
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ struct ASTContext::Implementation {
328328
CanGenericSignature SingleGenericParameterSignature;
329329

330330
/// The existential signature <T : P> for each P.
331-
llvm::DenseMap<std::pair<CanType, const DeclContext *>, CanGenericSignature>
331+
llvm::DenseMap<std::pair<CanType, const GenericSignatureImpl *>, CanGenericSignature>
332332
ExistentialSignatures;
333333

334334
/// Overridden declarations.
@@ -4441,17 +4441,18 @@ CanTypeWrapper<OpenedArchetypeType> OpenedArchetypeType::getNew(
44414441
}
44424442

44434443
CanTypeWrapper<OpenedArchetypeType>
4444-
OpenedArchetypeType::get(CanType existential, const DeclContext *useDC,
4444+
OpenedArchetypeType::get(CanType existential, GenericSignature parentSig,
44454445
Optional<UUID> knownID) {
4446-
return get(existential,
4447-
OpenedArchetypeType::getSelfInterfaceTypeFromContext(useDC),
4448-
useDC, knownID);
4446+
assert(existential->isExistentialType());
4447+
auto interfaceType = OpenedArchetypeType::getSelfInterfaceTypeFromContext(parentSig, existential->getASTContext());
4448+
return get(existential, interfaceType, parentSig, knownID);
44494449
}
44504450

44514451
CanOpenedArchetypeType OpenedArchetypeType::get(CanType existential,
44524452
Type interfaceType,
4453-
const DeclContext *useDC,
4453+
GenericSignature parentSig,
44544454
Optional<UUID> knownID) {
4455+
assert(existential->isExistentialType());
44554456
assert(!interfaceType->hasArchetype() && "must be interface type");
44564457
// FIXME: Opened archetypes can't be transformed because the
44574458
// the identity of the archetype has to be preserved. This
@@ -4485,7 +4486,7 @@ CanOpenedArchetypeType OpenedArchetypeType::get(CanType existential,
44854486

44864487
/// Create a generic environment for this opened archetype.
44874488
auto genericEnv =
4488-
GenericEnvironment::forOpenedExistential(existential, useDC, *knownID);
4489+
GenericEnvironment::forOpenedExistential(existential, parentSig, *knownID);
44894490
openedExistentialEnvironments[*knownID] = genericEnv;
44904491

44914492
// Map the interface type into that environment.
@@ -4495,22 +4496,22 @@ CanOpenedArchetypeType OpenedArchetypeType::get(CanType existential,
44954496
}
44964497

44974498
CanType OpenedArchetypeType::getAny(CanType existential, Type interfaceType,
4498-
const DeclContext *useDC) {
4499+
GenericSignature parentSig) {
4500+
assert(existential->isAnyExistentialType());
44994501
if (auto metatypeTy = existential->getAs<ExistentialMetatypeType>()) {
45004502
auto instanceTy =
45014503
metatypeTy->getExistentialInstanceType()->getCanonicalType();
45024504
return CanMetatypeType::get(
4503-
OpenedArchetypeType::getAny(instanceTy, interfaceType, useDC));
4505+
OpenedArchetypeType::getAny(instanceTy, interfaceType, parentSig));
45044506
}
45054507
assert(existential->isExistentialType());
4506-
return OpenedArchetypeType::get(existential, interfaceType, useDC);
4508+
return OpenedArchetypeType::get(existential, interfaceType, parentSig);
45074509
}
45084510

45094511
CanType OpenedArchetypeType::getAny(CanType existential,
4510-
const DeclContext *useDC) {
4511-
return getAny(existential,
4512-
OpenedArchetypeType::getSelfInterfaceTypeFromContext(useDC),
4513-
useDC);
4512+
GenericSignature parentSig) {
4513+
auto interfaceTy = OpenedArchetypeType::getSelfInterfaceTypeFromContext(parentSig, existential->getASTContext());
4514+
return getAny(existential, interfaceTy, parentSig);
45144515
}
45154516

45164517
void SubstitutionMap::Storage::Profile(
@@ -4666,19 +4667,14 @@ GenericEnvironment *GenericEnvironment::getIncomplete(
46664667

46674668
/// Create a new generic environment for an opened archetype.
46684669
GenericEnvironment *
4669-
GenericEnvironment::forOpenedExistential(Type existential,
4670-
const DeclContext *useDC, UUID uuid) {
4670+
GenericEnvironment::forOpenedExistential(
4671+
Type existential, GenericSignature parentSig, UUID uuid) {
46714672
auto &ctx = existential->getASTContext();
4672-
auto signature = ctx.getOpenedArchetypeSignature(existential, useDC);
4673-
4674-
SubstitutionMap subs;
4675-
if (auto *useEnvironment = useDC->getGenericEnvironmentOfContext()) {
4676-
subs = useEnvironment->getForwardingSubstitutionMap();
4677-
}
4678-
return GenericEnvironment::forOpenedExistential(existential, signature, uuid);
4673+
auto signature = ctx.getOpenedArchetypeSignature(existential, parentSig);
4674+
return GenericEnvironment::forOpenedArchetypeSignature(existential, signature, uuid);
46794675
}
46804676

4681-
GenericEnvironment *GenericEnvironment::forOpenedExistential(
4677+
GenericEnvironment *GenericEnvironment::forOpenedArchetypeSignature(
46824678
Type existential, GenericSignature signature, UUID uuid) {
46834679
// Allocate and construct the new environment.
46844680
auto &ctx = existential->getASTContext();
@@ -5187,22 +5183,19 @@ CanGenericSignature ASTContext::getSingleGenericParameterSignature() const {
51875183
return canonicalSig;
51885184
}
51895185

5190-
Type OpenedArchetypeType::getSelfInterfaceTypeFromContext(const DeclContext *useDC) {
5191-
auto typeContext = useDC->getInnermostTypeContext();
5192-
if (typeContext && typeContext->getSelfProtocolDecl()) {
5193-
return typeContext->getProtocolSelfType();
5194-
} else {
5195-
return GenericTypeParamType::get(
5196-
/*isTypeSequence=*/false,
5197-
/*depth*/ useDC->getGenericContextDepth() + 1, /*index*/ 0,
5198-
useDC->getASTContext());
5199-
}
5186+
Type OpenedArchetypeType::getSelfInterfaceTypeFromContext(GenericSignature parentSig,
5187+
ASTContext &ctx) {
5188+
unsigned depth = 0;
5189+
if (!parentSig.getGenericParams().empty())
5190+
depth = parentSig.getGenericParams().back()->getDepth() + 1;
5191+
return GenericTypeParamType::get(/*isTypeSequence=*/ false,
5192+
/*depth=*/ depth, /*index=*/ 0,
5193+
ctx);
52005194
}
52015195

52025196
CanGenericSignature
5203-
ASTContext::getOpenedArchetypeSignature(Type type, const DeclContext *useDC) {
5197+
ASTContext::getOpenedArchetypeSignature(Type type, GenericSignature parentSig) {
52045198
assert(type->isExistentialType());
5205-
assert(useDC && "Must have a working declaration context!");
52065199

52075200
if (auto existential = type->getAs<ExistentialType>())
52085201
type = existential->getConstraintType();
@@ -5213,7 +5206,7 @@ ASTContext::getOpenedArchetypeSignature(Type type, const DeclContext *useDC) {
52135206
// The opened archetype signature for a protocol type is identical
52145207
// to the protocol's own canonical generic signature if there aren't any
52155208
// outer generic parameters to worry about.
5216-
if (!useDC->isGenericContext()) {
5209+
if (parentSig.isNull()) {
52175210
if (const auto protoTy = dyn_cast<ProtocolType>(constraint)) {
52185211
return protoTy->getDecl()->getGenericSignature().getCanonicalSignature();
52195212
}
@@ -5222,31 +5215,23 @@ ASTContext::getOpenedArchetypeSignature(Type type, const DeclContext *useDC) {
52225215
// Otherwise we need to build a generic signature that captures any outer
52235216
// generic parameters. This ensures that we keep e.g. generic superclass
52245217
// existentials contained in a well-formed generic context.
5225-
auto found = getImpl().ExistentialSignatures.find({constraint, useDC});
5218+
auto canParentSig = parentSig.getCanonicalSignature();
5219+
auto found = getImpl().ExistentialSignatures.find({constraint, canParentSig.getPointer()});
52265220
if (found != getImpl().ExistentialSignatures.end())
52275221
return found->second;
52285222

5229-
GenericSignature outerSignature;
5230-
auto *typeContext = useDC->getInnermostTypeContext();
5231-
if (typeContext && typeContext->getSelfProtocolDecl()) {
5232-
outerSignature = GenericSignature();
5233-
} else {
5234-
outerSignature = useDC->getGenericSignatureOfContext();
5235-
}
5236-
5237-
auto genericParam = OpenedArchetypeType::getSelfInterfaceTypeFromContext(useDC)
5238-
->getCanonicalType()->getAs<GenericTypeParamType>();
5239-
5223+
auto genericParam = OpenedArchetypeType::getSelfInterfaceTypeFromContext(canParentSig, type->getASTContext())
5224+
->castTo<GenericTypeParamType>();
52405225
Requirement requirement(RequirementKind::Conformance, genericParam,
52415226
constraint);
52425227
auto genericSig = buildGenericSignature(
5243-
*this, outerSignature.getCanonicalSignature(),
5228+
*this, canParentSig,
52445229
{genericParam}, {requirement});
52455230

52465231
CanGenericSignature canGenericSig(genericSig);
52475232

52485233
auto result = getImpl().ExistentialSignatures.insert(
5249-
std::make_pair(std::make_pair(constraint, useDC), canGenericSig));
5234+
std::make_pair(std::make_pair(constraint, canParentSig.getPointer()), canGenericSig));
52505235
assert(result.second);
52515236
(void) result;
52525237

‎lib/AST/Decl.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -4100,7 +4100,8 @@ GenericParameterReferenceInfo ValueDecl::findExistentialSelfReferences(
41004100
return GenericParameterReferenceInfo();
41014101

41024102
const auto sig =
4103-
getASTContext().getOpenedArchetypeSignature(baseTy, useDC);
4103+
getASTContext().getOpenedArchetypeSignature(baseTy,
4104+
useDC->getGenericSignatureOfContext());
41044105
auto genericParam = sig.getGenericParams().front();
41054106
return findGenericParameterReferences(
41064107
this, sig, genericParam, treatNonResultCovariantSelfAsInvariant, None);

‎lib/AST/GenericSignature.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ bool GenericSignatureImpl::isValidTypeInContext(Type type) const {
472472

473473
ArrayRef<CanTypeWrapper<GenericTypeParamType>>
474474
CanGenericSignature::getGenericParams() const {
475-
auto params = getPointer()->getGenericParams().getOriginalArray();
475+
auto params = this->GenericSignature::getGenericParams().getOriginalArray();
476476
auto base = static_cast<const CanTypeWrapper<GenericTypeParamType>*>(
477477
params.data());
478478
return {base, params.size()};

‎lib/AST/Type.cpp

+9-6
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ Type TypeBase::typeEraseOpenedArchetypesWithRoot(
480480
return type;
481481

482482
const auto sig = root->getASTContext().getOpenedArchetypeSignature(
483-
root->getExistentialType(), useDC);
483+
root->getExistentialType(), useDC->getGenericSignatureOfContext());
484484

485485
unsigned metatypeDepth = 0;
486486

@@ -4008,7 +4008,8 @@ CanType ProtocolCompositionType::getMinimalCanonicalType(
40084008

40094009
// Use generic signature minimization: the requirements of the signature will
40104010
// represent the minimal composition.
4011-
const auto Sig = Ctx.getOpenedArchetypeSignature(CanTy, useDC);
4011+
auto sig = useDC->getGenericSignatureOfContext();
4012+
const auto Sig = Ctx.getOpenedArchetypeSignature(CanTy, sig);
40124013
const auto &Reqs = Sig.getRequirements();
40134014
if (Reqs.size() == 1) {
40144015
return Reqs.front().getSecondType()->getCanonicalType();
@@ -4017,7 +4018,7 @@ CanType ProtocolCompositionType::getMinimalCanonicalType(
40174018
Type superclass;
40184019
llvm::SmallVector<Type, 2> MinimalMembers;
40194020
bool MinimalHasExplicitAnyObject = false;
4020-
auto ifaceTy = OpenedArchetypeType::getSelfInterfaceTypeFromContext(useDC);
4021+
auto ifaceTy = Sig.getGenericParams().back();
40214022
for (const auto &Req : Reqs) {
40224023
if (!Req.getFirstType()->isEqual(ifaceTy)) {
40234024
continue;
@@ -5994,17 +5995,19 @@ SILBoxType::SILBoxType(ASTContext &C,
59945995
}
59955996

59965997
Type TypeBase::openAnyExistentialType(OpenedArchetypeType *&opened,
5997-
const DeclContext *useDC) {
5998+
GenericSignature parentSig) {
59985999
assert(isAnyExistentialType());
59996000
if (auto metaty = getAs<ExistentialMetatypeType>()) {
60006001
opened = OpenedArchetypeType::get(
6001-
metaty->getExistentialInstanceType()->getCanonicalType(), useDC);
6002+
metaty->getExistentialInstanceType()->getCanonicalType(),
6003+
parentSig.getCanonicalSignature());
60026004
if (metaty->hasRepresentation())
60036005
return MetatypeType::get(opened, metaty->getRepresentation());
60046006
else
60056007
return MetatypeType::get(opened);
60066008
}
6007-
opened = OpenedArchetypeType::get(getCanonicalType(), useDC);
6009+
opened = OpenedArchetypeType::get(getCanonicalType(),
6010+
parentSig.getCanonicalSignature());
60086011
return opened;
60096012
}
60106013

0 commit comments

Comments
 (0)