Skip to content

[6.2] Fix MutableSpan exclusive access to unsafe pointers #82451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 24, 2025

Conversation

atrick
Copy link
Contributor

@atrick atrick commented Jun 24, 2025

This fix enables exclusive access to a MutableSpan created from an UnsafeMutablePointer.

The compiler has a special case that allows MutableSpan to depend on a mutable
pointer without extending that pointer's access scope. That lets us implement
standard library code like this:

mutating public func extracting(droppingLast k: Int) -> Self {
  //...
  let newSpan = unsafe Self(_unchecked: _pointer, byteCount: newCount)
  return unsafe _overrideLifetime(newSpan, mutating: &self)

Refine this special case so that is does not apply to inout parameters where the
programmer has an expectation that the unsafe pointer is not copied when being
passed as an argument. Now, we safely get an exclusivity violation when creating
two mutable spans from the same pointer field:

@lifetime(&self)
mutating func getSpan() -> MutableSpan<T> {
  let span1 = makeMutableSpan(&self.pointer)
  let span2 = makeMutableSpan(&self.pointer) // ERROR: overlapping access
  return span1
}

If we don't fix this now, it will likely be source breaking in the future.

Fixes rdar://153745332 (Swift allows constructing two MutableSpans to
the same underlying pointer)

(cherry picked from commit 7c5d4b8)

--- CCC ---

Explanation: Fix MutableSpan exclusive access to unsafe pointers This
fix enables exclusive access to a MutableSpan created from an
UnsafeMutablePointer.

Scope: Affects users of MutableSpan when initializing them from an unsafe pointer.

Radar/SR Issue: rdar://153745332 (Swift allows constructing two
MutableSpans to the same underlying pointer)

main PR: #82450

Risk: Low. This only affects users of an API that requires lifetime
dependence. Without using an experimental feature, this only applies
to the initializers of Mutable[Raw]Span.

Testing: Added source-level unit tests

Reviewer: Meghana Gupta

atrick added 3 commits June 24, 2025 00:11
Consider an empty tuple to be a value introducer rather than a forwarding
instruction.

Fixes rdar://153978086 ([nonescapable] compiler crash with dependency on an
expression)

(cherry picked from commit bcc4a78)
Allow a dependence on Void to be considered immortal. This is the ultimate
override in cases where no other code pattern is supported yet.

(cherry picked from commit 36d2b5b)
This fix enables exclusive access to a MutableSpan created from an UnsafeMutablePointer.

The compiler has a special case that allows MutableSpan to depend on a mutable
pointer *without* extending that pointer's access scope. That lets us implement
standard library code like this:

    mutating public func extracting(droppingLast k: Int) -> Self {
      //...
      let newSpan = unsafe Self(_unchecked: _pointer, byteCount: newCount)
      return unsafe _overrideLifetime(newSpan, mutating: &self)

Refine this special case so that is does not apply to inout parameters where the
programmer has an expectation that the unsafe pointer is not copied when being
passed as an argument. Now, we safely get an exclusivity violation when creating
two mutable spans from the same pointer field:

    @Lifetime(&self)
    mutating func getSpan() -> MutableSpan<T> {
      let span1 = makeMutableSpan(&self.pointer)
      let span2 = makeMutableSpan(&self.pointer) // ERROR: overlapping access
      return span1
    }

If we don't fix this now, it will likely be source breaking in the future.

Fixes rdar://153745332 (Swift allows constructing two MutableSpans to
the same underlying pointer)

(cherry picked from commit 7c5d4b8)

--- CCC ---

Explanation: Fix MutableSpan exclusive access to unsafe pointers This
fix enables exclusive access to a MutableSpan created from an
UnsafeMutablePointer.

Scope: Affects users of MutableSpan when initializing them from an unsafe pointer.

Radar/SR Issue: rdar://153745332 (Swift allows constructing two
MutableSpans to the same underlying pointer)

main PR: swiftlang#82450

Risk: Low. This only affects users of an API that requires lifetime
dependence. Without using an experimental feature, this only applies
to the initializers of Mutable[Raw]Span.

Testing: Added source-level unit tests

Reviewer: TBD
@atrick atrick requested a review from a team as a code owner June 24, 2025 07:19
@atrick atrick added 🍒 release cherry pick Flag: Release branch cherry picks swift 6.2 labels Jun 24, 2025
@atrick atrick requested a review from meg-gupta June 24, 2025 07:20
@atrick
Copy link
Contributor Author

atrick commented Jun 24, 2025

@swift-ci test

@atrick atrick enabled auto-merge June 24, 2025 07:20
@atrick atrick merged commit 4a39ed2 into swiftlang:release/6.2 Jun 24, 2025
5 checks passed
@atrick atrick deleted the 62-unsafe-mutablespan branch June 24, 2025 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🍒 release cherry pick Flag: Release branch cherry picks swift 6.2
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants