I have the following working code (minimal example):
#[derive(Debug)]
struct Item {
x: i32
}
fn main() {
let mut items = vec![Item {x: 1}, Item {x: 2}, Item {x: 3}];
do_processing(&mut items, |items| {
dbg!(items);
});
}
fn do_processing<F>(items: &mut Vec<Item>, progress_closure: F)
where F: Fn(&Vec<Item>) {
for i in 0..items.len() {
let item = &mut items[i];
item.x += 1;
progress_closure(items);
}
}
I now want to move the progress closure into a variable, because I want to reuse it.
fn main() {
let mut items = vec![Item {x: 1}, Item {x: 2}, Item {x: 3}];
let progress_closure = |items| {
dbg!(items);
};
do_processing(&mut items, progress_closure);
}
This fails to compile, probably due to problems inferring the right type for the closure.
error: implementation of `FnOnce` is not general enough
--> src/main.rs:22:5
|
22 | do_processing(&mut items, progress_closure);
| ^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 Vec<Item>)` must implement `FnOnce<(&'1 Vec<Item>,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 Vec<Item>,)>`, for some specific lifetime `'2`
I therefore added lifetime annotations to do_processing
:
fn do_processing<'a, F>(items: &'a mut Vec<Item>, progress_closure: F)
where F: Fn(&'a Vec<Item>) {
for i in 0..items.len() {
let item = &mut items[i];
item.x += 1;
progress_closure(items);
}
}
However now I get the error that item
is still borrowed at the time of the progress_closure
call. I would assume that the borrow on item would end after the previous line, but apparently this is not the case.
error[E0502]: cannot borrow `*items` as mutable because it is also borrowed as immutable
--> src/main.rs:45:25
|
42 | fn do_processing<'a, F>(items: &'a mut Vec<Item>, progress_closure: F)
| -- lifetime `'a` defined here
...
45 | let item = &mut items[i];
| ^^^^^ mutable borrow occurs here
46 | item.x += 1;
47 | progress_closure(items);
| -----------------------
| | |
| | immutable borrow occurs here
| argument requires that `*items` is borrowed for `'a
Can somebody help me fix this situation?