Is the lifetime of `&mut []` treated specially during lifetime analysis in Rust?

Empty array is indeed special-cased by the compiler.

This answer describes the similar yet different case with shared references to constexpr-values. For this case, there is an RFC to make this constexpt-values "promoted to static", i.e. allocated in static memory and not at stack, so that they will live outside the function they're defined in.

And, inside this RFC, we have the following statement:

the compiler already special cases a small subset of rvalue const expressions to have static lifetime - namely the empty array expression:

let x: &'static [u8] = &[];

As for the mutable - or, as will be more relevant here, exclusive, or unique, references, RFC states the following:

It would be possible to extend support to &'static mut references, as long as there is the additional constraint that the referenced type is zero sized.
...
The zero-sized restriction is there because aliasing mutable references are only safe for zero sized types (since you never dereference the pointer for them).

This part seems to be not implemented, since this code is invalid:

fn main() {
    let _: &'static mut [()] = &mut [()]; // fail, reference to local
}

although [(); 1] is ZST, as one can check with std::mem::size_of.


The line self.0 = &mut []; works but is very strange if we look at their lifetimes: a reference to a local variable is assigned to self.0, which lives beyond the method call clear().

This is because Rust has rvalue static promotion feature which is explained in another post which @Lukas Kalbertodt pointed in comment,

Please check : Why can I return a reference to a local literal but not a variable?


For the lifetime error in this code:

self.0 = &mut [0];

This is not supported by static promotion from the RFC :

It would be possible to extend support to &'static mut references, as long as there is the additional constraint that the referenced type is zero sized.

This is a constraint for static mutability in this feature. It is possible for immutable types.

The code below will work fine for immutable slices.

let _: &'static [u32] = &[1, 2, 3]; // Possible

let _: &'static mut [u32] = &mut [1, 2, 3]; //Not possible

Tags:

Rust