Help with lifetime compile problem

I have some code as follows, I don't quite understand why the compiler is complaining about lifetime, can someone help me about this?

    struct Entity {}

    struct Container<'a> {
        root_index: usize,
        entities: &'a mut [Entity],
    }

    impl<'a> Container<'a> {
        fn root(&self) -> &'a Entity {
            &self.entities[self.root_index]
        }
    }

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> src/lib.rs:10:14
   |
10 |             &self.entities[self.root_index]
   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 9:9...
  --> src/lib.rs:9:9
   |
9  |         fn root(&self) -> &'a Entity {
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
  --> src/lib.rs:10:14
   |
10 |             &self.entities[self.root_index]
   |              ^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 8:10...
  --> src/lib.rs:8:10
   |
8  |     impl<'a> Container<'a> {
   |          ^^
note: ...so that reference does not outlive borrowed content
  --> src/lib.rs:10:13
   |
10 |             &self.entities[self.root_index]
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0495`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

You need to tie the lifetime to self rather than to the owner of the array.

impl<'a> Container<'a> {
    fn root<'b>(&'b self) -> &'b Entity {
        &self.entities[self.root_index]
    }
}

(or in shorthand with lifetimes elided)

impl<'a> Container<'a> {
    fn root(&self) -> &Entity {
        &self.entities[self.root_index]
    }
}

Since Container does not own its data, instead it is a temporary view over a slice, I would assume it is exactly the point that OP wants root to give away a reference with its lifetime tied to the underlying slice, and not to that of the "container"/view itself. (I'm not sure if that is at all possible with &mut, though.)

1 Like

You can't get a reference with lifetime 'a out because if you don't borrow self, then you can still access Container while the returned &Entity is alive, however accessing the &mut [Entity] would be invalid here as mutable references must have exclusive access, which you don't have due to the existence of an &Entity to the array.

2 Likes

Are you sure you don't want Container to store any entities? As written, it only borrows them. You probably should have entities: Vec<Entity> or entities: Box<[Entity]> if you want to store them by reference.

1 Like