Skip to content

Commit c47f352

Browse files
committed
AST: Use new form of getOpenedExistentialSignature() in GenericEnvironment::forOpenedExistential()
1 parent e9cec9d commit c47f352

File tree

6 files changed

+53
-75
lines changed

6 files changed

+53
-75
lines changed

include/swift/SIL/SILCloner.h

Lines changed: 7 additions & 7 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
}

lib/AST/ASTContext.cpp

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5342,22 +5342,21 @@ CanTypeWrapper<OpenedArchetypeType> OpenedArchetypeType::getNew(
53425342

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

53515348
if (!knownID)
53525349
knownID = UUID::fromTime();
53535350

53545351
auto *genericEnv = GenericEnvironment::forOpenedExistential(
5355-
existential, *knownID);
5352+
existentialSig.OpenedSig,
5353+
existentialSig.Shape,
5354+
existentialSig.Generalization,
5355+
*knownID);
53565356

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

53635362
Type OpenedArchetypeType::getAny(Type existential) {
@@ -5547,8 +5546,10 @@ GenericEnvironment *GenericEnvironment::forOpaqueType(
55475546
GenericEnvironment *
55485547
GenericEnvironment::forOpenedExistential(Type existential, UUID uuid) {
55495548
auto &ctx = existential->getASTContext();
5550-
auto signature = ctx.getOpenedExistentialSignature(existential, GenericSignature());
5551-
return forOpenedExistential(signature, existential, SubstitutionMap(), uuid);
5549+
auto existentialSig = ctx.getOpenedExistentialSignature(existential);
5550+
return forOpenedExistential(existentialSig.OpenedSig,
5551+
existentialSig.Shape,
5552+
existentialSig.Generalization, uuid);
55525553
}
55535554

55545555
/// Create a new generic environment for an opened archetype.
@@ -6175,26 +6176,24 @@ OpenedExistentialSignature
61756176
ASTContext::getOpenedExistentialSignature(Type type) {
61766177
assert(type->isExistentialType());
61776178

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

61836181
// The constraint type might contain type variables.
6184-
auto properties = constraint->getRecursiveProperties();
6182+
auto properties = canType->getRecursiveProperties();
61856183
auto arena = getArena(properties);
61866184

61876185
// Check the cache.
61886186
const auto &sigs = getImpl().getArena(arena).ExistentialSignatures;
6189-
auto found = sigs.find(constraint);
6187+
auto found = sigs.find(canType);
61906188
if (found != sigs.end())
61916189
return found->second;
61926190

61936191
OpenedExistentialSignature existentialSig;
61946192

61956193
// Generalize the existential type, to move type variables and primary
61966194
// archetypes into the substitution map.
6197-
auto gen = ExistentialTypeGeneralization::get(constraint);
6195+
auto gen = ExistentialTypeGeneralization::get(canType);
6196+
61986197
existentialSig.Shape = gen.Shape->getCanonicalType();
61996198
existentialSig.Generalization = gen.Generalization;
62006199

@@ -6212,7 +6211,7 @@ ASTContext::getOpenedExistentialSignature(Type type) {
62126211

62136212
// Cache the result.
62146213
auto result = getImpl().getArena(arena).ExistentialSignatures.insert(
6215-
std::make_pair(constraint, existentialSig));
6214+
std::make_pair(canType, existentialSig));
62166215
ASSERT(result.second);
62176216

62186217
return existentialSig;

lib/AST/GenericEnvironment.cpp

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,9 @@ Type
295295
GenericEnvironment::maybeApplyOuterContextSubstitutions(Type type) const {
296296
switch (getKind()) {
297297
case Kind::Primary:
298-
case Kind::OpenedExistential:
299298
return type;
300299

300+
case Kind::OpenedExistential:
301301
case Kind::OpenedElement:
302302
case Kind::Opaque: {
303303
OuterSubstitutions replacer{
@@ -358,25 +358,8 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
358358
auto genericSig = getGenericSignature();
359359
auto requirements = genericSig->getLocalRequirements(depType);
360360

361-
/// Substitute a type for the purpose of requirements.
362-
auto substForRequirements = [&](Type type) {
363-
switch (getKind()) {
364-
case Kind::Primary:
365-
case Kind::OpenedExistential:
366-
if (type->hasTypeParameter()) {
367-
return mapTypeIntoContext(type, LookUpConformanceInModule());
368-
} else {
369-
return type;
370-
}
371-
case Kind::OpenedElement:
372-
case Kind::Opaque:
373-
return maybeApplyOuterContextSubstitutions(type);
374-
}
375-
};
376-
377-
if (requirements.concreteType) {
378-
return substForRequirements(requirements.concreteType);
379-
}
361+
if (requirements.concreteType)
362+
return mapTypeIntoContext(requirements.concreteType);
380363

381364
assert(requirements.anchor && "No anchor or concrete type?");
382365

@@ -404,7 +387,7 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
404387
// Substitute into the superclass.
405388
Type superclass = requirements.superclass;
406389
if (superclass && superclass->hasTypeParameter()) {
407-
superclass = substForRequirements(superclass);
390+
superclass = mapTypeIntoContext(superclass);
408391
if (superclass->is<ErrorType>())
409392
superclass = Type();
410393
}
@@ -428,14 +411,10 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
428411
break;
429412

430413
case Kind::Opaque: {
431-
assert(!rootGP->isParameterPack());
432-
433414
// If the anchor type isn't rooted in a generic parameter that
434415
// represents an opaque declaration, then apply the outer substitutions.
435416
// It would be incorrect to build an opaque type archetype here.
436-
unsigned opaqueDepth =
437-
getOpaqueTypeDecl()->getOpaqueGenericParams().front()->getDepth();
438-
if (rootGP->getDepth() < opaqueDepth) {
417+
if (rootGP->getDepth() < genericSig->getMaxDepth()) {
439418
result = maybeApplyOuterContextSubstitutions(requirements.anchor);
440419
break;
441420
}
@@ -447,7 +426,10 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
447426
}
448427

449428
case Kind::OpenedExistential: {
450-
assert(!rootGP->isParameterPack());
429+
if (rootGP->getDepth() < genericSig->getMaxDepth()) {
430+
result = maybeApplyOuterContextSubstitutions(requirements.anchor);
431+
break;
432+
}
451433

452434
// FIXME: The existential layout's protocols might differ from the
453435
// canonicalized set of protocols determined by the generic signature.
@@ -475,10 +457,7 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
475457
}
476458

477459
case Kind::OpenedElement: {
478-
auto packElements = getGenericSignature().getInnermostGenericParams();
479-
auto elementDepth = packElements.front()->getDepth();
480-
481-
if (rootGP->getDepth() < elementDepth) {
460+
if (rootGP->getDepth() < genericSig->getMaxDepth()) {
482461
result = maybeApplyOuterContextSubstitutions(requirements.anchor);
483462
break;
484463
}
@@ -536,9 +515,7 @@ Type GenericEnvironment::mapTypeIntoContext(
536515
Type result = type.subst(QueryInterfaceTypeSubstitutions(this),
537516
lookupConformance,
538517
SubstFlags::PreservePackExpansionLevel);
539-
assert((!result->hasTypeParameter() || result->hasError() ||
540-
getKind() == Kind::Opaque) &&
541-
"not fully substituted");
518+
ASSERT(getKind() != Kind::Primary || !result->hasTypeParameter());
542519
return result;
543520

544521
}

lib/AST/LocalArchetypeRequirementCollector.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,9 @@ GenericSignature swift::buildGenericSignatureWithCapturedEnvironments(
137137
break;
138138

139139
case GenericEnvironment::Kind::OpenedExistential: {
140-
auto existentialTy = genericEnv->getOpenedExistentialType()
141-
->mapTypeOutOfContext();
140+
auto existentialTy = genericEnv->maybeApplyOuterContextSubstitutions(
141+
genericEnv->getOpenedExistentialType())
142+
->mapTypeOutOfContext();
142143
collector.addOpenedExistential(existentialTy);
143144
continue;
144145
}

lib/AST/Type.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3389,7 +3389,8 @@ Type ArchetypeType::getExistentialType() const {
33893389
// Opened types hold this directly.
33903390
if (auto *opened = dyn_cast<OpenedArchetypeType>(this)) {
33913391
if (opened->isRoot()) {
3392-
return genericEnv->getOpenedExistentialType();
3392+
return genericEnv->maybeApplyOuterContextSubstitutions(
3393+
genericEnv->getOpenedExistentialType());
33933394
}
33943395
}
33953396

@@ -3398,10 +3399,7 @@ Type ArchetypeType::getExistentialType() const {
33983399
auto genericSig = genericEnv->getGenericSignature();
33993400

34003401
auto existentialType = genericSig->getExistentialType(interfaceType);
3401-
if (existentialType->hasTypeParameter())
3402-
existentialType = genericEnv->mapTypeIntoContext(existentialType);
3403-
3404-
return existentialType;
3402+
return genericEnv->maybeApplyOuterContextSubstitutions(existentialType);
34053403
}
34063404

34073405
bool ArchetypeType::requiresClass() const {

lib/Sema/TypeCheckType.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2854,18 +2854,21 @@ TypeResolver::resolveOpenedExistentialArchetype(
28542854

28552855
archetypeType = ErrorType::get(interfaceType->getASTContext());
28562856
} {
2857-
// The constraint type is written with respect to the surrounding
2858-
// generic environment.
2859-
constraintType = GenericEnvironment::mapTypeIntoContext(
2860-
resolution.getGenericSignature().getGenericEnvironment(),
2861-
constraintType);
2862-
28632857
// The opened existential type is formed by mapping the interface type
28642858
// into a new opened generic environment.
28652859
auto *env = GenericEnvironment::forOpenedExistential(
28662860
constraintType->getCanonicalType(),
28672861
openedAttr->getUUID());
2868-
return env->mapTypeIntoContext(interfaceType);
2862+
2863+
// Rewrite the interface type into one with the correct depth.
2864+
interfaceType = Type(interfaceType).subst(
2865+
[&](SubstitutableType *type) -> Type {
2866+
return env->getGenericSignature().getGenericParams().back();
2867+
},
2868+
MakeAbstractConformanceForGenericType());
2869+
2870+
archetypeType = env->mapTypeIntoContext(interfaceType);
2871+
ASSERT(archetypeType->is<OpenedArchetypeType>());
28692872
}
28702873

28712874
return archetypeType;

0 commit comments

Comments
 (0)