I'm having a problem with the code below. The immutable iterator works fine, but the mutable one gives me the following error:
cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements.
Is it possible to somehow fix this error without using unsafe rust and sticking to the Iterator trait?
Link to the playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ae0b3f4c5c7749b130fe0b0142beb9e7
Code:
struct Collection<T, const S: usize> {
data: Vec<T>
}
struct CollectionIterator<'a, T, const S: usize> {
item_index: usize,
collection: &'a Collection<T, S>
}
struct CollectionIteratorMut<'a, T, const S: usize> {
item_index: usize,
collection: &'a mut Collection<T, S>
}
impl<T: Clone, const S: usize> Collection<T, S> {
fn new(num_items: usize, default_value: T) -> Collection<T, S> {
Collection {
data: vec![default_value; num_items * S]
}
}
fn iter(&self) -> CollectionIterator<T, S> {
CollectionIterator {
item_index: 0,
collection: self
}
}
fn iter_mut(&mut self) -> CollectionIterator<T, S> {
CollectionIterator {
item_index: 0,
collection: self
}
}
}
impl<'a, T, const S: usize> Iterator for CollectionIterator<'a, T, S> {
type Item = &'a [T];
fn next(&mut self) -> Option<Self::Item> {
if self.item_index < self.collection.data.len() {
self.item_index += S;
Some(&self.collection.data[self.item_index - S .. self.item_index])
} else {
None
}
}
}
impl<'a, T, const S: usize> Iterator for CollectionIteratorMut<'a, T, S> {
type Item = &'a mut [T];
fn next(&mut self) -> Option<Self::Item> {
if self.item_index < self.collection.data.len() {
self.item_index += S;
Some(&mut self.collection.data[self.item_index - S .. self.item_index])
} else {
None
}
}
}
fn main() {
let mut c: Collection<f64, 3> = Collection::new(5, 0.0);
for x in c.iter_mut() {
x[0] = 100.0;
}
for x in c.iter() {
println!("{} {} {}", x[0], x[1], x[2]);
}
}
Error:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:52:23
|
52 | Some(&mut self.collection.data[self.item_index - S .. self.item_index])
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 49:13...
--> src/main.rs:49:13
|
49 | fn next(&mut self) -> Option<Self::Item> {
| ^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:52:23
|
52 | Some(&mut self.collection.data[self.item_index - S .. self.item_index])
| ^^^^^^^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 47:6...
--> src/main.rs:47:6
|
47 | impl<'a, T, const S: usize> Iterator for CollectionIteratorMut<'a, T, S> {
| ^^
note: ...so that the types are compatible
--> src/main.rs:49:46
|
49 | fn next(&mut self) -> Option<Self::Item> {
| ______________________________________________^
50 | | if self.item_index < self.collection.data.len() {
51 | | self.item_index += S;
52 | | Some(&mut self.collection.data[self.item_index - S .. self.item_index])
... |
55 | | }
56 | | }
| |_____^
= note: expected `Iterator`
found `Iterator`