Skip to content

Commit 1f78973

Browse files
committed
Sema: Form pack expansion types in simplifyTypeExpr()
1 parent 88688f2 commit 1f78973

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

lib/Sema/PreCheckExpr.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2018,6 +2018,16 @@ TypeExpr *PreCheckExpression::simplifyTypeExpr(Expr *E) {
20182018
return new (Ctx) TypeExpr(CompRepr);
20192019
}
20202020

2021+
// Fold 'T...' into a pack expansion type when 'T' is a TypeExpr.
2022+
if (auto *operand = isPostfixEllipsisOperator(E)) {
2023+
llvm::errs() << "folding "; operand->dump();
2024+
if (auto *pattern = dyn_cast<TypeExpr>(operand)) {
2025+
auto *repr = new (Ctx) PackExpansionTypeRepr(pattern->getTypeRepr(),
2026+
E->getLoc());
2027+
return new (Ctx) TypeExpr(repr);
2028+
}
2029+
}
2030+
20212031
return nullptr;
20222032
}
20232033

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-typecheck-verify-swift -enable-experimental-feature VariadicGenerics
2+
3+
// REQUIRES: asserts
4+
5+
// Parsing an UnresolvedSpecializeExpr containing a PackExpansionType
6+
struct G<T...> {}
7+
8+
func f<T...>(_: T...) {
9+
_ = G< >.self
10+
_ = G<Int>.self
11+
_ = G<Int, String>.self
12+
_ = G<T... >.self
13+
_ = G<Int, (Array<T>)... >.self
14+
}
15+
16+
// Forming PackExpansionTypeReprs in simplifyTypeExpr()
17+
func g<T...>(_: T...) {
18+
_ = (T...).self
19+
_ = (Int, T...).self
20+
_ = ((T...) -> ()).self
21+
_ = ((Int, (Array<T>)...) -> ()).self
22+
23+
_ = (Int...).self // expected-error {{variadic expansion 'Int' must contain at least one variadic generic parameter}}
24+
}
25+

test/SILGen/pack_expansion_type.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,29 @@ public struct VariadicType<T...> {
1515
// 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...>) -> () {
1616
// 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...>):
1717
public func takesFunction<U...>(t: (T...) -> (U...)) {}
18+
}
19+
20+
// CHECK-LABEL: sil hidden [ossa] @$s19pack_expansion_type17variadicMetatypesyyxxQplF : $@convention(thin) <T...> (@in_guaranteed T...) -> () {
21+
// CHECK: bb0(%0 : $*T...):
22+
// CHECK: metatype $@thin VariadicType<>.Type
23+
// CHECK: metatype $@thin VariadicType<Int>.Type
24+
// CHECK: metatype $@thin VariadicType<Int, String>.Type
25+
// CHECK: metatype $@thin VariadicType<T...>.Type
26+
// CHECK: metatype $@thin VariadicType<Int, Array<T>...>.Type
27+
// CHECK: metatype $@thin (T...).Type
28+
// CHECK: metatype $@thin (Int, Array<T>...).Type
29+
// CHECK: metatype $@thin ((T...) -> ()).Type
30+
// CHECK: metatype $@thin ((Int, Array<T>...) -> ()).Type
31+
// CHECK: return
32+
33+
func variadicMetatypes<T...>(_: T...) {
34+
_ = VariadicType< >.self
35+
_ = VariadicType<Int>.self
36+
_ = VariadicType<Int, String>.self
37+
_ = VariadicType<T... >.self
38+
_ = VariadicType<Int, (Array<T>)... >.self
39+
_ = (T...).self
40+
_ = (Int, (Array<T>)...).self
41+
_ = ((T...) -> ()).self
42+
_ = ((Int, (Array<T>)...) -> ()).self
1843
}

0 commit comments

Comments
 (0)