Skip to content

Commit 0496ca4

Browse files
Bring back capture by box
1 parent 4e23370 commit 0496ca4

File tree

4 files changed

+15
-9
lines changed

4 files changed

+15
-9
lines changed

lib/SIL/IR/TypeLowering.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,15 @@ CaptureKind TypeConverter::getDeclCaptureKind(CapturedValue capture,
170170
return CaptureKind::StorageAddress;
171171
}
172172

173+
// Reference storage types can appear in a capture list, which means
174+
// we might allocate boxes to store the captures. However, those boxes
175+
// have the same lifetime as the closure itself, so we must capture
176+
// the box itself and not the payload, even if the closure is noescape,
177+
// otherwise they will be destroyed when the closure is formed.
178+
if (var->getInterfaceType()->is<ReferenceStorageType>()) {
179+
return CaptureKind::Box;
180+
}
181+
173182
// For 'let' constants
174183
if (!var->supportsMutation()) {
175184
assert(getTypeProperties(

test/SILGen/capture-transitive.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ class C {
3434

3535
func returnsSelf1() -> Self {
3636
return { [weak self] in self?.f(); return .init() }()
37-
// CHECK-NO-WEAK-LET-LABEL: sil private [ossa] @{{.*}}returnsSelf{{.*}} : $@convention(thin) (@inout_aliasable @sil_weak Optional<C>, @thick @dynamic_self C.Type) -> @owned C {
38-
// CHECK-HAS-WEAK-LET-LABEL: sil private [ossa] @{{.*}}returnsSelf{{.*}} : $@convention(thin) (@in_guaranteed @sil_weak Optional<C>, @thick @dynamic_self C.Type) -> @owned C {
37+
// CHECK-LABEL: sil private [ossa] @{{.*}}returnsSelf{{.*}} : $@convention(thin) (@guaranteed { var @sil_weak Optional<C> }, @thick @dynamic_self C.Type) -> @owned C
3938
}
4039

4140
func returnsSelf2() -> Self {

test/SILGen/dynamic_self.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,10 @@ class Z {
241241

242242
// CHECK: [[WEAK_SELF:%.*]] = alloc_box ${ var @sil_weak Optional<Z> }
243243
// CHECK: [[WEAK_SELF_LIFETIME:%.*]] = begin_borrow [lexical] [var_decl] [[WEAK_SELF]]
244-
// CHECK: [[WEAK_SELF_ADDR:%.*]] = project_box [[WEAK_SELF_LIFETIME]] : ${ var @sil_weak Optional<Z> }, 0
245-
// CHECK: [[FN:%.*]] = function_ref @$s12dynamic_self1ZC23testDynamicSelfCaptures1xACXDSi_tFyycfU1_ : $@convention(thin) (@in_guaranteed @sil_weak Optional<Z>, @thick @dynamic_self Z.Type) -> ()
246-
// CHECK: [[WEAK_SELF_COPY:%.*]] = alloc_stack $@sil_weak Optional<Z>
247-
// CHECK: copy_addr [[WEAK_SELF_ADDR]] to [init] [[WEAK_SELF_COPY]] : $*@sil_weak Optional<Z>
244+
// CHECK: [[FN:%.*]] = function_ref @$s12dynamic_self1ZC23testDynamicSelfCaptures1xACXDSi_tFyycfU1_ : $@convention(thin) (@guaranteed { var @sil_weak Optional<Z> }, @thick @dynamic_self Z.Type) -> ()
245+
// CHECK: [[WEAK_SELF_COPY:%.*]] = copy_value [[WEAK_SELF_LIFETIME]] : ${ var @sil_weak Optional<Z> }
248246
// CHECK-NEXT: [[DYNAMIC_SELF:%.*]] = metatype $@thick @dynamic_self Z.Type
249-
// CHECK: partial_apply [callee_guaranteed] [[FN]]([[WEAK_SELF_COPY]], [[DYNAMIC_SELF]]) : $@convention(thin) (@in_guaranteed @sil_weak Optional<Z>, @thick @dynamic_self Z.Type) -> ()
247+
// CHECK: partial_apply [callee_guaranteed] [[FN]]([[WEAK_SELF_COPY]], [[DYNAMIC_SELF]]) : $@convention(thin) (@guaranteed { var @sil_weak Optional<Z> }, @thick @dynamic_self Z.Type) -> ()
250248
let fn3 = {
251249
[weak self] in
252250
_ = self
@@ -429,7 +427,7 @@ class Derived : Base {
429427
class Generic<T> {
430428
// Examples where we have to add a special argument to capture Self's metadata
431429
func t1() -> Self {
432-
// CHECK-LABEL: sil private [ossa] @$s12dynamic_self7GenericC2t1ACyxGXDyFAEXDSgycfU_ : $@convention(thin) <T> (@in_guaranteed @sil_weak Optional<Generic<T>>, @thick @dynamic_self Generic<T>.Type) -> @owned Optional<Generic<T>>
430+
// CHECK-LABEL: sil private [ossa] @$s12dynamic_self7GenericC2t1ACyxGXDyFAEXDSgycfU_ : $@convention(thin) <T> (@guaranteed <τ_0_0> { var @sil_weak Optional<Generic<τ_0_0>> } <T>, @thick @dynamic_self Generic<T>.Type) -> @owned Optional<Generic<T>>
433431
_ = {[weak self] in self }
434432
return self
435433
}

test/SILGen/unowned-class-bound-generic-parameter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ func makeGenericClosureWithUnknownClass<T>(t: T) where T : ClassProtocol {
88
_ = { [unowned t] in _ = t }
99
}
1010

11-
// CHECK-LABEL: sil private [ossa] @$s4main34makeGenericClosureWithUnknownClass1tyx_tAA0G8ProtocolRzlFyycfU_ : $@convention(thin) <T where T : ClassProtocol> (@in_guaranteed @sil_unowned T) -> () {
11+
// CHECK-LABEL: sil private [ossa] @$s4main34makeGenericClosureWithUnknownClass1tyx_tAA0G8ProtocolRzlFyycfU_ : $@convention(thin) <T where T : ClassProtocol> (@guaranteed <τ_0_0 where τ_0_0 : ClassProtocol> { var @sil_unowned τ_0_0 } <T>) -> () {
1212

1313
func makeGenericClosureWithNativeClass1<T>(t: T) where T : BaseClass {
1414
_ = { [unowned t] in _ = t }

0 commit comments

Comments
 (0)