Files
swift-mirror/test/expr/closure/implicit_weak_capture.swift
Mike Ash 888f2ec894 [6.2][Test] Make implicit_weak_capture.swift more robust.
This test creates an object then checks a weak reference to that object on a background thread. It was doing this check after 10ms, and any small hiccup could potentially delay the object's destruction enough to spuriously fail.

Rearrange the test to check the weak reference in a loop for several seconds before giving up. This makes it very fast on success (it's done the moment it sees nil) while being robust against up to several seconds of delay in destroying the object if that happens.

rdar://149868181
(cherry picked from commit d0248afd14)
2025-07-23 16:38:59 -04:00

63 lines
1.5 KiB
Swift

// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking -swift-version 6)
// REQUIRES: concurrency
// REQUIRES: executable_test
// rdar://102155748
// UNSUPPORTED: back_deployment_runtime
func runIn10ms(_ closure: @escaping @Sendable () -> Void) {
Task {
try! await Task.sleep(nanoseconds: 10_000_000)
closure()
}
}
let checkInterval = 10_000_000
let checkIters = 1000
final class Weak: Sendable {
let property = "Self exists"
func test() async -> (Task<Void, Never>, Task<Void, Never>) {
let t1 = Task { [weak self] in
for _ in 0..<checkIters {
if let self {
// Use implicit self -- this should not result in a strong capture
_ = property
} else {
print("Self was captured weakly (1)")
return
}
try! await Task.sleep(nanoseconds: 10_000_000)
}
fatalError("Self was unexpectedly captured strongly")
}
let t2 = Task { [weak self] in
for _ in 0..<checkIters {
guard let self else {
print("Self was captured weakly (2)")
return
}
// Use implicit self -- this should not result in a strong capture
_ = property
runIn10ms { [self] in
// Use implicit self -- this should not result in a strong capture
_ = property
}
try! await Task.sleep(nanoseconds: 10_000_000)
}
fatalError("Self was unexpectedly captured strongly")
}
return (t1, t2)
}
}
let (t1, t2) = await Weak().test()
await t1.value
await t2.value