Skip to content

Commit 79f9a59

Browse files
Merge pull request #40744 from nate-chandler/lexical_lifetimes/test/verification/20220105/1
[Test] Checked variable lifetimes extend self.
2 parents b0ed490 + cb205a6 commit 79f9a59

File tree

1 file changed

+73
-12
lines changed

1 file changed

+73
-12
lines changed

validation-test/SILOptimizer/lexical-lifetimes.swift

Lines changed: 73 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
// RUN: %target-run-simple-swift(-Xfrontend -enable-copy-propagation) | %FileCheck %s
1+
// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking -parse-as-library -Xfrontend -enable-copy-propagation) | %FileCheck %s
22

3+
// REQUIRES: concurrency
34
// REQUIRES: executable_test
45

56
// =============================================================================
@@ -142,19 +143,79 @@ func test_localVar_keepsObjectAliveBeyondCallToSynchronizationPointFunction() {
142143
test_localVar_keepsObjectAliveBeyondCallToSynchronizationPointFunction_doit("blue")
143144
}
144145

146+
func do_foo(_ work: () -> ()) {
147+
work()
148+
}
149+
class Fooer {
150+
__consuming func foo() {
151+
weak var weakSelf = self
152+
do_foo {
153+
weakSelf?.foo1()
154+
weakSelf?.foo2()
155+
}
156+
}
157+
func foo1() {
158+
// CHECK: Fooer foo1
159+
print(type(of: self), #function)
160+
}
161+
func foo2() {
162+
// CHECK: Fooer foo2
163+
print(type(of: self), #function)
164+
}
165+
}
166+
167+
func test_self_keepsObjectAliveBeyond_callTo_functionTakingClosureCapturingWeakVar() {
168+
Fooer().foo()
169+
}
170+
171+
func do_foo_async(_ work: @escaping () -> ()) -> Task<Void, Never> {
172+
Task {
173+
work()
174+
}
175+
}
176+
class FooerAsync {
177+
var strongSelf: FooerAsync?
178+
__consuming func foo() -> Task<Void, Never> {
179+
weak var weakSelf = self
180+
strongSelf = self
181+
return do_foo_async {
182+
// At this point, strongSelf is keeping the object alive.
183+
weakSelf?.foo1()
184+
// By this point, strongSelf has been nil'd, dropping the object's retain
185+
// count to 0, deallocating the object, so weakSelf is nil.
186+
weakSelf?.foo2()
187+
}
188+
}
189+
func foo1() {
190+
// CHECK: FooerAsync foo1
191+
print(type(of: self), #function)
192+
strongSelf = nil
193+
}
194+
func foo2() {
195+
// CHECK-NOT: FooerAsync foo2
196+
print(type(of: self), #function)
197+
}
198+
}
199+
200+
func test_repeatedLoadWeakSelf() -> Task<Void, Never> {
201+
FooerAsync().foo()
202+
}
203+
145204
// =============================================================================
146205
// = Tests }} =
147206
// =============================================================================
148207

149-
func run() {
150-
test_localLet_keepsObjectAliveBeyondCallToClassWithWeakReference()
151-
// Reenable with rdar://86271875
152-
// test_localVar_keepsObjectAliveBeyondCallToClassWithWeakReference()
153-
test_localLet_keepsObjectAliveBeyondCallToClassWithPointer()
154-
test_localVar_keepsObjectAliveBeyondCallToClassWithPointer()
155-
test_localLet_keepsObjectAliveBeyondCallToSynchronizationPointFunction()
156-
test_localVar_keepsObjectAliveBeyondCallToSynchronizationPointFunction()
208+
@main struct Main {
209+
static func main() async {
210+
test_localLet_keepsObjectAliveBeyondCallToClassWithWeakReference()
211+
// Reenable with rdar://86271875
212+
// test_localVar_keepsObjectAliveBeyondCallToClassWithWeakReference()
213+
test_localLet_keepsObjectAliveBeyondCallToClassWithPointer()
214+
test_localVar_keepsObjectAliveBeyondCallToClassWithPointer()
215+
test_localLet_keepsObjectAliveBeyondCallToSynchronizationPointFunction()
216+
test_localVar_keepsObjectAliveBeyondCallToSynchronizationPointFunction()
217+
218+
test_self_keepsObjectAliveBeyond_callTo_functionTakingClosureCapturingWeakVar()
219+
await test_repeatedLoadWeakSelf().value
220+
}
157221
}
158-
159-
run()
160-

0 commit comments

Comments
 (0)