Skip to content

Commit 1cf7d51

Browse files
committed
SIL: Stub out type lowering of function types containing pack expansions
1 parent 1020b70 commit 1cf7d51

File tree

3 files changed

+49
-4
lines changed

3 files changed

+49
-4
lines changed

include/swift/SIL/AbstractionPattern.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,20 @@ class AbstractionPattern {
933933
return false;
934934
}
935935
}
936+
937+
bool isTypeParameterPack() const {
938+
switch (getKind()) {
939+
case Kind::Opaque:
940+
return false;
941+
case Kind::Type:
942+
case Kind::ClangType:
943+
case Kind::Discard: {
944+
return getType()->isParameterPack();
945+
}
946+
default:
947+
return false;
948+
}
949+
}
936950

937951
/// Is this an interface type that is subject to a concrete
938952
/// same-type constraint?

lib/SIL/IR/AbstractionPattern.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,7 +1584,15 @@ class SubstFunctionTypePatternVisitor
15841584
// If so, let's put a fresh generic parameter in the substituted signature
15851585
// here.
15861586
unsigned paramIndex = substGenericParams.size();
1587-
auto gp = GenericTypeParamType::get(false, 0, paramIndex, TC.Context);
1587+
1588+
bool isParameterPack = false;
1589+
if (substTy->isParameterPack() || substTy->is<PackArchetypeType>())
1590+
isParameterPack = true;
1591+
else if (pattern.isTypeParameterPack())
1592+
isParameterPack = true;
1593+
1594+
auto gp = GenericTypeParamType::get(isParameterPack, 0, paramIndex,
1595+
TC.Context);
15881596
substGenericParams.push_back(gp);
15891597
substReplacementTypes.push_back(substTy);
15901598

@@ -1881,11 +1889,30 @@ class SubstFunctionTypePatternVisitor
18811889
}
18821890

18831891
CanType visitPackType(PackType *pack, AbstractionPattern pattern) {
1884-
llvm_unreachable("Unimplemented!");
1892+
if (auto gp = handleTypeParameterInAbstractionPattern(pattern, pack))
1893+
return gp;
1894+
1895+
// Break down the pack.
1896+
SmallVector<Type, 4> packElts;
1897+
for (unsigned i = 0; i < pack->getNumElements(); ++i) {
1898+
packElts.push_back(visit(pack->getElementType(i),
1899+
pattern.getPackElementType(i)));
1900+
}
1901+
1902+
return CanType(PackType::get(TC.Context, packElts));
18851903
}
18861904

1887-
CanType visitPackExpansionType(PackExpansionType *pack, AbstractionPattern pattern) {
1888-
llvm_unreachable("Unimplemented!");
1905+
CanType visitPackExpansionType(PackExpansionType *pack,
1906+
AbstractionPattern pattern) {
1907+
// Avoid walking into the pattern and count type if we can help it.
1908+
if (!pack->hasTypeParameter() && !pack->hasArchetype() &&
1909+
!pack->hasOpaqueArchetype()) {
1910+
return CanType(pack);
1911+
}
1912+
1913+
return CanType(PackExpansionType::get(
1914+
visit(pack->getPatternType(), pattern.getPackExpansionPatternType()),
1915+
visit(pack->getCountType(), pattern.getPackExpansionCountType())));
18891916
}
18901917

18911918
CanType visitExistentialType(ExistentialType *exist,

test/SILGen/pack_expansion_type.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,8 @@ public struct VariadicType<T...> {
1111
// CHECK-LABEL: sil [ossa] @$s19pack_expansion_type12VariadicTypeV14variadicMethod1t1ux_qd__txQp_txxQp_qd__qd__Qptqd__RhzlF : $@convention(method) <T...><U... where ((T, U)...) : Any> (@in_guaranteed T..., @in_guaranteed U..., VariadicType<T...>) -> @out (T, U)... {
1212
// CHECK: bb0(%0 : $*(T, U)..., %1 : $*T..., %2 : $*U..., %3 : $VariadicType<T...>):
1313
public func variadicMethod<U...>(t: T..., u: U...) -> ((T, U)...) {}
14+
15+
// CHECK-LABEL: sil [ossa] @$s19pack_expansion_type12VariadicTypeV13takesFunction1tyqd__qd__Qp_txxQpXE_tlF : $@convention(method) <T...><U...> (@noescape @callee_guaranteed @substituted <τ_0_0..., τ_0_1..., τ_0_2..., τ_0_3...> (@in_guaranteed τ_0_0...) -> @out τ_0_2... for <T, T, U, U>, VariadicType<T...>) -> () {
16+
// CHECK: bb0(%0 : $@noescape @callee_guaranteed @substituted <τ_0_0..., τ_0_1..., τ_0_2..., τ_0_3...> (@in_guaranteed τ_0_0...) -> @out τ_0_2... for <T, T, U, U>, %1 : $VariadicType<T...>):
17+
public func takesFunction<U...>(t: (T...) -> (U...)) {}
1418
}

0 commit comments

Comments
 (0)