'Cannot borrow "values" as immutable because it is also borrowed as mutable
I've found lots of questions asking about immutable to mutable, but am not quite sure what I am doing wrong in this code.
The error I am getting is:
"cannot borrow values as immutable because it is also borrowed as mutable"
fn modify_vec_get_slice(values: &mut Vec<i32>) -> &[i32] {
// Modify "values" in some way
values.push(5);
// Return a slice into "values" (dummy code)
values.split_at(values.len() / 2).1
}
fn use_slice(slice: &[i32]) {
// Do something immutably with the slice
}
fn use_vec(values: &Vec<i32>) {
// Do something immutably with the vec
}
fn main() {
let mut values = vec![1, 2, 3, 4];
let slice = modify_vec_get_slice(&mut values); // use values mutably
use_vec(&values); // Error here is "&values" underlined in red, even though "values" is used immutably
use_slice(slice); // use slice immutably (which refers to the vec?). Uncommenting this line fixes the error
}
Why can't I use the slice (an immutable reference) when I can use &values (also an immutable reference)? Surely the mutable reference used in "modify_vec_get_slice" has ended by the time I get to the other functions?
Solution 1:[1]
The problem is that slice effectively owns a mutable borrow on values. To you it looks like this shouldn't be the case because the reference returned by modify_vec_get_slice() is immutable, but that immutable reference is tied to the lifetime of the mutable reference given to the function. If we explicitly specify the lifetimes that were assumed by the compiler via lifetime elision, this becomes clear:
fn modify_vec_get_slice<'a>(values: &'a mut Vec<i32>) -> &'a [i32] {
The returned reference is only allowed to live as long as the mutable borrow does, therefore extending the lifetime of slice extends the mutable borrow as well. There isn't any kind of implied "reference type downgrading" that happens in this scenario.
The simplest way to address this problem is to split the function into two, one that takes a mutable reference and performs the mutation, and one that takes an immutable reference and computes the bounds of the slice and returns it.
Further reading:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
