# Nested weak capture and implicit self in Swift 6

**URL:** <https://forums.swift.org/t/nested-weak-capture-and-implicit-self-in-swift-6/77230>\
**Category:** Using Swift\
**Tags:** concurrency, swift6\
**Created:** [January 16, 2025, 4:21am UTC](https://forums.swift.org/t/nested-weak-capture-and-implicit-self-in-swift-6/77230 "2025-01-16T04:21:12Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![harlanhaskins](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/harlanhaskins/32/333_2.png) [@harlanhaskins](https://forums.swift.org/u/harlanhaskins)\
**Post date:** [January 16, 2025, 4:21am UTC](https://forums.swift.org/t/nested-weak-capture-and-implicit-self-in-swift-6/77230/1 "2025-01-16T04:21:12Z")

</div>

The following code compiles fine in `-swift-version 5`, but errors with `implicit use of 'self' in closure; use 'self.' to make capture semantics explicit` in `-swift-version 6`

```swift
func acceptsClosure(_ x: @escaping () -> Void) {}

@MainActor
final class A {
    func nonisolatedMethod() {}

    func createsNestedClosure() {
        acceptsClosure { [weak self] in
            Task { @MainActor [weak self] in
                guard let self else { return }
                nonisolatedMethod()
             // ^ implicit use of 'self' in closure; use 'self.' to make capture semantics explicit
            }
        }
    }
}

```

If I remove either the outer `[weak self]` it accepts the code, but I am unsure of the reference capture semantics here (am I good? Is the outer capture not going to retain `self`?)

Is this the intended behavior, or is this a bug?

> **[Compiler Explorer - Swift](https://godbolt.org/z/eWT7793cW)**
>
> func acceptsClosure(\_ x: @escaping () -\> Void) {}
> 
> @MainActor
> final class A {
> func nonisolatedMethod() {}
> 
> func createsNestedClosure() {
> acceptsClosure { \[weak self\] in
> Task { @MainActor \[weak self\] in
> ...

---

<div class="post-metadata">

**Author:** ![Andropov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/andropov/32/35955_2.png) [@Andropov](https://forums.swift.org/u/Andropov)\
**Post date:** [January 16, 2025, 1:30pm UTC](https://forums.swift.org/t/nested-weak-capture-and-implicit-self-in-swift-6/77230/3 "2025-01-16T13:30:15Z")

</div>

In your original version, with two `[weak self]` captures, the following happens when the closure is called:

- **If `self` is `nil` at this point:**

- **If `self` is not nil at this point:**

> [@harlanhaskins](#):
>
> If I remove either the outer `[weak self]` it accepts the code, but I am unsure of the reference capture semantics here (am I good? Is the outer capture not going to retain `self`?)

You probably want to remove the **inner** `[weak self] in`, particularly if the first thing the `Task` is doing is `guard let self else { return }`:

```swift
func acceptsClosure(_ x: @escaping () -> Void) {}

final class A: @unchecked Sendable {
    func nonisolatedMethod() {}

    func createsNestedClosure() {
        acceptsClosure { [weak self] in
            guard let self else { return }
            Task { @MainActor in
                nonisolatedMethod()
            }
        }
    }
}

```

The stored closure will have a weak reference to `self` until it's executed. Then, one of two things happen:

- **If `self` is `nil` at this point:**

- **If `self` is not nil at this point:**

This is usually what you want, because a `Task` should eventually finish, so you're not creating a retain cycle by having a `Task` strongly capture `self`\[1\]. And in this case, the `Task` was already strongly capturing `self` immediately either way.

[This thread](https://forums.swift.org/t/unexpected-memory-leak-when-using-task-in-a-closure-causes/66272) touches on this topic too, it's worth a read.

* * *

1. Key exception: if the `Task` can run forever. For example, by containing a `for await` loop over a never-ending `AsyncSequence`.

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [January 16, 2025, 2:09pm UTC](https://forums.swift.org/t/nested-weak-capture-and-implicit-self-in-swift-6/77230/4 "2025-01-16T14:09:11Z")

</div>

cc @cal—the fact that Harlan's original code doesn't work in Swift 6 mode seems like a bug, no?

---

<div class="post-metadata">

**Author:** ![cal](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/cal/32/35557_2.png) [@cal](https://forums.swift.org/u/cal)\
**Post date:** [January 16, 2025, 2:43pm UTC](https://forums.swift.org/t/nested-weak-capture-and-implicit-self-in-swift-6/77230/5 "2025-01-16T14:43:27Z")

</div>

Definitely looks like a bug to me

---

<div class="post-metadata">

**Author:** ![cal](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/cal/32/35557_2.png) [@cal](https://forums.swift.org/u/cal)\
**Post date:** [January 19, 2025, 2:41am UTC](https://forums.swift.org/t/nested-weak-capture-and-implicit-self-in-swift-6/77230/6 "2025-01-19T02:41:07Z")

</div>

Here's a fix: [Fix issue where implicit self was unexpectedly not allowed in nested weak self closure in Swift 6 mode by calda · Pull Request #78738 · swiftlang/swift · GitHub](https://github.com/swiftlang/swift/pull/78738) thanks for the report!
