Workaround before Polonius makes it to stable

Hello,

This pattern is safe but the stable borrow checker doesn't agree. Polonius is cool with it though.

fn func(vec: &mut Vec<usize>) -> Option<&mut usize> {
    for i in 0..1000 {
        //Needs Polonius to work
        match vec.get_mut(i) {
            Some(result) => {return Some(result);},
            None => {}
        };

        //Works reagrdless
        // let mut idx = None;
        // match vec.get_mut(i) {
        //     Some(result) => {idx = Some(i)},
        //     None => {}
        // };
        // match idx {
        //     Some(idx) => {return vec.get_mut(idx)},
        //     None => {}
        // }
    }
    None
}

fn main() {
    let mut my_vec = vec![9, 8, 7];
    let result = func(&mut my_vec);
    println!("{result:?}");
}

I have one workaround (commented out) but it's not workable in practice. (Vec::get_mut is a placeholder for another method with the same kind of signature)

Does anyone know another work-around that's available on stable that doesn't require calling the method twice?

Thank you

Will polonius-the-crab help here?

2 Likes

I think it just might! Thank you!

After spending far more time than I care to admit trying to refactor things to work without any craziness, I finally went with polonius-the-crab.

Yet another huge debt of gratitude to the amazing work of @Yandros

3 Likes

For curiosity, regarding https://docs.rs/polonius-the-crab/0.4.1/polonius_the_crab/fn.polonius.html#easier-apis-for-the-most-pervasive-use-cases, did you go for the sugary-but-with-poor-diagnostics macro API, or did you venture into directly using the underlying API (fn polonius(), PoloniusResult, and ForLt)?

2 Likes

The macro did what I needed. :slight_smile:

1 Like