#Data remains borrowed after return

7 messages · Page 1 of 1 (latest)

thin vortex
#

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=eab1394af98134c406c7c0fe36bb0f94

struct Foo {
    data: Option<u8>,
}

impl Foo {
    fn get(&mut self) -> &u8 {
        if let Some(data) = self.data.as_ref() {
            if *data > 10 {
                return data;
            }
        }

        self.data.insert(20)
    }
}
Compiling playground v0.0.1 (/playground)
error[E0502]: cannot borrow `self.data` as mutable because it is also borrowed as immutable
  --> src/main.rs:13:9
   |
6  |     fn get(&mut self) -> &u8 {
   |            - let's call the lifetime of this reference `'1`
7  |         if let Some(data) = self.data.as_ref() {
   |                             ------------------ immutable borrow occurs here
8  |             if *data > 10 {
9  |                 return &data;
   |                        ----- returning this value requires that `self.data` is borrowed for `'1`
...
13 |         self.data.insert(20)
   |         ^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here

For more information about this error, try `rustc --explain E0502`.
error: could not compile `playground` (bin "playground") due to previous error

I expect that this should compile because when the code flow exits the if statements, data is dropped and so is the immutable borrow on self.data.

#

I don't want to use get_or_insert because I need to treat data <= 10 same as None

kind hornet
#

it seems like a limit in the borrow checker, since you return &data in the if, the immutable borrow need to live as long as the original borrow, from the compiler limited pov

toxic bough
#

This is a known limitation that the (future) polonus borrow checker is supposed to solve

tame lion
#

I think this is the issue that https://docs.rs/polonius-the-crab/latest/polonius_the_crab/ is a workaround for.

Alternately, this https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d70d1c09bcdb4edda968af510dfc74fd compiles and does the same thing (though only if you do the check with pattern matching; adding an if *data > 10 guard to the first arm gives the same error as above)

thin vortex
#

Thanks everyone, this was very informative