Search code examples
rustreferenceslicetraitslifetime

Rust lifetimes for implementing a trait on nested slices


I want to create a wrapper around (nested) slices for easy operations on multidimensional data, owned by a different struct. The most basic version of the mutable version of my slice wrapper might look like this:

struct MySliceMut<'a> {
    data: Vec<&'a mut [f32]>,
}

impl<'a, 'b> MySliceMut<'a> {
    fn get(&'b mut self) -> &'a mut [&'b mut [f32]] {
        self.data.as_mut_slice()
    }
}

Now if I want to implement a trait, for instance AddAssign, Rust does not seem to infer the lifetime of &mut self from the implementing type. The compiler complains that &mut self might outlive 'a:

impl<'a> AddAssign<MySlice<'a>> for MySliceMut<'a> { // lifetime 'a
    fn add_assign(&mut self, rhs: MySlice<'a>) { // lifetime '1
        let a = self.get(); // lifetime may not live long enough, '1 must outlive 'a
        let b = rhs.get();

        // do inplace addition here
    }
}

Full Code - Rust Playground

I tried to figure out the issue with the lifetimes, but can't find it. Would the trait impl require any additional annotations?


Solution

  • struct MySlice<'a> {
        data: Vec<&'a [f32]>,
    }
    
    impl<'a, 'b> MySlice<'a> {
        fn get(&'b self) -> &'a [&'b [f32]] {
            self.data.as_slice()
        }
    }
    

    Problem with your code is that fn get(&'b self) returns variable with wrong lifetime. Associated lifetime 'a of MySlice<'a> is lifetime of inner slice. Associated lifetime 'b of fn get(...) is lifetime of the self. So I guess the function probably should return &'b [&'a [f32]] instead.

    -- Edited --

    Make sure to change fn get(...) of MySliceMut either.