I am having issues with a struct that I am passing around as a mutable reference. The issue only occurs when the struct is defined to hold a reference.
struct Global<'a> {
one: i32,
two: &'a i32
}
fn do_task<'a, F, R: 'a>(global: &'a mut Global<'a>, task: F)
where F: Fn(&'a mut Global<'a>) -> &'a R {
let result = task(global);
}
fn one<'a>(global: &'a mut Global<'a>) -> &'a i32 {
&global.one
}
fn two<'a>(global: &'a mut Global<'a>) -> &'a i32 {
global.two
}
fn main() {
let number = 2;
let mut global = Global {
one: 1,
two: &number
};
do_task(&mut global, one);
do_task(&mut global, two);
}
The borrow checker complains with the following:
error: cannot borrow `global` as mutable more than once at a time
do_task(&mut global, two);
^~~~~~
note: previous borrow of `global` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `global` until the borrow ends
do_task(&mut global, one);
^~~~~~
note: previous borrow ends here
fn main() {
...
}
^
But, if I change the code so that the field two
is not a reference, like in the following example, then it passes.
struct Global {
one: i32,
two: i32,
}
fn do_task<'a, F, R: 'a>(global: &'a mut Global, task: F)
where F: Fn(&'a mut Global) -> &'a R {
let result = task(global);
}
fn one<'a>(global: &'a mut Global) -> &'a i32 {
&global.one
}
fn two<'a>(global: &'a mut Global) -> &'a i32 {
&global.two
}
fn main() {
let mut global = Global {
one: 1,
two: 2
};
do_task(&mut global, one);
do_task(&mut global, two);
}
I tried surrounding the do_task
function calls with another scope, but it had no effect.
Why does having the reference extend the mutable borrow to the end of main, and is there any way around this?
I am using rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14)