Skip to content

Commit 279d4e6

Browse files
committed
SIL: Preliminary AbstractionPattern support for PackElementType
1 parent eb8d935 commit 279d4e6

File tree

2 files changed

+70
-14
lines changed

2 files changed

+70
-14
lines changed

include/swift/SIL/AbstractionPattern.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -938,10 +938,9 @@ class AbstractionPattern {
938938
case Kind::Discard: {
939939
auto type = getType();
940940
if (isa<DependentMemberType>(type) ||
941-
isa<GenericTypeParamType>(type)) {
942-
return true;
943-
}
944-
if (isa<ArchetypeType>(type)) {
941+
isa<GenericTypeParamType>(type) ||
942+
isa<PackElementType>(type) ||
943+
isa<ArchetypeType>(type)) {
945944
return true;
946945
}
947946
return false;
@@ -960,7 +959,8 @@ class AbstractionPattern {
960959
case Kind::Discard: {
961960
auto type = getType();
962961
if (isa<DependentMemberType>(type) ||
963-
isa<GenericTypeParamType>(type)) {
962+
isa<GenericTypeParamType>(type) ||
963+
isa<PackElementType>(type)) {
964964
return true;
965965
}
966966
if (auto archetype = dyn_cast<ArchetypeType>(type)) {
@@ -1448,6 +1448,10 @@ class AbstractionPattern {
14481448
/// the abstraction pattern for an element type.
14491449
AbstractionPattern getTupleElementType(unsigned index) const;
14501450

1451+
/// Given that the value being abstracted is a pack element type, return
1452+
/// the abstraction pattern for its pack type.
1453+
AbstractionPattern getPackElementPackType() const;
1454+
14511455
/// Given that the value being abstracted is a pack type, return
14521456
/// the abstraction pattern for an element type.
14531457
AbstractionPattern getPackElementType(unsigned index) const;

lib/SIL/IR/AbstractionPattern.cpp

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "swift/AST/ModuleLoader.h"
2626
#include "swift/AST/TypeCheckRequests.h"
2727
#include "swift/AST/CanTypeVisitor.h"
28+
#include "swift/Basic/Defer.h"
2829
#include "swift/SIL/TypeLowering.h"
2930
#include "swift/SIL/AbstractionPatternGenerators.h"
3031
#include "clang/AST/ASTContext.h"
@@ -234,6 +235,8 @@ bool AbstractionPattern::requiresClass() const {
234235
case Kind::Discard:
235236
case Kind::ClangType: {
236237
auto type = getType();
238+
if (auto element = dyn_cast<PackElementType>(type))
239+
type = element.getPackType();
237240
if (auto archetype = dyn_cast<ArchetypeType>(type))
238241
return archetype->requiresClass();
239242
if (type->isTypeParameter()) {
@@ -616,6 +619,40 @@ void AbstractionPattern::forEachExpandedTupleElement(CanType substType,
616619
assert(substEltIndex == substEltTypes.size());
617620
}
618621

622+
AbstractionPattern
623+
AbstractionPattern::getPackElementPackType() const {
624+
switch (getKind()) {
625+
case Kind::Invalid:
626+
llvm_unreachable("querying invalid abstraction pattern!");
627+
case Kind::PartialCurriedObjCMethodType:
628+
case Kind::CurriedObjCMethodType:
629+
case Kind::PartialCurriedCFunctionAsMethodType:
630+
case Kind::CurriedCFunctionAsMethodType:
631+
case Kind::CFunctionAsMethodType:
632+
case Kind::ObjCMethodType:
633+
case Kind::CXXMethodType:
634+
case Kind::CurriedCXXMethodType:
635+
case Kind::PartialCurriedCXXMethodType:
636+
case Kind::OpaqueFunction:
637+
case Kind::OpaqueDerivativeFunction:
638+
case Kind::ClangType:
639+
case Kind::Tuple:
640+
case Kind::ObjCCompletionHandlerArgumentsType:
641+
llvm_unreachable("not a pack type");
642+
case Kind::Opaque:
643+
return *this;
644+
case Kind::Discard:
645+
llvm_unreachable("operation not needed on discarded abstractions yet");
646+
case Kind::Type:
647+
if (isTypeParameterOrOpaqueArchetype())
648+
return AbstractionPattern::getOpaque();
649+
return AbstractionPattern(getGenericSubstitutions(),
650+
getGenericSignature(),
651+
cast<PackElementType>(getType()).getPackType());
652+
}
653+
llvm_unreachable("bad kind");
654+
}
655+
619656
static CanType getCanPackElementType(CanType type, unsigned index) {
620657
return cast<PackType>(type).getElementType(index);
621658
}
@@ -1905,31 +1942,34 @@ class SubstFunctionTypePatternVisitor
19051942
SmallVector<Requirement, 2> substRequirements;
19061943
SmallVector<Type, 2> substReplacementTypes;
19071944
CanType substYieldType;
1908-
bool WithinExpansion = false;
1945+
unsigned packExpansionLevel;
19091946

19101947
SubstFunctionTypePatternVisitor(TypeConverter &TC)
1911-
: TC(TC) {}
1948+
: TC(TC), packExpansionLevel(0) {}
19121949

19131950
// Creates and returns a fresh type parameter in the substituted generic
19141951
// signature if `pattern` is a type parameter or opaque archetype. Returns
19151952
// null otherwise.
1916-
CanType handleTypeParameter(AbstractionPattern pattern, CanType substTy) {
1953+
CanType handleTypeParameter(AbstractionPattern pattern, CanType substTy,
1954+
unsigned level) {
19171955
if (!pattern.isTypeParameterOrOpaqueArchetype())
19181956
return CanType();
19191957

19201958
unsigned paramIndex = substGenericParams.size();
19211959

1960+
bool withinExpansion = (level < packExpansionLevel);
1961+
19221962
// Pack parameters that aren't within expansions should just be
19231963
// abstracted as scalars.
1924-
bool isParameterPack = (WithinExpansion && pattern.isTypeParameterPack());
1964+
bool isParameterPack = (withinExpansion && pattern.isTypeParameterPack());
19251965

19261966
auto gp = GenericTypeParamType::get(isParameterPack, 0, paramIndex,
19271967
TC.Context);
19281968
substGenericParams.push_back(gp);
19291969

19301970
CanType replacement;
19311971

1932-
if (WithinExpansion) {
1972+
if (withinExpansion) {
19331973
// If we're within an expansion, and there are substitutions in the
19341974
// abstraction pattern, use those instead of substTy. substTy is not
19351975
// contextually meaningful in this case; see handlePackExpansion.
@@ -2005,11 +2045,21 @@ class SubstFunctionTypePatternVisitor
20052045
}
20062046
}
20072047

2048+
if (level > 0)
2049+
return CanType(PackElementType::get(gp, level));
2050+
20082051
return CanType(gp);
20092052
}
20102053

20112054
CanType visit(CanType t, AbstractionPattern pattern) {
2012-
if (auto gp = handleTypeParameter(pattern, t))
2055+
unsigned level = 0;
2056+
if (auto elementType = dyn_cast<PackElementType>(t)) {
2057+
level = elementType->getLevel();
2058+
t = elementType.getPackType();
2059+
pattern = pattern.getPackElementPackType();
2060+
}
2061+
2062+
if (auto gp = handleTypeParameter(pattern, t, level))
20132063
return gp;
20142064

20152065
return CanTypeVisitor::visit(t, pattern);
@@ -2180,9 +2230,11 @@ class SubstFunctionTypePatternVisitor
21802230
// the pack substitution for that parameter recorded in the pattern.
21812231

21822232
// Remember that we're within an expansion.
2183-
// FIXME: when we introduce PackElementType we'll need to be clear
2184-
// about which pack expansions to treat this way.
2185-
llvm::SaveAndRestore<bool> scope(WithinExpansion, true);
2233+
++packExpansionLevel;
2234+
2235+
SWIFT_DEFER {
2236+
--packExpansionLevel;
2237+
};
21862238

21872239
auto origPatternType = origExpansion.getPackExpansionPatternType();
21882240

0 commit comments

Comments
 (0)