Skip to content

Commit e6253b2

Browse files
committed
AST: Re-implement mapPackTypeIntoElementContext() in terms of mapContextualPackTypeIntoElementContext()
1 parent b011215 commit e6253b2

File tree

2 files changed

+26
-28
lines changed

2 files changed

+26
-28
lines changed

lib/AST/GenericEnvironment.cpp

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,10 @@ Type GenericEnvironment::mapTypeIntoContext(GenericTypeParamType *type) const {
659659
return result;
660660
}
661661

662+
/// So this expects a type written with the archetypes of the original generic
663+
/// environment, not 'this', the opened element environment, because it is the
664+
/// original PackArchetypes that become ElementArchetypes. Also this function
665+
/// does not apply outer substitutions, which might not be what you expect.
662666
Type
663667
GenericEnvironment::mapContextualPackTypeIntoElementContext(Type type) const {
664668
assert(getKind() == Kind::OpenedElement);
@@ -689,41 +693,23 @@ GenericEnvironment::mapContextualPackTypeIntoElementContext(CanType type) const
689693
return CanType(mapContextualPackTypeIntoElementContext(Type(type)));
690694
}
691695

696+
/// Unlike mapContextualPackTypeIntoElementContext(), this also applies outer
697+
/// substitutions, so it behaves like mapTypeIntoContext() in that respect.
692698
Type
693699
GenericEnvironment::mapPackTypeIntoElementContext(Type type) const {
694700
assert(getKind() == Kind::OpenedElement);
695701
assert(!type->hasArchetype());
696702

697-
auto sig = getGenericSignature();
698-
auto shapeClass = getOpenedElementShapeClass();
699-
700-
FindElementArchetypeForOpenedPackParam
701-
findElementArchetype(this, getOpenedPackParams());
702-
703-
// Map the interface type to the element type by stripping
704-
// away the isParameterPack bit before mapping type parameters
705-
// to archetypes.
706-
return type.transformRec([&](TypeBase *ty) -> llvm::Optional<Type> {
707-
// We're only directly substituting pack parameters.
708-
if (!ty->isTypeParameter()) {
709-
// Don't recurse into nested pack expansions; just map it into
710-
// context.
711-
if (ty->is<PackExpansionType>())
712-
return mapTypeIntoContext(ty);
713-
714-
// Recurse into any other type.
715-
return llvm::None;
716-
}
703+
if (!type->hasTypeParameter()) return type;
717704

718-
// Just do normal mapping for types that are not rooted in
719-
// opened type parameters.
720-
auto rootParam = ty->getRootGenericParam();
721-
if (!rootParam->isParameterPack() ||
722-
!sig->haveSameShape(rootParam, shapeClass))
723-
return mapTypeIntoContext(ty);
705+
// Get a contextual type in the original generic environment, not the
706+
// substituted one, which is what mapContextualPackTypeIntoElementContext()
707+
// expects.
708+
auto contextualType = getPackElementContextSubstitutions()
709+
.getGenericSignature().getGenericEnvironment()->mapTypeIntoContext(type);
724710

725-
return Type(findElementArchetype(ty));
726-
});
711+
contextualType = mapContextualPackTypeIntoElementContext(contextualType);
712+
return maybeApplyOuterContextSubstitutions(contextualType);
727713
}
728714

729715
Type
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %target-swift-frontend -emit-ir %s -disable-availability-checking
2+
3+
public protocol P {
4+
associatedtype A
5+
}
6+
7+
public struct G<each T> {}
8+
9+
public struct S<T: P, each U: P> where repeat T.A == G<repeat each U> {
10+
public init(predicate: repeat each U) {}
11+
}
12+

0 commit comments

Comments
 (0)