Why does the setter reject the inline expression, but take its broken form?

I would naively expect the two functions try_drain_*below to have the same behavior, but the first will not compile, and the second will execute without problems.

struct Container {
    map: RefCell<HashMap<i32, i32>>,
}

impl Container {
    fn try_drain_inline(&self) {
        self.map.borrow_mut().drain();
    }

    fn try_drain_broken_down(&self) {
        let mut guard = self.map.borrow_mut();
        guard.drain();
    }
}

The loan controller complains about try_drain_inline on the playground :

error[E0597]: borrowed value does not live long enough
  --> src/main.rs:15:5
   |
14 |         self.map.borrow_mut().drain();
   |         ---------------------        ^ temporary value dropped here while still borrowed
   |         |
   |         temporary value created here
   |
   = note: values in a scope are dropped in the opposite order they are created

whereas with try_drain_broken_downthis is normal.

There seems to be a problem with the order in which the created temporary files are destroyed; and "manually", materializing the time frame, corrects the situation ...

Why did the borrowing controller reject the inline form and take the broken one?


Note: my real code is a function try_popthat requires TWO intermediate variables:

fn try_pop(&self) -> Option<i32> {
    let mut guard = self.map.borrow_mut();
    let mut drain = guard.drain();
    drain.next().map(|(_, t)| t)
}
+4
1

:

fn try_drain_inline_broken_down(&self) {
    {   // Implicit block around the whole expression
        let mut guard = self.map.borrow_mut();
        guard.drain()    // No semicolon here
    };                   // The semicolon is here
}

, , drain, , , guard, .

, drain, , guard , .

+2

Source: https://habr.com/ru/post/1682043/


All Articles