6

The following code does not compile (playground):

#![allow(unused)]
use std::cell::RefCell;

enum Token {
    A,
    B,
}

struct Thing {
    c: Token,
}

fn main() {
    let a = RefCell::new(Thing { c: Token::A });

    if let Token::A = a.borrow().c {
        //Error!
    }
}

It fails with this error:

error[E0597]: `a` does not live long enough
  --> src/main.rs:16:23
   |
16 |     if let Token::A = a.borrow().c {
   |                       ^ borrowed value does not live long enough
...
19 | }
   | - `a` dropped here while still borrowed
   |
   = note: values in a scope are dropped in the opposite order they are created

If I add anything after the statement, even a single ; then it works fine:

if let Token::A = a.borrow().c { 
};  // Ok

I assume that it is because the value of the if is used as the return of main, so the borrow in the if let is somehow extended. But that should not happen, it is just ()! Or is there something I'm not understanding?

BTW, the same thing happens with:

match a.borrow().c {
    _ => ()
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • 1
    I tried using `feature(nll)`, no cookie. Using `let b: () = a.borrow().c;`, the compiler wants `b` to be of type `Token` (NOT `&Token`). So we have a borrow with no outstanding reference somehow... oO – Matthieu M. Jul 05 '18 at 06:52
  • 1
    See also [Why does adding a semicolon to an if let avoid a borrow checker error?](https://stackoverflow.com/q/50066190/155423). – Shepmaster Jul 05 '18 at 12:12
  • 2
    Specifically, this code works with NLL *with* the experimental "polonius" implementation (`#![feature(nll)]` + `RUSTFLAGS='-Z polonius'`). – Shepmaster Jul 05 '18 at 12:14

0 Answers0