Lifetime issue when shortening mutable slice

Hello

While poling a future, I want to progressively shorten a slice until is is empty:

slice = &slice[n..]

When it's a mutable slice the compiler complains about lifetime:

slice = &mut slice[n..]

Complete example and playground:

use std::{mem::transmute, pin::Pin};

#[derive(Debug)]
struct Foo<'a> {
    buf: &'a [u8],
}

impl<'a> Foo<'a> {
    fn skip(mut self: Pin<&mut Self>, n: usize) {
        // This is fine:
        self.buf = &self.buf[n..];
    }
}

#[derive(Debug)]
struct FooMut<'a> {
    buf: &'a mut [u8],
}

impl<'a> FooMut<'a> {
    fn skip(mut self: Pin<&mut Self>, n: usize) {
        // This ain't:
        // self.buf = &mut self.buf[n..];
        // I have to cheat:
        self.buf = unsafe { transmute(&mut self.buf[n..]) };
    }
}

fn main() {
    let mut data = [4, 8, 15, 16, 23, 42];

    let mut foo = Foo { buf: &data };
    let mut foo = Pin::new(&mut foo);
    foo.as_mut().skip(3);
    println!("{:?}", foo);

    let mut foo = FooMut { buf: &mut data };
    let mut foo = Pin::new(&mut foo);
    foo.as_mut().skip(3);
    println!("{:?}", foo);
}
self.buf = &mut std::mem::take(&mut self.buf)[n..];
1 Like

Thank you. That's interesting. I wonder why it simply works with a non mutable slice but not with the mutable one, since in any case the original slice reference is lost.

Because a non-mutable slice reference, i.e. the type &[T] implements Copy. This is why dereferencing &'a &' b [T] is allowed to give &'b [T], not just &'a [T].

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.