Skip to content

Commit 305e796

Browse files
committed
AST: Rewrite GenericEnvironment::mapElementTypeIntoPackContext()
We don't need to build a DenseMap here. More importantly, this changes the logic to avoid calling mapTypeOutOfContext() on element archetypes, instead doing the mapping directly.
1 parent 6a4f7ff commit 305e796

File tree

1 file changed

+32
-26
lines changed

1 file changed

+32
-26
lines changed

lib/AST/GenericEnvironment.cpp

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -718,52 +718,58 @@ GenericEnvironment::mapElementTypeIntoPackContext(Type type) const {
718718
// generic environment.
719719
assert(type->hasElementArchetype());
720720

721-
ElementArchetypeType *element = nullptr;
722-
type.visit([&](Type type) {
723-
auto archetype = type->getAs<ElementArchetypeType>();
724-
if (!element && archetype)
725-
element = archetype;
726-
});
721+
GenericEnvironment *elementEnv = nullptr;
727722

728-
auto sig = getGenericSignature();
729-
auto *elementEnv = element->getGenericEnvironment();
730-
auto shapeClass = elementEnv->getOpenedElementShapeClass();
731-
QueryInterfaceTypeSubstitutions substitutions(this);
723+
// Map element archetypes to interface types in the element generic
724+
// environment's signature.
725+
type = type.subst(
726+
[&](SubstitutableType *type) -> Type {
727+
auto *archetype = cast<ArchetypeType>(type);
732728

733-
type = type->mapTypeOutOfContext();
729+
if (isa<OpenedArchetypeType>(archetype))
730+
return archetype;
734731

735-
auto interfaceType = element->getInterfaceType();
732+
if (isa<ElementArchetypeType>(archetype)) {
733+
assert(!elementEnv ||
734+
elementEnv == archetype->getGenericEnvironment());
735+
elementEnv = archetype->getGenericEnvironment();
736+
}
736737

737-
llvm::SmallDenseMap<GenericParamKey, GenericTypeParamType *>
738-
packParamForElement;
739-
auto elementDepth = interfaceType->getRootGenericParam()->getDepth();
738+
return archetype->getInterfaceType();
739+
},
740+
MakeAbstractConformanceForGenericType(),
741+
SubstFlags::AllowLoweredTypes |
742+
SubstFlags::PreservePackExpansionLevel);
740743

744+
auto shapeClass = elementEnv->getOpenedElementShapeClass();
745+
746+
llvm::SmallVector<GenericTypeParamType *, 2> members;
747+
auto elementDepth = elementEnv->getGenericSignature()->getMaxDepth();
748+
749+
auto sig = getGenericSignature();
741750
for (auto *genericParam : sig.getGenericParams()) {
742751
if (!genericParam->isParameterPack())
743752
continue;
744753

745754
if (!sig->haveSameShape(genericParam, shapeClass))
746755
continue;
747756

748-
GenericParamKey elementKey(/*isParameterPack*/false,
749-
/*depth*/elementDepth,
750-
/*index*/packParamForElement.size());
751-
packParamForElement[elementKey] = genericParam;
757+
members.push_back(genericParam);
752758
}
753759

754-
// Map element archetypes to the pack archetypes by converting
755-
// element types to interface types and adding the isParameterPack
756-
// bit. Then, map type parameters to archetypes.
760+
// Map element interface types to pack archetypes.
761+
QueryInterfaceTypeSubstitutions mapIntoContext(this);
757762
return type.subst(
758763
[&](SubstitutableType *type) {
759764
auto *genericParam = type->getAs<GenericTypeParamType>();
760765
if (!genericParam)
761766
return Type();
762767

763-
if (auto *packParam = packParamForElement[{genericParam}])
764-
return substitutions(packParam);
765-
766-
return substitutions(genericParam);
768+
if (genericParam->getDepth() == elementDepth) {
769+
genericParam = members[genericParam->getIndex()];
770+
assert(genericParam->isParameterPack());
771+
}
772+
return mapIntoContext(genericParam);
767773
},
768774
LookUpConformanceInSignature(sig.getPointer()),
769775
SubstFlags::PreservePackExpansionLevel);

0 commit comments

Comments
 (0)