Hi, I’m having trouble with some code, and I’ve managed to reduce the issue to this test case:
fn test<'a>(xs: &'a mut Vec<String>) -> Option<&'a String> {
if let Some(x) = xs.first_mut() {
return Some(x);
}
xs.first()
}
fn main() {
test(&mut vec!["hi".to_string()]);
}
Compiler output:
t.rs:6:5: 6:7 error: cannot borrow `*xs` as immutable because it is also borrowed as mutable [E0502]
t.rs:6 xs.first()
^~
t.rs:2:22: 2:24 note: previous borrow of `*xs` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `*xs` until the borrow ends
t.rs:2 if let Some(x) = xs.first_mut() {
^~
t.rs:7:2: 7:2 note: previous borrow ends here
t.rs:1 fn test<'a>(xs: &'a mut Vec<String>) -> Option<&'a String> {
...
t.rs:7 }
^
t.rs:6:5: 6:7 error: cannot borrow `*xs` as immutable because it is also borrowed as mutable [E0502]
t.rs:6 xs.first()
^~
t.rs:2:22: 2:24 note: previous borrow of `*xs` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `*xs` until the borrow ends
t.rs:2 if let Some(x) = xs.first_mut() {
^~
t.rs:7:2: 7:2 note: previous borrow ends here
t.rs:1 fn test<'a>(xs: &'a mut Vec<String>) -> Option<&'a String> {
...
t.rs:7 }
^
error: aborting due to 2 previous errors
So, if a branch (if let
or match
) borrows a mutable reference to a variable and uses it to return early, the borrow is considered alive for the rest of the function body, and I can’t find a way to reduce this scope. I don’t see why this happens, especially considering that when there’s no early return
the code compiles…
Thanks in advance for the help!