# \[Pitch\] Box

**URL:** <https://forums.swift.org/t/pitch-box/84014>\
**Category:** Pitches\
**Created:** [January 7, 2026, 6:19pm UTC](https://forums.swift.org/t/pitch-box/84014 "2026-01-07T18:19:19Z")\
**Posts on this page:** 20\
**Page:** 5

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [January 21, 2026, 5:32pm UTC](https://forums.swift.org/t/pitch-box/84014/81 "2026-01-21T17:32:47Z")

</div>

You can use it to create recursive non-copyable types, or put the storage of a large non-copyable type on the heap so that you don't overflow the stack.

I would however like to second the recommendation that `Unique<T>` provide a stable address.

Edit: It's also not refcounted.

---

<div class="post-metadata">

**Author:** ![ibex](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ibex/32/30439_2.png) [@ibex](https://forums.swift.org/u/ibex)\
**Post date:** [January 21, 2026, 11:10pm UTC](https://forums.swift.org/t/pitch-box/84014/82 "2026-01-21T23:10:49Z")

</div>

`Unique` is better than `Box`, but `Pointer` or `SafePointer` is more descriptive of what this type really is.

> [@Alejandro](#):
>
> `Box` which is a simple smart pointer type that uniquely owns a value on the heap

---

<div class="post-metadata">

**Author:** ![ellie20](https://avatars.discourse-cdn.com/v4/letter/e/6f9a4e/32.png) [@ellie20](https://forums.swift.org/u/ellie20)\
**Post date:** [January 22, 2026, 1:03am UTC](https://forums.swift.org/t/pitch-box/84014/83 "2026-01-22T01:03:36Z")

</div>

> [@jrose](#):
>
> I do still think we want interop with UnsafePointer—more than just Span, in that we should promise that the address is stable. I expect this to be the type that will let people stop using UnsafeMutablePointer.allocate, but still allow them to pass addresses to C APIs [EDIT: that need to persist them]—especially when they learn inout-to-pointer conversion is only stable in a few rare cases.

Even though promising that `Unique` has a stable address would improve things, I'm concerned that it would still be easy to accidentally break the exclusivity/aliasing rules when unsafely forming persistent pointers. Specifically, it'd be dangerous to non-instantaneously borrow or mutate the inner value if other Swift or C code has an unsafe pointer to the value. I [mentioned earlier](https://forums.swift.org/t/pitch-box/84014/22) how mixing unsafe pointers and safe references like that has caused problems for Rust.

If we expect that, at some point, `Unique` will be primarily used to unsafely form persistent pointers (such as if the other use cases are subsumed by the `indirect` keyword), then I think it'd be a good idea to acknowledge that the primary use case for the type is unsafe. In C++, `std::unique_ptr` is still useful for preventing double-free errors and memory leaks, even if it's used to unsafely form persistent pointers.

To do that, we could name the type something like `UnsafeUnique`, and mark the `.value` property as `@unsafe`, to remind people to be careful about ensuring exclusivity. To remind people that the pointer isn't necessarily exclusive/non-aliased, I think it'd be even better to drop the "unique" part of the name and name it something like `UnsafeOwned`.

It would also be dangerous to send a `Unique` instance across isolation domains, if one forgets to send the unsafe pointers across isolation domains as well. So I think it'd also be a good idea to always make `Unique` non-`Sendable`. Then region-based isolation would know that the `Unique` instance and the unsafe pointers always need to be in the same isolation domain.

---

<div class="post-metadata">

**Author:** ![QuinceyMorris](https://avatars.discourse-cdn.com/v4/letter/q/d26b3c/32.png) [@QuinceyMorris](https://forums.swift.org/u/QuinceyMorris)\
**Post date:** [January 22, 2026, 5:57am UTC](https://forums.swift.org/t/pitch-box/84014/84 "2026-01-22T05:57:23Z")

</div>

Indulging my regrettable proclivity for bike-shedding…

It seems to me that the last several posts have been circling around a very interesting set of ideas. Integrating those points of view, but edging away a step, I'll throw in a new variant:

```swift
    UniqueValue

```

My reasoning is as follows:

- This contains a great big signpost reassuring us that this is about values, not about some abstract concept of "uniqueness" alone.

- It also emphasizes that this is **not** about reference types, and hence indicates why you wouldn't just use a class instance instead.

- The word "unique" suggests something that has a "freestanding" (or kinda "persistent") identity, which is a gesture in the direction of "pointer".

- By not using the word "pointer" in the name, I've punted on any promises that might be implied about pointer lifetimes if the word "pointer" were actually in the name.

- For me, `UniqueValue` links loosely to "special value", which links loosely to "special place in memory", which links loosely to "heap", without actually committing to the concept of a heap at the language level. The "special place" is a sort of boarding school for values that need extra supervision — you know where the inmates sleep! 🙂

---

<div class="post-metadata">

**Author:** ![vanvoorden](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/vanvoorden/32/33619_2.png) [@vanvoorden](https://forums.swift.org/u/vanvoorden)\
**Post date:** [January 22, 2026, 6:44am UTC](https://forums.swift.org/t/pitch-box/84014/85 "2026-01-22T06:44:21Z")

</div>

> [@ibex](#):
>
> `Unique` is better than `Box`, but `Pointer` or `SafePointer` is more descriptive of what this type really is.

Please correct me if I'm wrong here… but `Span` already _is_ our "safe" `Pointer`?

There are actually very few _references_ [womp womp…] of "pointers" in TSPL Language Guide. Pointers are mentioned a lot more in the Reference Manual. But if we assume that the Language Guide is what beginners are starting with then there's basically just this:

> <https://github.com/swiftlang/swift-book/blob/8aff03e21219bde2fcb08612d25520e02f5ea3f6/TSPL.docc/LanguageGuide/ClassesAndStructures.md?plain=1#L687-L699>

Which starts with the assumption the readers came from "C" languages. But I'm not really sure it's so easy to assume that working with pointers is something very common for entry-level engineers today. Those engineers can be very smart and build efficient data structures and algorithms _without_ having experience with a language that requires us to "think" about pointers upfront.

The `Unsafe[Mutable][Raw][Buffer]Pointer` types are "unsafe" for a reason. I don't see any need for us to begin to ship a safe `Pointer` and _also_ put that in the name itself. I think it's better to ask what a safe pointer would give us here that we don't already have… and then think of a name for that _without_ explicitly calling it a `Pointer`. I believe `Span` and `Unique` both sort of fit that idea.

---

<div class="post-metadata">

**Author:** ![OneSadCookie](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/onesadcookie/32/3205_2.png) [@OneSadCookie](https://forums.swift.org/u/OneSadCookie)\
**Post date:** [January 22, 2026, 11:00am UTC](https://forums.swift.org/t/pitch-box/84014/86 "2026-01-22T11:00:41Z")

</div>

Perhaps instead of marking the (actually-safe) `Unique` type as `@unsafe`, it would be sufficient to limit pointer conversions to being consuming? So instead of it offering `var unsafeAddress: UnsafeMutablePointer<Value> { get }` it would offer `consuming func intoUnsafePointer() -> UnsafeMutablePointer<Value>` and `init(unsafeUniquePointer: UnsafeMutablePointer<Value>)` with the requirement that the provided pointer have been obtained via the `intoUnsafePointer` method.

---

<div class="post-metadata">

**Author:** ![ellie20](https://avatars.discourse-cdn.com/v4/letter/e/6f9a4e/32.png) [@ellie20](https://forums.swift.org/u/ellie20)\
**Post date:** [January 22, 2026, 6:41pm UTC](https://forums.swift.org/t/pitch-box/84014/87 "2026-01-22T18:41:18Z")

</div>

That would mean `Unique` effectively loses its stable address\[1\] guarantee, because we can only have a stable address if we make the `Unique` instance go away. It's a perfectly reasonable design for a type that lacks a stable address guarantee, such as the `Box` type in Rust. But we would lose the benefits of a type that provides a stable address guarantee, such as the `std::unique_ptr` type in C++: that we can use a stable address while still avoiding double-free errors and memory leaks.

I guess my point is that a type with a stable address guarantee ought to be different from a type without one. Using a stable address is fundamentally unsafe, because it creates aliasing that can't be tracked by the compiler or the runtime. This has far-reaching effects: whether the type should conform to `Sendable`, whether borrowing and mutating the inner value should be considered safe operations, whether the compiler should make no-aliasing optimizations, and (arguably) what the type should be named.

I also happen to think that any use case for a heap allocation that doesn't need a stable address guarantee would be better served by a language feature, such as `indirect` enum cases and stored properties.

* * *

1. This is technically a misnomer, because what we're actually talking about is stable _pointers_. The difference is that pointers have provenance, which means a pointer can be invalid even if its memory address is a valid memory address.

---

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [January 23, 2026, 12:42am UTC](https://forums.swift.org/t/pitch-box/84014/88 "2026-01-23T00:42:43Z")

</div>

Rust's `Box` has a stable address. It's just not much of a footgun because you're going to reach for `&*box` and `&mut *box` before you reach for `as_ptr()` or `as_mut_ptr()`. The only reason it's even potentially an issue here is because we don't have first class references.

We should just document that `Unique.withUnsafe{Mutable}Pointer` provides a stable address, and then either move towards either first class local `borrowing/inout` bindings or non-escapable non-owning safe pointer types (like Spans, but for single elements).

On an unrelated bikeshedding note, I'd prefer UniqueBox over simply Unique, since otherwise it's not obvious that it stores its value on the heap type instead of inline.

Also, a consuming `leak() -> UnsafeMutablePointer` method could be useful regardless.

---

<div class="post-metadata">

**Author:** ![ellie20](https://avatars.discourse-cdn.com/v4/letter/e/6f9a4e/32.png) [@ellie20](https://forums.swift.org/u/ellie20)\
**Post date:** [January 23, 2026, 1:02am UTC](https://forums.swift.org/t/pitch-box/84014/89 "2026-01-23T01:02:24Z")

</div>

A `Box` in Rust does not have a stable address. For example, the following Rust code has undefined behavior (according to Miri, under both Stacked Borrows and Tree Borrows):

```rust
#![feature(box_as_ptr)]

fn main() {
    unsafe {
        let mut boxed = Box::new(42);
        let ptr = Box::as_mut_ptr(&mut boxed);
        *ptr += 1;
        boxed = boxed;
        *ptr += 1;
    }
}

```

I [wrote earlier](https://forums.swift.org/t/pitch-box/84014/22) in detail about the problems things like this have caused. In short: this is extremely error-prone. In Rust, unsafe pointers can be invalidated according to the aliasing rules, which are extremely subtle. Swift usually avoids these problems because it only exposes unsafe pointers to existing values through closure-based APIs like `withUnsafePointer`, which make the lifetime of an unsafe pointer visible in the source code.

---

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [January 23, 2026, 3:49am UTC](https://forums.swift.org/t/pitch-box/84014/90 "2026-01-23T03:49:17Z")

</div>

That's not because the address isn't stable, That error happens because the pointer is marked as `noalias` and that makes the self assignment logically invalidate it. This is purely a borrow checker issue. There's not even consensus that the pointer being noalias is correct, either: [What are the uniqueness guarantees of Box and Vec? · Issue #326 · rust-lang/unsafe-code-guidelines · GitHub](https://github.com/rust-lang/unsafe-code-guidelines/issues/326#issuecomment-2135007265)

> **[Rust Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=5b154bc1d62e981eca2a1a01133da920)**
>
> A browser interface to the Rust compiler to experiment with the language

---

<div class="post-metadata">

**Author:** ![ellie20](https://avatars.discourse-cdn.com/v4/letter/e/6f9a4e/32.png) [@ellie20](https://forums.swift.org/u/ellie20)\
**Post date:** [January 24, 2026, 12:13am UTC](https://forums.swift.org/t/pitch-box/84014/91 "2026-01-24T00:13:58Z")

</div>

I'm using "stable address" to mean "stable pointer", even though they are technically different concepts, because I think it aligns with how the term "stable address" has been used in this discussion. To be more precise, a `Box` in Rust doesn't provide a stable pointer, because according to the aliasing rules, pointers to the inner value are invalidated when the `Box` is moved. This means it's not useful in practice that the memory address itself doesn't technically change.\[1\]

The problem isn't that the `noalias` marker is potentially incorrect. It's consistent with Rust's aliasing rules, and there's nothing inherently wrong with the aliasing rules.\[2\] The problem is that the aliasing rules are not consistent with people's expectations, so the community has considered changing the aliasing rules.

* * *

1. The discrepancy between pointers and memory addresses is rationalized using a concept called "pointer provenance". 

2. Technically, the rules aren't officially decided, but the community usually uses the rules of Stacked Borrows and/or Tree Borrows. Miri uses those rules, and the compiler uses a subset of those rules to justify some optimizations, such as the `noalias` marker. The specific aliasing rules of `Box` are documented.

---

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [January 24, 2026, 2:45am UTC](https://forums.swift.org/t/pitch-box/84014/92 "2026-01-24T02:45:33Z")

</div>

I think it's better in the context of Swift for the pointer to remain valid if it is moved. This also falls out naturally from the obvious implementation as a safe wrapper over `UnsafeMutablePointer`.

---

<div class="post-metadata">

**Author:** ![grynspan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/grynspan/32/15315_2.png) [@grynspan](https://forums.swift.org/u/grynspan)\
**Post date:** [January 25, 2026, 5:17pm UTC](https://forums.swift.org/t/pitch-box/84014/93 "2026-01-25T17:17:04Z")

</div>

If the goal is to build something similar to `std::unique_ptr`, the type should also have a mechanism for consuming an existing pointer and specifying a custom deallocator. That would allow patterns like:

```swift
import Darwin // Glibc, Musl, ucrt, etc.
let safeCString = unsafe Unique(consuming: strdup(...), deallocatingWith: free)

```

At which point Swift has taken ownership of the C string (a C pointer) and is able to correctly deinitialize and deallocate it at the end of the `Unique` instance's lifetime.

Otherwise, it is constrained to providing its own allocation/deallocation which, while still useful, will force developers to incur a deep copy if the value they want to use comes from a non-Swift source such as a C/POSIX function.

---

<div class="post-metadata">

**Author:** ![dmt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dmt/32/30830_2.png) [@dmt](https://forums.swift.org/u/dmt)\
**Post date:** [January 26, 2026, 1:01am UTC](https://forums.swift.org/t/pitch-box/84014/94 "2026-01-26T01:01:37Z")

</div>

If the goal is that:

> [@grynspan](#):
>
> the type should also have a mechanism for consuming an existing pointer and specifying a custom deallocator.

We should design this to separate the case that requires a delegated destructor from the one that uses the default allocator. This ensures the standard allocating implementation doesn't pay for extra space (closure storage) or dynamic dispatch calls when they aren't required.

For example like in C++:

```swift
protocol Deallocator<Pointee>: ~Copyable {
  associatedtype Pointee: ~Copyable
  func dealloc(_ pointer: UnsafeMutablePointer<Pointee>)
}
struct Box<D: Deallocator>: ~Copyable {
  typealias Value = D.Pointee
  let pointer: UnsafeMutablePointer<Value>
  let deallocator: D
}

```

However, that makes the type awkward to use:

```swift
func f(_ box: consuming Box<some Deallocator<Int>>)

```

Or introduce it as a protocol:

```swift
protocol Box<T>: ~Copyable {
  associatedtype T: ~Copyable
  var value: T { borrow mutate }
  consuming func consume() -> T
  // ...
}

func f(_ box: consuming some Box<T>)

```

This allows it to be used as a currency type while providing two implementations: one optimized for standard allocation, and another capable of delegating destruction to a closure (and be used for erasure).  
This would also allow users to implement their own zero-overhead versions when the destruction function is statically known.

---

<div class="post-metadata">

**Author:** ![ksluder](https://avatars.discourse-cdn.com/v4/letter/k/eada6e/32.png) [@ksluder](https://forums.swift.org/u/ksluder)\
**Post date:** [January 26, 2026, 1:07am UTC](https://forums.swift.org/t/pitch-box/84014/95 "2026-01-26T01:07:47Z")

</div>

My understanding is that the expectation is that `Span` is the currency type, not `Box`. Whether the `Span` came from a `Box` would be an implementation detail. If you need to manage the lifetime of the allocation, you would use a different type than `Box` to vend the `Span`.

---

<div class="post-metadata">

**Author:** ![grynspan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/grynspan/32/15315_2.png) [@grynspan](https://forums.swift.org/u/grynspan)\
**Post date:** [January 26, 2026, 3:11am UTC](https://forums.swift.org/t/pitch-box/84014/96 "2026-01-26T03:11:35Z")

</div>

> [@dmt](#):
>
> We should design this to separate the case that requires a delegated destructor from the one that uses the default allocator. This ensures the standard allocating implementation doesn't pay for extra space (closure storage) or dynamic dispatch calls when they aren't required.

Because the type will be `@frozen`, this _could_ be done with an additional generic parameter:

```swift
struct Unique<Value, Deallocator>: ... {
  var _address: UnsafeMutablePointer<Value>
  var _deallocator: Deallocator

  typealias _CustomDeallocator = (UnsafeMutablePointer<Value>) -> Void

  init(...) where Deallocator == Void {
    ...
  }

  init(..., deallocatingWith deallocator: @escaping Deallocator) where Deallocator == _CustomDeallocator {
    ...
    _deallocator = deallocator
  }

  deinit {
    // Ugly, but the compiler can optimize it away
    if Deallocator.self == _CustomDeallocator .self {
      (_deallocator as! _CustomDeallocator)(_address)
    } else {
      _address.deinitialize()
      _address.deallocate()
    }
  }
}

```

Of course, this then requires the caller to track the deallocator as part of the type, which is ungainly (and a problem for `std::unique_ptr` too.) Using two separate types has the same problem and an existential box around `any UniqueProtocol` or some such would take even _more_ space.

(I'd be inclined to just eat the cost here, honestly.)

---

<div class="post-metadata">

**Author:** ![glukianets](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/glukianets/32/34964_2.png) [@glukianets](https://forums.swift.org/u/glukianets)\
**Post date:** [January 26, 2026, 11:46am UTC](https://forums.swift.org/t/pitch-box/84014/97 "2026-01-26T11:46:00Z")

</div>

One more naming option to consider: following the precedent of `InlineArray`, call it `Outline`, or `OutlineBox`.

As it was noted by others, calling it `Unique` suggests semantics that isn't really there; calling it `Pointer` would be misleading since it has little to do with pointers as a concept; and calling it `Box` is nice but fails to communicate what is it actually for. Calling it `Outline` covers the last part: it hints on the main use case, which is untying actual value storage from its immediate inline storage slot.

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [January 26, 2026, 3:34pm UTC](https://forums.swift.org/t/pitch-box/84014/98 "2026-01-26T15:34:26Z")

</div>

> [@glukianets](#):
>
> One more naming option to consider: following the precedent of `InlineArray`, call it `Outline`, or `OutlineBox`.

I might be wrong, but I believe the opposite of inline as an adjective is "out of line", not "outline".

---

<div class="post-metadata">

**Author:** ![allevato](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/allevato/32/385_2.png) [@allevato](https://forums.swift.org/u/allevato)\
**Post date:** [January 26, 2026, 4:24pm UTC](https://forums.swift.org/t/pitch-box/84014/99 "2026-01-26T16:24:43Z")

</div>

The Swift compiler does use the adjective "outlined" quite a bit to describe code that's been lifted out of a context and into its own function, which is sort of the same concept, but regardless the term "outlined/out of line" is orders of magnitude less commonly encountered in programming (compared to "inline") and would be far too jargony for a standard library API.

---

<div class="post-metadata">

**Author:** ![Nobody1707](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nobody1707/32/2169_2.png) [@Nobody1707](https://forums.swift.org/u/Nobody1707)\
**Post date:** [January 26, 2026, 4:49pm UTC](https://forums.swift.org/t/pitch-box/84014/100 "2026-01-26T16:49:08Z")

</div>

I think that Box as a suffix adequately conveys that the storage is out-of-line, and Unique as a prefix adequately conveys non-copyability. I just think that having the name be just one or the other would be misleading.

[Previous page](https://forums.swift.org/t/pitch-box/84014.md?page=4)

[Next page](https://forums.swift.org/t/pitch-box/84014.md?page=6)
