# UnsafePointer Sendable should be revoked

**URL:** <https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926>\
**Category:** Discussion\
**Created:** [September 9, 2021, 6:09pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926 "2021-09-09T18:09:05Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Andrew\_Trick](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/andrew_trick/32/323_2.png) [@Andrew\_Trick](https://forums.swift.org/u/Andrew_Trick)\
**Post date:** [September 9, 2021, 6:09pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/1 "2021-09-09T18:09:05Z")

</div>

Can anyone think of a reason that the family of UnsafePointer types should be Sendable?

I'm guessing this was done for convenient ObjC API migration. That may be sufficient motivation, but that argument needs to be put forward. Aside from that, making UnsafePointer Sendable is clearly wrong from both a logical and practical standpoint. Logically, UnsafePointer directly violates Sendable's protection against shared mutable state. As a practical matter, a Sendable UnsafePointer causes Sendable to be inferred for any wrapper that safely manages ownership, but naturally does not provide exclusive access to the memory.

This means programs will end up with race conditions without any source level indication of the danger.

Conceptually, sharing UnsafePointers across actors requires a strategy to avoid shared mutable state. Either through uniqueness or shared immutability. At the very least, that strategy should be made explicit.

```swift
// The underlying memory may only be accessed via a single
// UniquePointer instance during its lifetime.
struct UniquePointer<T> : @unchecked Sendable {
  var pointer: UnsafeMutablePointer<T>
}

// The underlying memory may only be accessed via other instances of
// SharedPointer during the lifetime of a SharedPointer instance.
struct SharedPointer<T> : @unchecked Sendable {
  var pointer: UnsafePointer<T>
}

```

In the not too distant future, move-only language features will allow the compiler to enforce both of these strategies.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [September 9, 2021, 6:52pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/2 "2021-09-09T18:52:53Z")

</div>

I agree that it’s probably unwise, especially with automatic checking/derivation, but it was part of the proposal: [https://github.com/apple/swift-evolution/blob/main/proposals/0302-concurrent-value-and-concurrent-closures.md#adoption-of-sendable-by-standard-library-types](https://github.com/apple/swift-evolution/blob/main/proposals/0302-concurrent-value-and-concurrent-closures.md#adoption-of-sendable-by-standard-library-types)

> - `Unsafe(Mutable)(Buffer)Pointer` : these generic types _unconditionally_ conform to the `Sendable` protocol. This means that an unsafe pointer to a non-concurrent value can potentially be used to share such values between concurrency domains. Unsafe pointer types provide fundamentally unsafe access to memory, and the programmer must be trusted to use them correctly; enforcing a strict safety rule for one narrow dimension of their otherwise completely unsafe use seems inconsistent with that design.

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [September 9, 2021, 7:03pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/3 "2021-09-09T19:03:20Z")

</div>

Yeah, I agree that the derivation aspect tips it the other way. Rust has pretty much the same feature and they make pointers non-Sendable by default for exactly that reason.

> [R]aw pointers are, strictly speaking, marked as thread-unsafe as more of a _lint_. Doing anything useful with a raw pointer requires dereferencing it, which is already unsafe. In that sense, one could argue that it would be "fine" for them to be marked as thread safe.
> 
> However it's important that they aren't thread-safe to prevent types that contain them from being automatically marked as thread-safe. These types have non-trivial untracked ownership, and it's unlikely that their author was necessarily thinking hard about thread safety.

([Send and Sync - The Rustonomicon](https://doc.rust-lang.org/nomicon/send-and-sync.html))

I wish we had realized this sooner, but it’s probably still worth fixing.

---

<div class="post-metadata">

**Author:** ![Paul\_Cantrell](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/paul_cantrell/32/16764_2.png) [@Paul\_Cantrell](https://forums.swift.org/u/Paul_Cantrell)\
**Post date:** [September 9, 2021, 7:31pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/4 "2021-09-09T19:31:30Z")

</div>

Counterargument: It says “unsafe” in the name.

Countercounterargument: You don’t see that name at the call site.

If not for a revocation of the conformance, this does seem to me to require some kind of compile-time diagnostic, and/or some feature that puts the word “unsafe” in the contexts where concurrency safety decisions matter.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [September 9, 2021, 7:40pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/5 "2021-09-09T19:40:36Z")

</div>

> [@jrose](#):
>
> I wish we had realized this sooner, but it’s probably still worth fixing.

It did not escape “our” collective attention. I explicitly pointed this out during the original discussions, even the derivation part—[more than once](https://forums.swift.org/t/se-0302-second-review-sendable-and-sendable-closures/45253/7)—but it was decided to proceed in this manner. 🤷‍♂️

But, I’m still glad it’s getting attention again; better late than never. Thanks for fleshing out the full argument @Andrew_Trick.

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [September 9, 2021, 7:53pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/6 "2021-09-09T19:53:49Z")

</div>

You’re right. I wish _I_ had supported it sooner and that the core team had evaluated the concerns raised by you and others sooner.

---

<div class="post-metadata">

**Author:** ![Andrew\_Trick](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/andrew_trick/32/323_2.png) [@Andrew\_Trick](https://forums.swift.org/u/Andrew_Trick)\
**Post date:** [September 9, 2021, 8:00pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/7 "2021-09-09T20:00:30Z")

</div>

@xwu Thanks for pointing out the original discussion. You're right. I'm not raising any new concern here. I started this topic because I wanted to see the final justification explained before we actually enable enforcement.

Two points I'd like to add

1. Revoking Sendable before enforcement is enabled is reversible. IIUC we can always add '@unchecked Sendable' later if there turns out to be a major usability problem. If the usability concern is only speculative, then it doesn't makes sense to irreversibly introduce definite risk.

2. I disagree with the characterization of any "Unsafe" API as "broadly unsafe". The programmer must be aware of precisely every aspect of unsafety. The obvious requirement for the UnsafePointer family is the need to separately guarantee memory lifetime. And, obviously subscripting a non-buffer type has no bounds check. Type safety is uncompromised. The reason pointers are not Sendable is that they have reference semantics, which actually has nothing to do with the "Unsafe" prefix. Sendable's job is to stop programmers from accidentally passing around things with reference semantics even when it's obvious that those things have reference semantics.

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [September 15, 2021, 4:23pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/8 "2021-09-15T16:23:08Z")

</div>

> [@Andrew\_Trick](#):
>
> Revoking Sendable before enforcement is enabled is reversible. IIUC we can always add '@unchecked Sendable' later if there turns out to be a major usability problem. If the usability concern is only speculative, then it doesn't makes sense to irreversibly introduce definite risk.

Given that Swift 5.5 is not really enforcing `Sendable`, I do think we have a window in which we can revoke this conformance without causing undue source compatibility breaks.

> [@Andrew\_Trick](#):
>
> I disagree with the characterization of any "Unsafe" API as "broadly unsafe". The programmer must be aware of precisely every aspect of unsafety. The obvious requirement for the UnsafePointer family is the need to separately guarantee memory lifetime. And, obviously subscripting a non-buffer type has no bounds check. Type safety is uncompromised. The reason pointers are not Sendable is that they have reference semantics, which actually has nothing to do with the "Unsafe" prefix. Sendable's job is to stop programmers from accidentally passing around things with reference semantics even when it's obvious that those things have reference semantics.

This is a great argument, and one I should have given more thought to earlier. I think we should revoke these conformances. Apologies to @xwu and others for not thinking about this bit deeply enough, and thanks to @Andrew_Trick for making the argument so well.

Doug

---

<div class="post-metadata">

**Author:** ![Andrew\_Trick](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/andrew_trick/32/323_2.png) [@Andrew\_Trick](https://forums.swift.org/u/Andrew_Trick)\
**Post date:** [September 15, 2021, 6:53pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/9 "2021-09-15T18:53:36Z")

</div>

Thanks @Douglas_Gregor. Can this be reviewed by core team as an amendment to:  
SE-0302 Sendable and sendable closures]([swift-evolution/0302-concurrent-value-and-concurrent-closures.md at main · apple/swift-evolution · GitHub](https://github.com/apple/swift-evolution/blob/main/proposals/0302-concurrent-value-and-concurrent-closures.md))

Or are there upcoming Sendable proposals we can combine it with?

Or as it's own SE?

PR:

> <https://github.com/apple/swift/pull/39218>
>
> To send them across actors, they need to be wrapped in an '@unchecked
> Sendable'… type. Typically such a wrapper type would be be responsible
> for ensuring its uniqueness or immutability.
> 
> Inferring Sendability for arbitrary types that contain Unsafe\*Pointers
> would introduce race conditions without warning or any explicit
> acknoledgement from the programmer that the pointer is in fact unique.

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [September 15, 2021, 8:50pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/10 "2021-09-15T20:50:39Z")

</div>

> [@Andrew\_Trick](#):
>
> Thanks @Douglas_Gregor. Can this be reviewed by core team as an amendment to:  
> SE-0302 Sendable and sendable closures]([https://github.com/apple/swift-evolution/blob/main/proposals/0302-concurrent-value-and-concurrent-closures.md](https://github.com/apple/swift-evolution/blob/main/proposals/0302-concurrent-value-and-concurrent-closures.md))

Given that this part of SE-0302 is implemented in Swift 5.5, I suspect that the Core Team will want to treat this as a separate proposal rather than an amendment.

> [@Andrew\_Trick](#):
>
> Or are there upcoming Sendable proposals we can combine it with?

There are a few other `Sendable`-related bits that I think need we need to consider and could be bundled together:

- There is no spelling for "this type is explicitly not `Sendable`", to suppress implicit inference of `Sendable` for internal/private/fileprivate types.

- The hard requirement that key paths cannot be formed with non-`Sendable` captured values is too strict, because it makes key-paths useless with some types. We should probably have key path literals produce a `KeyPath<...> & Sendable` type when their captures are all `Sendable`.

- We likely want a `-require-explicit-sendable` option to produce warnings about any public type in a module that is not marked as `Sendable` or non-`Sendable`, so library authors can make sure they don't forget about `Sendable` for the types they vend.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [September 15, 2021, 8:57pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/11 "2021-09-15T20:57:23Z")

</div>

> [@Douglas\_Gregor](#):
>
> There is no spelling for "this type is explicitly not `Sendable` ", to suppress implicit inference of `Sendable` for internal/private/fileprivate types.

I had thought there was discussion about marking an explicit `Sendable` conformance as unavailable?

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [September 16, 2021, 4:57pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/12 "2021-09-16T16:57:29Z")

</div>

> [@xwu](#):
>
> I had thought there was discussion about marking an explicit `Sendable` conformance as unavailable?

I brought it up in the [thread on staging Sendable checking](https://forums.swift.org/t/pitch-staging-in-sendable-checking/51341/13), with this suggestion:

```swift
public struct MyType : @available(unavailable, *) Sendable {
  var x, y: Double
  // some day we may add some shared state here
}

```

Doug

---

<div class="post-metadata">

**Author:** ![lorentey](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lorentey/32/1299_2.png) [@lorentey](https://forums.swift.org/u/lorentey)\
**Post date:** [September 23, 2021, 11:37pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/13 "2021-09-23T23:37:45Z")

</div>

> [@Andrew\_Trick](#):
>
> The reason pointers are not Sendable is that they have reference semantics

I don't want to derail this thread, but I'm getting increasingly confused by what these terms mean. What exactly makes `UnsafePointer` have "reference semantics"? Why would reference semantics preclude "sendability"?

Does `ManagedAtomic<Int>` in the swift-atomics package have "reference semantics"? If so, does that mean it [should not be `Sendable`](https://forums.swift.org/t/when-should-managedatomic-unsafeatomic-be-marked-sendable/52321/4)? (It is safely transferrable across concurrency domains.)

Does this extension give `Int` "reference semantics"? Is it in conflict with its `Sendable` conformance?

```swift
var storage: [String] = ...
extension Int {
  var pointee: String { 
    get { storage[self] }
    set { storage[self] = newValue }
  }
}

```

(How can we possibly infer sendability by just looking at a type's stored properties, without analyzing its operations?)

---

<div class="post-metadata">

**Author:** ![Andrew\_Trick](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/andrew_trick/32/323_2.png) [@Andrew\_Trick](https://forums.swift.org/u/Andrew_Trick)\
**Post date:** [September 23, 2021, 11:59pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/14 "2021-09-23T23:59:49Z")

</div>

> [@lorentey](#):
>
> > [@Andrew\_Trick](#):
> >
> > The reason pointers are not Sendable is that they have reference semantics
> 
> I don't want to derail this thread, but I'm getting increasingly confused by what these terms mean. What exactly makes `UnsafePointer` have "reference semantics"? Why would reference semantics preclude "sendability"?

I could be wrong about any of this, but here's how I use the terms.

In this context, "reference semantics" means shared mutable state. In particular, access to storage reachable via the value can result in mutation visible across executors.

Pointers have a special kind of references semantics that doesn't involve "object references". Maybe that's the confusion?

> [@lorentey](#):
>
> Does `ManagedAtomic<Int>` in the swift-atomics package have "reference semantics"? If so, does that mean it [should not be `Sendable`](https://forums.swift.org/t/when-should-managedatomic-unsafeatomic-be-marked-sendable/52321/4)? (It is safely transferrable across concurrency domains.)

Atomics absolutely have reference semantics. They are a special category of explicitly "shared mutable" types though, so they are Sendable as long as their payload is Sendable.

> [@lorentey](#):
>
> Does this extension give `Int` "reference semantics"? Is it in conflict with its `Sendable` conformance?
> 
> ```swift
> var storage: [String] = ...
> extension Int {
> var pointee: String { 
> get { storage[self] }
> set { storage[self] = newValue }
> }
> }
> 
> ```
> 
> (How can we possibly infer sendability by just looking at a type's stored properties, without analyzing its operations?)

That would only give `Int` reference semantics if that extension were actually callable from multiple executors, which it should not be.

So, reference semantic things can be Sendable under various conditions:

- immutability
- uniqueness
- mutable-if-uniqueness
- shared mutability

...but all these properties must be transitively guaranteed across the object (or pointer) graph reachable from the value

---

<div class="post-metadata">

**Author:** ![tera](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tera/32/38201_2.png) [@tera](https://forums.swift.org/u/tera)\
**Post date:** [September 24, 2021, 12:46am UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/15 "2021-09-24T00:46:19Z")

</div>

> [@Andrew\_Trick](#):
>
> That would only give `Int` reference semantics if that extension were actually callable from multiple executors, which it should not be.
> 
> ...but all these properties must be transitively guaranteed across the object (or pointer) graph reachable from the value

that's just hard-to-impossible to guarantee.. the function can be in a third party code, you integrated that code and audit its sources, all good at that point no mutable global access. next revision of that third party code introduces a mutable global access as nothing in the function contract (signature) prevents it doing so... (forget third party.. it can be your team member doing this change (forget your team member, that can be yourself, a few months later)). as in [the other thread](https://forums.swift.org/t/on-purity-grades-of-value-types-was-valuetype-protocol/52139) i believe such traits must be reflected in the function signature (or derived from the parent type if not specified at the function level) and checked by the compiler.

---

<div class="post-metadata">

**Author:** ![Terje](https://avatars.discourse-cdn.com/v4/letter/t/848f3c/32.png) [@Terje](https://forums.swift.org/u/Terje)\
**Post date:** [January 25, 2022, 10:43am UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/16 "2022-01-25T10:43:49Z")

</div>

I was about to shoot myself in the foot on this.  
Will this be revoked in the future? I hope so but I couldn't find any recent posts or proposals on this.  
I hope it was not too inappropriate to post this as a friendly reminder.

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [January 25, 2022, 12:08pm UTC](https://forums.swift.org/t/unsafepointer-sendable-should-be-revoked/51926/17 "2022-01-25T12:08:47Z")

</div>

> <https://github.com/apple/swift-evolution/blob/main/proposals/0331-remove-sendable-from-unsafepointer.md>
