# Create &'static Box\<T\> at compile time

**URL:** <https://internals.rust-lang.org/t/create-static-box-t-at-compile-time/23280>\
**Category:** Uncategorized\
**Created:** [July 28, 2025, 3:21am UTC](https://internals.rust-lang.org/t/create-static-box-t-at-compile-time/23280 "2025-07-28T03:21:03Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![JeffBurdges](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jeffburdges/32/2116_2.png) [@JeffBurdges](https://internals.rust-lang.org/u/JeffBurdges)\
**Post date:** [July 28, 2025, 3:21am UTC](https://internals.rust-lang.org/t/create-static-box-t-at-compile-time/23280/1 "2025-07-28T03:21:03Z")

</div>

At present, if you want to statically initialize parameters in code, then you often need `Cow<'static,[T]>` fields, so that slice types could be created both at runtime via `Cow::Owned(vec)` and at compile time via `Cow::Borrowed(&[..])`.

This `Cow` trick enables shallow clones nicely, but maybe incurs a variant check. I'd hope rustc optimizes away that variant check!

You'd never use `&'static Box<[T]>` directly, since it incurs an indirection, without any benefits, but..

If you never clone the data, then you might've some big parameters struct containing many slices, so why not use `Box<[T]>` and create them at compile time?

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

```rust
pub struct Parameters {
    foo: Box<[u64]>,
}

static PARAMETERS: &'static Parameters = &Parameters {
    foo: unsafe { box_from_static_slice(&[1,2,3,4,5,6]) },
};

pub const unsafe fn box_from_static_slice<T: 'static>(x: &'static [T]) -> Box<[T]> {
    unsafe { core::mem::transmute(x) }
}

```

In this case, rustc complains it "encountered mutable reference or box pointing to read-only memory" under [E0080], with an acknoledgement that "this check might be overzealous".

Should this be allowed? Or should we simply say that `Cow<'static,[T]>` is idomatic here, and that rustc must optimize away the variant check?

In fact, there maybe an optimization conflict here: `Cow<'static,[T]>` needs three `usize` and the variant, while `Box<[T]>` needs only two `usize`, so if rustc optimizes agressively for space then it'll treat the `NonNull` pointer as the variant flag, which then prevents optimizing away the variant check.

Ergo, should we use some `ToOwnedBox` trait with `<[T] as ToOwned>::Owned = Box<[T]>` and a corresponding `CowBox<'a,T>` type, which definitely saves one `usize`? If so, would rustc optimize away the variant check here?

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jrose/32/9591_2.png) [@jrose](https://internals.rust-lang.org/u/jrose)\
**Post date:** [July 28, 2025, 3:45am UTC](https://internals.rust-lang.org/t/create-static-box-t-at-compile-time/23280/2 "2025-07-28T03:45:30Z")

</div>

I have idly wanted `&'static Arc<T>` a few times for an API that takes an Arc but also would be nice to have some static options as well. This is even _more_ of a perf hit because if you don’t change anything else you still pay for all the increments and decrements; the only thing you really save is the allocation. But sometimes that would be nice!

There are various variant-based solutions out there for this, but honestly just being able to allocate an Arc statically would be sufficient, given that there would be a permanent root (the global). Box seems even simpler to get working in that sense: if you use `Box::new` in a `static` context, you get a pointer to static data that lives over somewhere else. Being able to reinterpret a `static` pointer is just one more step.

…That said, there are two things I can see getting in the way. The first is Allocator metadata—if we ever have Allocator methods that allow you to ask questions about live allocations, GlobalAlloc will have to at least _handle_ being asked about static Boxes or Arcs. The second is putting the static allocation inside an UnsafeCell of some kind—oops, now the root isn’t permanent. Both of these can be dealt with, but they do make things a little more complicated than just “define some const behaviors for these”.

I guess I digressed from the original idea a bit, which was saying that a `& &'static T` (sic) could be argued to _already_ be a valid `&Box<T>`.

---

<div class="post-metadata">

**Author:** ![Jules-Bertholet](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jules-bertholet/32/10671_2.png) [@Jules-Bertholet](https://internals.rust-lang.org/u/Jules-Bertholet)\
**Post date:** [July 28, 2025, 4:06am UTC](https://internals.rust-lang.org/t/create-static-box-t-at-compile-time/23280/3 "2025-07-28T04:06:45Z")

</div>

> [@JeffBurdges](#):
>
> I'd hope rustc optimizes away that variant check!

It does: [`Cow\<[T]\>` layout forces unnecessary branching · Issue #117763 · rust-lang/rust · GitHub](https://github.com/rust-lang/rust/issues/117763#issuecomment-1872393819)

---

<div class="post-metadata">

**Author:** ![JeffBurdges](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jeffburdges/32/2116_2.png) [@JeffBurdges](https://internals.rust-lang.org/u/JeffBurdges)\
**Post date:** [July 28, 2025, 5:01am UTC](https://internals.rust-lang.org/t/create-static-box-t-at-compile-time/23280/4 "2025-07-28T05:01:15Z")

</div>

All cool, so `CowBox` saves only memory, vs `Cow`. This helps when you access some static data lots, like the tables used in FFTs or binary field multiplications. It's only the variant check that's worring here, not the extra memory.

I should've said `&'static Params { .. Box<T> .. }` for the title probably..

An `&'static Arc<T>` would only help if you _really_ never cloned, becasue any `Arc::clone` would increment the counters and trigger segfaults, no? It's unsafe.

I suspect `std::sync` could be forked to add pseudo-variants everywhere that bypass the atomics, while being 100% layout compatible with `std::sync`, so their non-static variants could be cast into their regular forms for free: `Arc` could use the same `NonNull<ArcInner>` like `Arc` does, but `strong = usize::MAX` means ignore the atomics entirely, and you check the `strong` niche by doing a non-atomic read first. `Mutex` etc could similar have static variants, created by tweaking their poisoning flag, again checking the variant using a non-atomic read first. You maybe have something more complex going on though, ala allocator features.

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jrose/32/9591_2.png) [@jrose](https://internals.rust-lang.org/u/jrose)\
**Post date:** [July 28, 2025, 5:30am UTC](https://internals.rust-lang.org/t/create-static-box-t-at-compile-time/23280/5 "2025-07-28T05:30:31Z")

</div>

> [@JeffBurdges](#):
>
> An `&'static Arc<T>` would only help if you _really_ never cloned, becasue any `Arc::clone` would increment the counters and trigger segfaults, no? It's unsafe.

No, you put the allocation in static RW memory and it’s fine (like any `static` in Rust with interior mutability). Not quite as good as static RO memory, but still an improvement over a new allocation that gets _copied_ from static RO memory. (Which is not to say an “immortal” representation can’t be considered, but it’s not a prerequisite.)

---

<div class="post-metadata">

**Author:** ![Ddystopia](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ddystopia/32/10915_2.png) [@Ddystopia](https://internals.rust-lang.org/u/Ddystopia)\
**Post date:** [July 28, 2025, 6:05am UTC](https://internals.rust-lang.org/t/create-static-box-t-at-compile-time/23280/6 "2025-07-28T06:05:43Z")

</div>

What about having static mut? This compiles

> **[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&code=%0Apub%2Bstruct%2BParameters%2B%7B%0A%2B%2B%2B%2B%2F%2F%2Bfoo%3A%2B%26%27static%2B%5Bu64%5D%2C%0A%2B%2B%2B%2Bfoo%3A%2BBox%3C%5Bu64%5D%3E%2C%0A%7D%0Astatic%2Bmut%2BSLICE%3A%2B%5Bu64%3B%2B6%5D%2B%3D%2B%5B1%2C%2B2%2C%2B3%2C%2B4%2C%2B5%2C%2B6%5D%3B%0Astatic%2BPARAMETERS%3A%2B%26%27static%2BParameters%2B%3D%2B%26Parameters%2B%7B%0A%2B%2B%2B%2B%2F%2F%2Bfoo%3A%2B%26%5B1%2C2%2C3%2C4%2C5%5D%2C%0A%2B%2B%2B%2Bfoo%3A%2Bunsafe%2B%7B%2Bbox_from_static_slice%28%26mut%2B*%26raw%2Bmut%2BSLICE%29%7D%0A%7D%3B%0A%0A%0Apub%2Bconst%2Bunsafe%2Bfn%2Bbox_from_static_slice%3CT%3A%2B%27static%3E%28x%3A%2B%26%27static%2Bmut%2B%5BT%5D%29%2B-%3E%2BBox%3C%5BT%5D%3E%2B%7B%0A%2B%2B%2B%2Bunsafe%2B%7B%2Bcore%3A%3Amem%3A%3Atransmute%28x%29%2B%7D%0A%7D%0A%0Afn%2Bmain%28%29%2B%7B%0A%2B%2B%2B%2Bprintln%21%28%22Hello%2C%2Bworld%21%22%29%3B%0A%7D)**
>
> A browser interface to the Rust compiler to experiment with the language

---

<div class="post-metadata">

**Author:** ![RalfJung](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ralfjung/32/2415_2.png) [@RalfJung](https://internals.rust-lang.org/u/RalfJung)\
**Post date:** [July 28, 2025, 7:01am UTC](https://internals.rust-lang.org/t/create-static-box-t-at-compile-time/23280/7 "2025-07-28T07:01:00Z")

</div>

One problem here is that in general it is hard to say when this would be sound. For instance, `&'static Mutex<Box<T>>` is unsound since I could, at runtime, `mem::swap` that box with another one and then drop it -- which is UB since the box wasn't actually allocated with the runtime allocator.

The error you encounter exits because we are not sure that things would be sound without that error. That said, it does seem very plausible that you need unsafe to get yourself into that situation, so we could then blame any soundness issues on you using unsafe incorrectly.

The other reason we have this check is that I don't fully trust the static const checks reliably rejecting certain patterns in const contexts. So I wanted code like this to be rejected by a 2nd line of defense:

```rust
static OH_NO: &mut i32 = &mut 42;

```

That is achieved by the error you ran into. We could make the error smarter, suppressing it behind shared references, but interior mutability makes that non-trivial.

---

<div class="post-metadata">

**Author:** ![JarredAllen](https://avatars.discourse-cdn.com/v4/letter/j/a183cd/32.png) [@JarredAllen](https://internals.rust-lang.org/u/JarredAllen)\
**Post date:** [July 28, 2025, 5:53pm UTC](https://internals.rust-lang.org/t/create-static-box-t-at-compile-time/23280/8 "2025-07-28T17:53:16Z")

</div>

What about a constructor for making `&'a Box<T>` from `&'a &'a T`? [Miri suggests that doing a raw transmute is sound](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=d741a0d402a3fd34f5d106abecd76e13), so the standard library should be able to make a `const` constructor for it. And since you only ever get a shared reference to the box, you won't call the destructor so you don't need to worry about allocating.

As for statically-constructed `Arc`s, this seems to me to be a benefit of handling overflow the way the linux kernel's `Arc`s do, by saturating at the limit and leaking the value instead of aborting. I have a library with an `Arc`-like thing I've been working on, and I can statically construct it by starting with the count already saturated, so it will never try to free it. And I think this change to `Arc` would be allowed, since I don't see anything in the docs promising this behavior.

These don't solve the issue of potentially including an allocator API for querying info about an allocation, but if that's a concern, we could make the constructors return a `Box`/`Arc` referencing some stdlib-private allocator that users can't get at so they can't try to call those methods.

---

<div class="post-metadata">

**Author:** ![jjpe](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jjpe/32/9779_2.png) [@jjpe](https://internals.rust-lang.org/u/jjpe)\
**Post date:** [July 29, 2025, 4:39pm UTC](https://internals.rust-lang.org/t/create-static-box-t-at-compile-time/23280/9 "2025-07-29T16:39:16Z")

</div>

I have a silly-sounding question.

Why opt for `&’static Box<T>` when you can just leak a `Box<T>` and obtain a `&’static T`?

What is the advantage of putting the former (and its reference-counting siblings) behind a `&’static` shared borrow vis a vis the latter?

EDIT:

Upon further reflection, I see only downsides to the former, as you get additional pointer chasing (and accompanying cache misses) due to the double indirection.

So it’s not a rhetorical question. I'm assuming that despite the downsides there is a valid use case for putting a box/rc/arc value behind an additional `&’static` borrow.

---

<div class="post-metadata">

**Author:** ![toc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/toc/32/6692_2.png) [@toc](https://internals.rust-lang.org/u/toc)\
**Post date:** [July 29, 2025, 10:48pm UTC](https://internals.rust-lang.org/t/create-static-box-t-at-compile-time/23280/10 "2025-07-29T22:48:56Z")

</div>

> [@jjpe](#):
>
> Why opt for `&’static Box<T>` when you can just leak a `Box<T>` and obtain a `&’static T`?

I think this is for cases where the static in question is typically being used as a `Box<T>`/`Arc<T>`, and thus some trickery would be necessary to use it in its native fashion. I’d love to see some concrete examples of this, but I am not doubtful they exist.

Side note: I don’t think “pointer chasing” concerns really hold water on global statics. My guess is they are perfectly predicted, and in any case global statics aren’t really something we have `n` of.

---

<div class="post-metadata">

**Author:** ![JeffBurdges](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jeffburdges/32/2116_2.png) [@JeffBurdges](https://internals.rust-lang.org/u/JeffBurdges)\
**Post date:** [August 13, 2025, 11:55pm UTC](https://internals.rust-lang.org/t/create-static-box-t-at-compile-time/23280/11 "2025-08-13T23:55:43Z")

</div>

> [@jjpe](#):
>
> Why opt for `&’static Box<T>` when ...?

That was never the question. I literally wrote:

> [@JeffBurdges](#):
>
> You'd never use `&'static Box<[T]>` directly, since it incurs an indirection, without any benefits, but..

The real question was: If we have a complex type with internal allocation, then how should we best create some compile-time deeply `'static` flavor? So `&'static Parameters` where `Parameters` contains a `Box<[T]>` in read only memory?

You cannot simply leak that `foo: Box<[T]>` because you cannot even create that `foo` during regular production runtime. If `foo` were FFT parameters, then you might blow your whole FFT optimization recreating them every time your consumer loads your code. Yet, you do want roughly the same algebraic operations available when creating `foo`. If `foo` were AI weghts, then you've fresh local layers, but the deeper layers cost serious money. If `foo` comes from some cryptographic ceremony, then `foo` could only be created during a meeting by specific trusted people, but you might've dynamic flavors being created all the time.

Above, the answer has two parts:

1. `Cow<'static,[T]>` incurs no variant check, making it typically free when used immutably in `Parameters`. It's not free when used mutably of course. This answer works for types you initialize in code during development, but want statically initialization in production. Afaik this covers every case I'll hit.

2. Interior mutability could mess up `&'static Parameters`, like if `Parameters` contains `Mutex<T>`. Yet, `Box<T>: Freeze` whenever `T: Freeze`, so maybe E0080 could be silenced using `Freeze`?

---

<div class="post-metadata">

**Author:** ![quinedot](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/quinedot/32/7294_2.png) [@quinedot](https://internals.rust-lang.org/u/quinedot)\
**Post date:** [August 14, 2025, 12:38am UTC](https://internals.rust-lang.org/t/create-static-box-t-at-compile-time/23280/12 "2025-08-14T00:38:45Z")

</div>

> [@JeffBurdges](#):
>
> `Box<T>: Freeze` whenever `T: Freeze`

`Box<T>`\[1\] is _always_ `Freeze`. `Freeze` does not mean an absence of interior mutability generally, only shallowly -- before indirection. And `Box` is all about indirection.

* * *

1. with the default allocator
