Commit Graph

1 Commits

Author SHA1 Message Date
Michael Gottesman
0ce3729740 [rbi] Mark mutable weak capture boxes containing Sendable types as immutable if they are never interprocedurally written to and teach SILIsolationInfo::isSendable that they are meant to be treated as Sendable.
The pass works by walking functions in the modules looking for mutable alloc_box
that contains a weak variable and is knowably a capture. In such a case, the
pass checks all uses of the alloc_box interprocedurally including through
closures and if provably immutable marks the box and all closure parameters as
being inferred immutable.

This change also then subsequently changes SILIsolationInfo to make it so that
such boxes are considered Sendable in a conservative manner that pattern matches
the weak reference code emission pretty closely.

The reason why I am doing this is that issue #82427 correctly tightened region
isolation checking to catch unsafe concurrent access to mutable shared
state. However, this introduced a regression for a common Swift pattern:
capturing `self` weakly in escaping closures.

The problem occurs because:

1. Weak captures are stored in heap-allocated boxes.
2. By default, these boxes are **mutable** (`var`) even if never written to after initialization
3. Mutable boxes are non-Sendable (they could be unsafely mutated from multiple threads)
4. Region isolation now correctly errors when sending non-Sendable values across isolation boundaries

This breaks code like:

```swift
@MainActor class C {
    func test() {
        timer { [weak self] in  // Captures self in a mutable box
            Task { @MainActor in
                self?.update()  // ERROR: sending mutable box risks data races
            }
        }
    }
}
```

Note how even though `self` is Sendable since it is MainActor-isolated, the *box
containing* the weak reference is not Sendable because it is mutable.

With the change in this commit, we now recognize that the box can safely be
treated as Sendable since we would never write to it.

rdar://166081666
2026-01-16 09:58:01 -08:00