Which borrow checker issue is this? Can't perform immutable borrow in none branch of optional mutable reference match

#![allow(unused)]

// fn get_mut_undeleted_section_match(v: &mut Vec<usize>, at: usize) -> &mut usize {
//     match v.get_mut(at) {
//         Some(se) => {
//             se
//         }
//         None => panic!("array was only {} long", v.len()),
//     }
// }

fn get_nonzero_section(v: &mut Vec<usize>, at: usize) -> &mut usize {
    if let Some(se) = v.get_mut(at) {
        se
    } else {
        panic!("array was only {} long", v.len())
    }
}

fn main() {}

(Playground)

It's so simple, we can tell that in the none branch, the mutable borrow is no longer needed (the match branch contains no reference members, so should not hold the borrow), but it wont allow the immutable borrow. I'm sure something like this has been reported before, but I don't know how to find the tracking issue.

(workaround: Take a copy of v.len() at the beginning, but what I'm really interested in is finding the tracking issue. This wouldn't be adequiate if, for instance, you needed to run a complex query on v in the non-matching arm, based on what was in the arm.)

3 Likes

This is the “conditional return” problem that is fixed in the next-generation borrow-checker Polonius. You can enable Polonius in nightly builds of rustc with the -Z polonius option.

For more information, see the Polonius working group.

3 Likes

You may wish to follow any/all of

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.