[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)
This commit is contained in:
Mike Ash
2025-06-03 17:08:41 -04:00
parent 4518bc9dcf
commit 888f2ec894

View File

@@ -13,37 +13,50 @@ func runIn10ms(_ closure: @escaping @Sendable () -> Void) {
}
}
let checkInterval = 10_000_000
let checkIters = 1000
final class Weak: Sendable {
let property = "Self exists"
func test() {
runIn10ms { [weak self] in
if let self {
// Use implicit self -- this should not result in a strong capture
_ = property
fatalError("Self was unexpectedly captured strongly")
} else {
print("Self was captured weakly (1)")
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")
}
runIn10ms { [weak self] in
guard let self else {
print("Self was captured weakly (2)")
return
}
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
fatalError("Self was unexpectedly captured strongly")
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)
}
}
Weak().test()
try await Task.sleep(nanoseconds: 30_000_000)
let (t1, t2) = await Weak().test()
await t1.value
await t2.value