Skip to content

Commit 3f317a1

Browse files
authored
Merge pull request swiftlang#76216 from slavapestov/existential-signature-rework-part-2
Convert more callers to use new form of ASTContext::getOpenedExistentialSignature()
2 parents 0ea717a + 586a36a commit 3f317a1

15 files changed

+184
-159
lines changed

include/swift/AST/GenericEnvironment.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,21 @@ class alignas(1 << DeclAlignInBits) GenericEnvironment final
232232
/// Create a new generic environment for an opened existential.
233233
///
234234
/// \param existential The subject existential type
235+
/// \param uuid The unique identifier for this opened existential
236+
static GenericEnvironment *
237+
forOpenedExistential(Type existential, UUID uuid);
238+
239+
/// Create a new generic environment for an opened existential.
240+
///
241+
/// \param signature The opened existential signature
242+
/// \param existential The generalized existential type
235243
/// \param outerSubs The substitution map containing archetypes from the
236244
/// outer generic context
237245
/// \param uuid The unique identifier for this opened existential
238246
static GenericEnvironment *
239-
forOpenedExistential(Type existential, SubstitutionMap outerSubs, UUID uuid);
247+
forOpenedExistential(GenericSignature signature,
248+
Type existential, SubstitutionMap outerSubs,
249+
UUID uuid);
240250

241251
/// Create a new generic environment for an opened element.
242252
///

include/swift/AST/SubstitutionMap.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,19 @@ struct LookUpConformanceInOverrideSubs {
324324
ProtocolDecl *proto) const;
325325
};
326326

327+
// Substitute the outer generic parameters from a substitution map, ignoring
328+
/// inner generic parameters with a given depth.
329+
struct OuterSubstitutions {
330+
SubstitutionMap subs;
331+
unsigned depth;
332+
333+
bool isUnsubstitutedTypeParameter(Type type) const;
334+
Type operator()(SubstitutableType *type) const;
335+
ProtocolConformanceRef operator()(CanType dependentType,
336+
Type conformingReplacementType,
337+
ProtocolDecl *conformedProtocol) const;
338+
};
339+
327340
} // end namespace swift
328341

329342
namespace llvm {

include/swift/SIL/SILCloner.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
387387

388388
auto substExistentialTy = getOpASTType(origExistentialTy);
389389
auto *newEnv = GenericEnvironment::forOpenedExistential(
390-
substExistentialTy, subMap, UUID::fromTime());
390+
substExistentialTy, UUID::fromTime());
391391

392392
registerLocalArchetypeRemapping(origEnv, newEnv);
393393
}

lib/AST/ASTContext.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5351,9 +5351,8 @@ CanOpenedArchetypeType OpenedArchetypeType::get(CanType existential,
53515351
if (!knownID)
53525352
knownID = UUID::fromTime();
53535353

5354-
auto *genericEnv =
5355-
GenericEnvironment::forOpenedExistential(
5356-
existential, SubstitutionMap(), *knownID);
5354+
auto *genericEnv = GenericEnvironment::forOpenedExistential(
5355+
existential, *knownID);
53575356

53585357
// Map the interface type into that environment.
53595358
auto result = genericEnv->mapTypeIntoContext(interfaceType)
@@ -5544,10 +5543,19 @@ GenericEnvironment *GenericEnvironment::forOpaqueType(
55445543
return env;
55455544
}
55465545

5546+
/// Create a new generic environment for an opened archetype.
5547+
GenericEnvironment *
5548+
GenericEnvironment::forOpenedExistential(Type existential, UUID uuid) {
5549+
auto &ctx = existential->getASTContext();
5550+
auto signature = ctx.getOpenedExistentialSignature(existential, GenericSignature());
5551+
return forOpenedExistential(signature, existential, SubstitutionMap(), uuid);
5552+
}
5553+
55475554
/// Create a new generic environment for an opened archetype.
55485555
GenericEnvironment *
55495556
GenericEnvironment::forOpenedExistential(
5550-
Type existential, SubstitutionMap subs, UUID uuid) {
5557+
GenericSignature signature, Type existential,
5558+
SubstitutionMap subs, UUID uuid) {
55515559
assert(existential->isExistentialType());
55525560

55535561
// TODO: We could attempt to preserve type sugar in the substitution map.
@@ -5569,15 +5577,13 @@ GenericEnvironment::forOpenedExistential(
55695577
if (found != environments.end()) {
55705578
auto *existingEnv = found->second;
55715579
assert(existingEnv->getOpenedExistentialType()->isEqual(existential));
5580+
assert(existingEnv->getGenericSignature().getPointer() == signature.getPointer());
55725581
assert(existingEnv->getOuterSubstitutions() == subs);
55735582
assert(existingEnv->getOpenedExistentialUUID() == uuid);
55745583

55755584
return existingEnv;
55765585
}
55775586

5578-
auto parentSig = subs.getGenericSignature().getCanonicalSignature();
5579-
auto signature = ctx.getOpenedExistentialSignature(existential, parentSig);
5580-
55815587
// Allocate and construct the new environment.
55825588
unsigned numGenericParams = signature.getGenericParams().size();
55835589
size_t bytes = totalSizeToAlloc<SubstitutionMap,

lib/AST/ExistentialGeneralization.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ class Generalizer : public CanTypeVisitor<Generalizer, Type> {
8181
private:
8282
Type visitProtocolType(CanProtocolType type) {
8383
// Simple protocol types have no sub-structure.
84-
assert(!type.getParent() || !type.getParent()->isSpecialized());
8584
return type;
8685
}
8786

lib/AST/GenericEnvironment.cpp

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -291,48 +291,6 @@ GenericEnvironment::getMappingIfPresent(GenericParamKey key) const {
291291
return std::nullopt;
292292
}
293293

294-
namespace {
295-
296-
/// Substitute the outer generic parameters from a substitution map, ignoring
297-
/// innter generic parameters with a given depth.
298-
struct SubstituteOuterFromSubstitutionMap {
299-
SubstitutionMap subs;
300-
unsigned depth;
301-
302-
/// Whether this is a type parameter that should not be substituted.
303-
bool isUnsubstitutedTypeParameter(Type type) const {
304-
if (!type->isTypeParameter())
305-
return false;
306-
307-
if (auto depMemTy = type->getAs<DependentMemberType>())
308-
return isUnsubstitutedTypeParameter(depMemTy->getBase());
309-
310-
if (auto genericParam = type->getAs<GenericTypeParamType>())
311-
return genericParam->getDepth() >= depth;
312-
313-
return false;
314-
}
315-
316-
Type operator()(SubstitutableType *type) const {
317-
if (isUnsubstitutedTypeParameter(type))
318-
return Type(type);
319-
320-
return QuerySubstitutionMap{subs}(type);
321-
}
322-
323-
ProtocolConformanceRef operator()(CanType dependentType,
324-
Type conformingReplacementType,
325-
ProtocolDecl *conformedProtocol) const {
326-
if (isUnsubstitutedTypeParameter(dependentType))
327-
return ProtocolConformanceRef(conformedProtocol);
328-
329-
return LookUpConformanceInSubstitutionMap(subs)(
330-
dependentType, conformingReplacementType, conformedProtocol);
331-
}
332-
};
333-
334-
}
335-
336294
Type
337295
GenericEnvironment::maybeApplyOuterContextSubstitutions(Type type) const {
338296
switch (getKind()) {
@@ -342,10 +300,8 @@ GenericEnvironment::maybeApplyOuterContextSubstitutions(Type type) const {
342300

343301
case Kind::OpenedElement:
344302
case Kind::Opaque: {
345-
auto packElements = getGenericSignature().getInnermostGenericParams();
346-
auto elementDepth = packElements.front()->getDepth();
347-
SubstituteOuterFromSubstitutionMap replacer{
348-
getOuterSubstitutions(), elementDepth};
303+
OuterSubstitutions replacer{
304+
getOuterSubstitutions(), getGenericSignature()->getMaxDepth()};
349305
return type.subst(replacer, replacer);
350306
}
351307
}

lib/AST/LocalArchetypeRequirementCollector.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ LocalArchetypeRequirementCollector::LocalArchetypeRequirementCollector(
2929
: Context(ctx), OuterSig(sig), Depth(sig.getNextDepth()) {}
3030

3131
void LocalArchetypeRequirementCollector::addOpenedExistential(Type constraint) {
32+
if (auto existential = constraint->getAs<ExistentialType>())
33+
constraint = existential->getConstraintType();
34+
3235
assert(constraint->isConstraintType() ||
3336
constraint->getClassOrBoundGenericClass());
3437
assert(OuterSig || !constraint->hasTypeParameter() &&
@@ -134,10 +137,9 @@ GenericSignature swift::buildGenericSignatureWithCapturedEnvironments(
134137
break;
135138

136139
case GenericEnvironment::Kind::OpenedExistential: {
137-
auto constraint = genericEnv->getOpenedExistentialType();
138-
if (auto existential = constraint->getAs<ExistentialType>())
139-
constraint = existential->getConstraintType()->mapTypeOutOfContext();
140-
collector.addOpenedExistential(constraint);
140+
auto existentialTy = genericEnv->getOpenedExistentialType()
141+
->mapTypeOutOfContext();
142+
collector.addOpenedExistential(existentialTy);
141143
continue;
142144
}
143145
case GenericEnvironment::Kind::OpenedElement: {

lib/AST/SubstitutionMap.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,3 +666,35 @@ SubstitutionMap SubstitutionMap::mapIntoTypeExpansionContext(
666666
SubstFlags::SubstituteOpaqueArchetypes |
667667
SubstFlags::PreservePackExpansionLevel);
668668
}
669+
670+
bool OuterSubstitutions::isUnsubstitutedTypeParameter(Type type) const {
671+
if (!type->isTypeParameter())
672+
return false;
673+
674+
if (auto depMemTy = type->getAs<DependentMemberType>())
675+
return isUnsubstitutedTypeParameter(depMemTy->getBase());
676+
677+
if (auto genericParam = type->getAs<GenericTypeParamType>())
678+
return genericParam->getDepth() >= depth;
679+
680+
return false;
681+
}
682+
683+
Type OuterSubstitutions::operator()(SubstitutableType *type) const {
684+
if (isUnsubstitutedTypeParameter(type))
685+
return Type(type);
686+
687+
return QuerySubstitutionMap{subs}(type);
688+
}
689+
690+
ProtocolConformanceRef OuterSubstitutions::operator()(
691+
CanType dependentType,
692+
Type conformingReplacementType,
693+
ProtocolDecl *conformedProtocol) const {
694+
if (isUnsubstitutedTypeParameter(dependentType))
695+
return ProtocolConformanceRef(conformedProtocol);
696+
697+
return LookUpConformanceInSubstitutionMap(subs)(
698+
dependentType, conformingReplacementType, conformedProtocol);
699+
}
700+

lib/AST/Type.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3398,7 +3398,10 @@ Type ArchetypeType::getExistentialType() const {
33983398
auto genericSig = genericEnv->getGenericSignature();
33993399

34003400
auto existentialType = genericSig->getExistentialType(interfaceType);
3401-
return genericEnv->mapTypeIntoContext(existentialType);
3401+
if (existentialType->hasTypeParameter())
3402+
existentialType = genericEnv->mapTypeIntoContext(existentialType);
3403+
3404+
return existentialType;
34023405
}
34033406

34043407
bool ArchetypeType::requiresClass() const {

lib/SILOptimizer/Utils/Existential.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "swift/SILOptimizer/Utils/Existential.h"
1414
#include "swift/AST/ConformanceLookup.h"
15+
#include "swift/AST/LocalArchetypeRequirementCollector.h"
1516
#include "swift/AST/ProtocolConformance.h"
1617
#include "swift/Basic/Assertions.h"
1718
#include "swift/SIL/BasicBlockUtils.h"
@@ -250,15 +251,20 @@ void ConcreteExistentialInfo::initializeSubstitutionMap(
250251
// Construct a single-generic-parameter substitution map directly to the
251252
// ConcreteType with this existential's full list of conformances.
252253
//
253-
// NOTE: getOpenedExistentialSignature() generates the signature for passing an
254+
// NOTE: LocalArchetypeRequirementCollector generates the signature for passing an
254255
// opened existential as a generic parameter. No opened archetypes are
255256
// actually involved here--the API is only used as a convenient way to create
256257
// a substitution map. Since opened archetypes have different conformances
257258
// than their corresponding existential, ExistentialConformances needs to be
258259
// filtered when using it with this (phony) generic signature.
259-
CanGenericSignature ExistentialSig =
260-
M->getASTContext().getOpenedExistentialSignature(ExistentialType,
261-
GenericSignature());
260+
261+
auto &ctx = M->getASTContext();
262+
LocalArchetypeRequirementCollector collector(ctx, CanGenericSignature());
263+
collector.addOpenedExistential(ExistentialType);
264+
auto ExistentialSig = buildGenericSignature(
265+
ctx, collector.OuterSig, collector.Params, collector.Requirements,
266+
/*allowInverses=*/true).getCanonicalSignature();
267+
262268
ExistentialSubs = SubstitutionMap::get(
263269
ExistentialSig, [&](SubstitutableType *type) { return ConcreteType; },
264270
[&](CanType /*depType*/, Type /*replaceType*/,

0 commit comments

Comments
 (0)