I have the following code:
struct Bar<T> {
k: [T; 10],
}
impl<T> Bar<T> {
fn thing(&self, i: usize) -> &T {
&self.k[i]
}
fn thing_mut(&mut self, i: usize) -> &mut T {
&mut self.k[i]
}
}
struct Foo<'a, T: 'a> {
bar: &'a Bar<T>,
count: usize,
}
impl<'a, T> Foo<'a, T> {
fn get(&mut self) -> Option<&'a T> {
if self.count < 10 {
let thing = self.bar.thing(self.count);
self.count += 1;
Some(thing)
} else {
None
}
}
}
struct FooMut<'a, T: 'a> {
bar: &'a mut Bar<T>,
count: usize,
}
impl<'a, T> FooMut<'a, T> {
fn get(&mut self) -> Option<&'a mut T> {
if self.count < 10 {
let thing = self.bar.thing_mut(self.count);
self.count += 1;
Some(thing)
} else {
None
}
}
}
Foo
compiles, but FooMut
does not:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/main.rs:40:34
|
40 | let thing = self.bar.thing_mut(self.count);
| ^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 38:5...
--> src/main.rs:38:5
|
38 | / fn get(&mut self) -> Option<&'a mut T> {
39 | | if self.count < 10 {
40 | | let thing = self.bar.thing_mut(self.count);
41 | | self.count += 1;
... |
45 | | }
46 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:40:25
|
40 | let thing = self.bar.thing_mut(self.count);
| ^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 37:1...
--> src/main.rs:37:1
|
37 | impl<'a, T> FooMut<'a, T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...so that the expression is assignable:
expected std::option::Option<&'a mut T>
found std::option::Option<&mut T>
Why does the immutable one compile just fine, but not the mutable one? Is there some lifetime annotation I am missing in the FooMut
case? I have seen plenty of answers for lifetimes and references, but I am specifically asking in this case about the mutable vs non-mutable case.