Consider the following function, recursively printing elements of a Vec
:
I.
// Compiles fine
fn print_recursive_string<'a>(vec: &'a mut Vec<String>) {
let e = vec.pop();
if e.is_none() {
return;
}
println!("{:?}", e);
print_recursive_string(vec);
vec.push(e.unwrap());
}
It compiles and works as expected: Rust Playground
II.
Now let’s replace the element type of Vec
from owned String
to a slice &'a str
:
// Compile error of multiple mutable borrows
fn print_recursive_slice<'a>(vec: &'a mut Vec<&'a str>) {
let e = vec.pop();
if e.is_none() {
return;
}
println!("{:?}", e);
print_recursive_slice(vec);
vec.push(e.unwrap()); // <--- compile error here
}
The function refuses to compile with the following error:
error[E0499]: cannot borrow `*vec` as mutable more than once at a time
--> src/lib.rs:8:5
|
1 | fn print_recursive_slice<'a>(vec: &'a mut Vec<&'a str>) {
| -- lifetime `'a` defined here
...
7 | print_recursive_slice(vec);
| --------------------------
| | |
| | first mutable borrow occurs here
| argument requires that `*vec` is borrowed for `'a`
8 | vec.push(e.unwrap());
| ^^^ second mutable borrow occurs here
Rust Playground
III.
Now let’s introduce another lifetime parameter 'b: 'a
and change the element type from &'a str
to &'b str
:
// Magic: compiles fine
fn print_recursive_slice_lt<'a, 'b>(vec: &'a mut Vec<&'b str>)
where
'b: 'a,
{
let e = vec.pop();
if e.is_none() {
return;
}
println!("{:?}", e);
print_recursive_slice_lt(vec);
vec.push(e.unwrap());
}
This code compiles and runs fine, but it’s completely unclear to me why. Rust Playground
What’s wrong with making everything to be of lifetime &'a
?