How to get a static reference of a generic constant?

This trait cannot be compiled

trait GetConst {
    type Get: Copy;
    const GET: Self::Get;
    
    fn get() -> &'static Self::Get {
        &Self::GET
    }
}

which gives an error

error[E0515]: cannot return reference to temporary value
 --> src/lib.rs:8:9
  |
8 |         &Self::GET
  |         ^---------
  |         ||
  |         |temporary value created here
  |         returns a reference to data owned by the current function

For more information about this error, try `rustc --explain E0515`.

I know some types with destructors that can be put in constant, like Vec<T>, which makes itself cannot be static. But is there some trait bound that can constrain a type to must have no destructor, to prevent something like Vec<T> , make this example compile? Thanks.

TLDR: generic static variables are not supported -- static items are top level items, even if they were defined inside the scope of (generic) functions.

the reason you can take a 'static reference to a constant of concrete types, is because constant promotion occurs. a generic type CANNOT be promoted.

1 Like

This can work when the function body is defined in an impl and not the trait:

trait GetConst {
    type Get: Copy;
    const GET: Self::Get;
    fn get() -> &'static Self::Get;
}

struct Foo;
#[derive(Clone, Copy)]
struct Bar;

impl GetConst for Foo {
    type Get = Bar;
    const GET: Bar = Bar;
    fn get() -> &'static Self::Get {
        &Self::GET
    }
}

Alternatively, you could make the constant itself be a reference, which callers can dereference if they want the value:

trait GetConst {
    type Get: Copy + 'static;
    const GET: &'static Self::Get;
}

impl GetConst for Foo {
    type Get = Bar;
    const GET: &'static Bar = &Bar;
}

Neither of these will work if the impl is itself generic.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.