'Implementing Index for type with a lifetime parameter

I have some types like this, where they each have a lifetime parameter.

use std::marker::PhantomData;
use std::ops::Index;

pub struct Foo<'ctx> {
    bars: Vec<Bar<'ctx>>,
    phantom: PhantomData<&'ctx ()>,
}

impl Foo<'_> {
    pub fn get_bar(&self, index: usize) -> Option<&Bar> {
        self.bars.get(index)
    }
}

pub struct Bar<'ctx> {
    // pretend we are using a context here
    phantom: PhantomData<&'ctx ()>,
}

I'd like to implement Index for Foo, but the compiler doesn't like it:


impl <'ctx> Index<usize> for Foo<'ctx> {
    type Output = Bar<'ctx>;

    fn index(&self, _index: usize) -> &Self::Output {
        self.get_bar(_index).unwrap()
    }
}

I get this error:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/ir/foo.rs:24:14
   |
24 |         self.get_bar(_index).unwrap()
   |              ^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime defined here...
  --> src/ir/foo.rs:23:14
   |
23 |     fn index(&self, _index: usize) -> &Self::Output {
   |              ^^^^^
note: ...so that reference does not outlive borrowed content
  --> src/ir/foo.rs:24:9
   |
24 |         self.get_bar(_index).unwrap()
   |         ^^^^
note: but, the lifetime must be valid for the lifetime `'ctx` as defined here...
  --> src/ir/foo.rs:20:7
   |
20 | impl <'ctx> Index<usize> for Foo<'ctx> {
   |       ^^^^
note: ...so that the types are compatible
  --> src/ir/foo.rs:23:53
   |
23 |       fn index(&self, _index: usize) -> &Self::Output {
   |  _____________________________________________________^
24 | |         self.get_bar(_index).unwrap()
25 | |     }
   | |_____^
   = note: expected `<Foo<'ctx> as Index<usize>>`
              found `<Foo<'_> as Index<usize>>`

(I see a few similar questions on SO but they all seem to differ in the particulars, namely that the Output type has a lifetime parameter).



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source