Skip to content

Commit 78ae7ac

Browse files
committed
SILGen: Support for local function default argument captures
Fixes <https://bugs.swift.org/browse/SR-2189>, <rdar://problem/20796451>.
1 parent 533d41d commit 78ae7ac

File tree

3 files changed

+79
-5
lines changed

3 files changed

+79
-5
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,9 +2189,6 @@ SILGenFunction::emitApplyOfDefaultArgGenerator(SILLocation loc,
21892189
SILDeclRef generator
21902190
= SILDeclRef::getDefaultArgGenerator(defaultArgsOwner.getDecl(),
21912191
destIndex);
2192-
2193-
// TODO: Should apply the default arg generator's captures, but Sema doesn't
2194-
// track them.
21952192

21962193
auto fnRef = ManagedValue::forUnmanaged(emitGlobalFunctionRef(loc,generator));
21972194
auto fnType = fnRef.getType().castTo<SILFunctionType>();
@@ -2206,8 +2203,13 @@ SILGenFunction::emitApplyOfDefaultArgGenerator(SILLocation loc,
22062203
ResultPlanPtr resultPtr =
22072204
ResultPlanBuilder::computeResultPlan(*this, calleeTypeInfo, loc, C);
22082205
ArgumentScope argScope(*this, loc);
2206+
2207+
SmallVector<ManagedValue, 4> captures;
2208+
emitCaptures(loc, generator, CaptureEmission::ImmediateApplication,
2209+
captures);
2210+
22092211
return emitApply(std::move(resultPtr), std::move(argScope), loc, fnRef,
2210-
subs, {}, calleeTypeInfo, ApplyOptions::None, C);
2212+
subs, captures, calleeTypeInfo, ApplyOptions::None, C);
22112213
}
22122214

22132215
RValue SILGenFunction::emitApplyOfStoredPropertyInitializer(

lib/Sema/TypeCheckCaptures.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,8 @@ void TypeChecker::computeCaptures(AnyFunctionRef AFR) {
624624
/*isObjC=*/false);
625625
E->walk(finder);
626626

627-
if (finder.getDynamicSelfCaptureLoc().isValid()) {
627+
if (!AFD->getDeclContext()->isLocalContext() &&
628+
finder.getDynamicSelfCaptureLoc().isValid()) {
628629
Context.Diags.diagnose(finder.getDynamicSelfCaptureLoc(),
629630
diag::dynamic_self_default_arg);
630631
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
2+
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
3+
4+
// CHECK-LABEL: sil hidden [ossa] @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF : $@convention(thin) <T> (Int, @guaranteed AnyObject, @in_guaranteed Any, @in_guaranteed T) -> ()
5+
func outer<T>(x: Int, y: AnyObject, z: Any, w: T) {
6+
func local1(x: Int = x) {}
7+
func local2(y: AnyObject = y) {}
8+
func local3(z: Any = z) {}
9+
func local4(w: T = w) {}
10+
func local5<U>(u: U, w: T = w) {}
11+
12+
// CHECK: [[FN:%.*]] = function_ref @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF6local1L_ACySi_tlFfA_ : $@convention(thin) (Int) -> Int
13+
// CHECK: [[ARG:%.*]] = apply [[FN]](%0) : $@convention(thin) (Int) -> Int
14+
// CHECK: [[LOCAL1:%.*]] = function_ref @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF6local1L_ACySi_tlF : $@convention(thin) (Int, Int) -> ()
15+
// CHECK: apply [[LOCAL1]]([[ARG]], %0) : $@convention(thin) (Int, Int) -> ()
16+
local1()
17+
18+
// CHECK: [[FN:%.*]] = function_ref @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF6local2L_ADyyXl_tlFfA_ : $@convention(thin) (@guaranteed AnyObject) -> @owned AnyObject
19+
// CHECK: [[ARG:%.*]] = apply [[FN]](%1) : $@convention(thin) (@guaranteed AnyObject) -> @owned AnyObject
20+
// CHECK: [[LOCAL2:%.*]] = function_ref @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF6local2L_ADyyXl_tlF : $@convention(thin) (@guaranteed AnyObject, @guaranteed AnyObject) -> ()
21+
// CHECK: apply [[LOCAL2]]([[ARG]], %1) : $@convention(thin) (@guaranteed AnyObject, @guaranteed AnyObject) -> ()
22+
// CHECK: destroy_value [[ARG]] : $AnyObject
23+
local2()
24+
25+
// CHECK: [[BOX:%.*]] = alloc_box ${ var Any }
26+
// CHECK: [[BOX_ADDR:%.*]] = project_box [[BOX]] : ${ var Any }, 0
27+
// CHECK: copy_addr %2 to [initialization] [[BOX_ADDR]] : $*Any
28+
// CHECK: [[BOX_BORROW:%.*]] = begin_borrow [[BOX]] : ${ var Any }
29+
// CHECK: [[FN:%.*]] = function_ref @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF6local3L_AEyyp_tlFfA_ : $@convention(thin) (@guaranteed { var Any }) -> @out Any
30+
// CHECK: [[STACK:%.*]] = alloc_stack $Any
31+
// CHECK: [[BOX2:%.*]] = alloc_box ${ var Any }
32+
// CHECK: [[BOX2_ADDR:%.*]] = project_box [[BOX2]] : ${ var Any }, 0
33+
// CHECK: copy_addr %2 to [initialization] [[BOX2_ADDR]] : $*Any
34+
// CHECK: [[BOX2_BORROW:%.*]] = begin_borrow [[BOX2]] : ${ var Any }
35+
// CHECK: apply [[FN]]([[STACK]], [[BOX2_BORROW]]) : $@convention(thin) (@guaranteed { var Any }) -> @out Any
36+
// CHECK: end_borrow [[BOX2_BORROW]] : ${ var Any }
37+
// CHECK: destroy_value [[BOX2]] : ${ var Any }
38+
// CHECK: %30 = function_ref @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF6local3L_AEyyp_tlF : $@convention(thin) (@in_guaranteed Any, @guaranteed { var Any }) -> ()
39+
// CHECK: apply %30([[STACK]], [[BOX_BORROW]]) : $@convention(thin) (@in_guaranteed Any, @guaranteed { var Any }) -> ()
40+
// CHECK: destroy_addr [[STACK]] : $*Any
41+
// CHECK: dealloc_stack [[STACK]] : $*Any
42+
// CHECK: end_borrow [[BOX_BORROW]] : ${ var Any }
43+
// CHECK: destroy_value [[BOX]] : ${ var Any }
44+
local3()
45+
46+
local4()
47+
48+
local5(u: "hi")
49+
}
50+
51+
// CHECK-LABEL: sil private [ossa] @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF6local1L_ACySi_tlFfA_ : $@convention(thin) (Int) -> Int
52+
// CHECK-LABEL: sil private [ossa] @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF6local1L_ACySi_tlF : $@convention(thin) (Int, Int) -> ()
53+
// CHECK-LABEL: sil private [ossa] @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF6local2L_ADyyXl_tlFfA_ : $@convention(thin) (@guaranteed AnyObject) -> @owned AnyObject
54+
// CHECK-LABEL: sil private [ossa] @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF6local2L_ADyyXl_tlF : $@convention(thin) (@guaranteed AnyObject, @guaranteed AnyObject) -> ()
55+
// CHECK-LABEL: sil private [ossa] @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF6local3L_AEyyp_tlFfA_ : $@convention(thin) (@guaranteed { var Any }) -> @out Any
56+
// CHECK-LABEL: sil private [ossa] @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF6local3L_AEyyp_tlF : $@convention(thin) (@in_guaranteed Any, @guaranteed { var Any }) -> ()
57+
// CHECK-LABEL: sil private [ossa] @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF6local4L_AFyx_tlF : $@convention(thin) <T> (@in_guaranteed T, @guaranteed <τ_0_0> { var τ_0_0 } <T>) -> ()
58+
// CHECK-LABEL: sil private [ossa] @$s23default_arguments_local5outer1x1y1z1wySi_yXlypxtlF6local5L_1uAFyqd___xtr__lFfA0_ : $@convention(thin) <T><U> (@guaranteed <τ_0_0> { var τ_0_0 } <T>) -> @out T
59+
60+
class ArtClass<T> {
61+
// CHECK-LABEL: sil hidden [ossa] @$s23default_arguments_local8ArtClassC10selfMethod1uyqd___tlF : $@convention(method) <T><U> (@in_guaranteed U, @guaranteed ArtClass<T>) -> ()
62+
func selfMethod<U>(u: U) {
63+
// CHECK-LABEL: sil private [ossa] @$s23default_arguments_local8ArtClassC10selfMethod1uyqd___tlF0C0L_1vAE1syqd0___qd__Sitr___lFfA1_ : $@convention(thin) <T><U><V> (@thick @dynamic_self ArtClass<T>.Type) -> Int
64+
// CHECK-LABEL: sil private [ossa] @$s23default_arguments_local8ArtClassC10selfMethod1uyqd___tlF0C0L_1vAE1syqd0___qd__Sitr___lF : $@convention(thin) <T><U><V> (@in_guaranteed V, @in_guaranteed U, Int, @thick @dynamic_self ArtClass<T>.Type) -> ()
65+
func local<V>(v: V, u: U, s: Int = Self.intMethod()) {}
66+
}
67+
68+
static func intMethod() -> Int {
69+
return 0
70+
}
71+
}

0 commit comments

Comments
 (0)