Non-static data in `static`

Hello,

what I basically need is to have something like Box, but with data living in static variable, not heap. But I cannot create a static variable that will hold the value. Partially because I cannot name required lifetimes, and TAIT wont help there either - statics cannot mention types from outter scope, so even if TAIT finds lifetime, it is still getting rejected. What can we do about it and should we?

Another possibility is that one day it will be possible to write an Allocator trait which will have Aligned<align, [u8; size]> as a backing buffer (Aligned trait is implementable in stable rust, see elain) and give Box<T, impl Allocator>. I guess concrete allocator type should remain erased.

The Some code example:

use std::{mem::MaybeUninit, ptr::{addr_of_mut, drop_in_place}};

fn main() {
    struct Foo<'a>(&'a i32);
    static mut FOO: MaybeUninit<Foo<'?>> = MaybeUninit::uninit();

    unsafe {
        let num: i32 = 42;
        let foo = Foo(&num);
        let foo_uninit = &mut *addr_of_mut!(FOO);
        let foo = foo_uninit.write(foo);
        println!("{}", foo.0);
        drop_in_place(foo);
    }
}

TAIT feature also does not allow this - or at least not in my hands.

Maybe if there was trait Staticalize that would be something like that: Staticalize<for<'a> Foo<'a>>::Static -> Foo<'static> (and work with futures etc), then one might use it or TAIT to get job done?

Well, this will require unsafe code anyway, so you can just transmute() to Foo<'static>.

What if Foo cannot be named? Type inference cannot understand, that Dst should be the same as Src but with 'static bounds

From lifetimes perspective, this is not allowed, because there can be code running after main exits, e.g. Termination formatter, panic hook, atexit handlers, other threads, and they could all access 'static data that outlives data in main.


To initialize static data at run time, Rust uses OnceCell/LazyCell and similar. There's a cost of a check on every access.

If you ensure the data is always initialised before it's used and isn't mutated afterwards, you could access it safely without a check. It does require unsafe to implement.

You cannot do it even with unsafe

I've opened What do we need to get the same functionality without `generic_const_exprs`? that elaborates the question. There is real unsafe implemention, but it requires feature generic_const_expressions. I would really appreciate if you have a knowledge on how to make it "just using unsafe". Especially for unnamable types, like futures - not just store Foo<'static> and unsafely write Foo<'a>, because you cannot rewrite lifetimes of unnamable type - maximum it just get it with TAIT feature

Sorry, I've meant you'd have to use a 'static lifetime for the type, and actually have it obey such lifetime.

I don't think Rust has any way to reason about shorter lifetimes accessed through anything global, since lifetimes are very scope-oriented.

Well, I agree that Rust is not obligated to reason about them, but at least give ability to use unsafe, so users can reason about them themselves. Now there is just no way to do this without replacing 'a to 'static by hand, but you can only do it with nameable types

Instead of accessing the mutable static directly post initialization, you could access it via a function. A function could read any sort of type out of a backing static mut [u64; BIG_ENOUGH].

This is exactly what I did in liked post and to be ergonomic it requires (maybe Perma) unstable feature generic_const_expressions

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.