As others have said, the main idea here is to take &mut &... [T] (where ... is mut or empty) and read / write to the inner slice. Other answers demonstrate that it’s possible &mut &[T] in safe code and maybe &mut &mut [T] with unsafe code, but they do not explain why there is a difference ... and &mut &mut [T] with safe code too.
In expressions with explicit lifetimes, the nested link is something like &'a mut &'b ... [T] for some lifetimes of 'a and' b , and the goal here is to get a &'b ... [T] , slice and record this in &'a mut .
For &'a mut &'b [T] this is easy: &[T] is a copy, so writing *slice = &slice[1..] will effectively copy &'b [T] from &mut , and then overwrite the existing value more short. A copy means that it literally gets &'b [T] for work, and therefore there is no direct connection between this and &'a mut , and therefore it is legal to mutate. This is really something like
fn pop_front<'a, 'b>(slice: &'a mut &'b[i32]) {
(I have outlined lifetimes and annotated the type to associate it with my explanation, but this is not necessary for the code to work.)
For &'a mut &'b mut [T] everything is a little more complicated: &mut [T] cannot be copied: dereferencing will not be copied, it will reborrow to give &'a mut [T] , that is, the slice has a lifetime which is related to the external &'a mut , and not the internal &'b mut [T] . This means that the chopped link has a shorter lifetime than the type that it is trying to overwrite, so it is not valid for storing the fragment at this position. In other words:
fn pop_front<'a, 'b>(slice: &'a mut &'b mut [i32]) { let value: &'a mut [i32] = &mut **slice; *slice = &mut value[1..] // error }
A safe way for &'a mut &'b mut [T] is to get an internal slice from a link with this 'b lifetime. This requires tracking the “single owner” rule, without borrowing, and the best function for manipulating ownership is mem::replace . This allows us to extract the internal &'b mut [T] , replacing it with some kind of placeholder, which we can then overwrite with the short version. The best / only placeholder is an empty array: the entry &mut [] can be &'c mut [X] for any type X and any lifetime 'c , since there is no data to store, and therefore nothing needs to be initialized, and no data will never become invalid. In particular, it could be &'b mut [T] :
fn pop_front<'a, 'b>(slice: &'a mut &'b mut [i32]) { let value: &'b mut [i32] = mem::replace(slice, &mut []); *slice = &mut value[1..] }
(As above, I made things more explicit than necessary.)