Filter_map cause E0495 error

Hi guys, I am trying to make the code below works, especially the test method.

struct A<T> {
    inner: Vec<T>,
}

impl<T> A<T> {
    fn get_mut(&mut self, ind: usize) -> Option<&mut T> {
        self.inner.get_mut(ind)
    }

    fn test(&mut self) -> Vec<&mut T> {
        [0, 1, 2]
            .into_iter()
            .filter_map(|ind| self.get_mut(*ind))
            .collect()
    }
}

When I am trying to build the code, compiler tell me that:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/filter_map.rs:13:36
   |
13 |             .filter_map(|ind| self.get_mut(*ind))
   |                                    ^^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime `'_` as defined here...
  --> src/filter_map.rs:13:25
   |
13 |             .filter_map(|ind| self.get_mut(*ind))
   |                         ^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that closure can access `self`
  --> src/filter_map.rs:13:31
   |
13 |             .filter_map(|ind| self.get_mut(*ind))
   |                               ^^^^
note: but, the lifetime must be valid for the anonymous lifetime defined here...
  --> src/filter_map.rs:10:13
   |
10 |     fn test(&mut self) -> Vec<&mut T> {
   |             ^^^^^^^^^
note: ...so that the types are compatible
  --> src/filter_map.rs:11:9
   |
11 | /         [0, 1, 2]
12 | |             .into_iter()
13 | |             .filter_map(|ind| self.get_mut(*ind))
14 | |             .collect()
   | |______________________^
   = note: expected `Vec<&mut T>`
              found `Vec<&mut T>`

I am a bit confused about the notes from compiler. I thought the Option<&mut T> of get_mut method should follow the lifetime of &self, so the result Vec<&mut T> should also follow the &self lifetime right?

Obviously, I am wrong. So how can I fix it and which part of my thought is wrong?

Thank you!

The analysis that the compiler uses doesn't know that all of your indices [0,1,2] are unique. This code looks the same to the compiler but can never work, because it produces multiple &mut references to a single item:

    fn test(&mut self) -> Vec<&mut T> {
        [0, 0, 0]
            .into_iter()
            .filter_map(|ind| self.get_mut(*ind))
            .collect()
    }
2 Likes

And to help you write code that will actually compile, you can just take a mutable slice of the inner vec:

fn test(&mut self) -> &mut [T] {
    &mut self.inner[..3]
}

It is unclear if this is what you actually want to write. I understand that questions like this usually end up simplifying the problem too much and devolving to an XY problem.

But anyway, this code does what the original snippet appears to want to achieve. Rust Playground

2 Likes

Here's another interpretation of what you may want -- a way to return mutable references to some subset of the inner values, by indices.

4 Likes

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.