I have a vector of references, and push a reference to a value, move the value and then attempt to use the vector:
fn main() {
let mut my_vec: Vec<&Box<i32>> = vec![];
let my_val = Box::new(5);
my_vec.push(&my_val);
drop(my_val);
println!("{:?}", my_vec)
}
This gives us an error:
error[E0505]: cannot move out of `my_val` because it is borrowed
--> src/main.rs:5:10
|
4 | my_vec.push(&my_val);
| ------- borrow of `my_val` occurs here
5 | drop(my_val);
| ^^^^^^ move out of `my_val` occurs here
6 | println!("{:?}", my_vec)
| ------ borrow later used here
If this was allowed to compile, we would get a use after free so it's good that Rust is able to detect that the vector can't outlive things it references.
If we look at this similar piece of code
fn dont_push<T>(_v: &mut Vec<T>, _a: T) {}
fn main() {
let mut my_vec: Vec<&Box<i32>> = vec![];
let my_val = Box::new(5);
dont_push(&mut my_vec, &my_val);
drop(my_val);
println!("{:?}", my_vec)
}
We get the same error:
error[E0505]: cannot move out of `my_val` because it is borrowed
--> src/main.rs:7:10
|
6 | dont_push(&mut my_vec, &my_val);
| ------- borrow of `my_val` occurs here
7 | drop(my_val);
| ^^^^^^ move out of `my_val` occurs here
8 | println!("{:?}", my_vec)
| ------ borrow later used here
This seems to suggest that Rust looks at the type signature of push and dont_push to figure out that it's possible that my_vec requires my_val to still be alive.
What is the general rule?
From my experimenting here, it looks like it might be something along the lines of "if one argument to a function is a mutable reference, that argument can't outlive the other ones". What happens if there are multiple mutable references?