Hi,
I am writing a special kind of container for which I would like to provide an Iterator. The immutable Iterator does not pose a problem but the mutable one. This is a minimal example:
trait Item {}
impl Item for u32 {}
struct Container<T: Item> {
data: Vec<T>,
}
struct IterMut<'a, T: 'a + Item> {
container: &'a mut Container<T>,
index: usize,
}
impl<'a, T: Item> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
let item = &mut self.container.data[self.index]; // error here!
Some(item)
}
}
fn main() {
let mut container = Container {
data: vec![1u32, 2, 3],
};
let iter_mut = IterMut {
container: &mut container,
index: 0,
};
for i in iter_mut {
// ...
}
}
The resulting error is:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:17:25
|
17 | let item = &mut self.container.data[self.index]; // error here!
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 16:5...
--> src/main.rs:16:5
|
16 | / fn next(&mut self) -> Option<Self::Item> {
17 | | let item = &mut self.container.data[self.index]; // error here!
18 | | Some(item)
19 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:17:25
|
17 | let item = &mut self.container.data[self.index]; // error here!
| ^^^^^^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 14:1...
--> src/main.rs:14:1
|
14 | impl<'a, T: Item> Iterator for IterMut<'a, T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...so that the types are compatible:
expected std::iter::Iterator
found std::iter::Iterator
My guess is that a second shorter lifetime is required for the returned reference but I cannot figure out how to express that with 'x: 'y. Am I wrong?
Can somebody please explain what the problem is and how to fix the code?
Note: I could simply return the standard iterator of the Vec but this is not the point here.
Thanks