Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

if let in block expression position borrow check mismatch #41495

Closed
MBons opened this issue Apr 24, 2017 · 2 comments
Closed

if let in block expression position borrow check mismatch #41495

MBons opened this issue Apr 24, 2017 · 2 comments

Comments

@MBons
Copy link

MBons commented Apr 24, 2017

I've ran into a borrowing issue using try_borrow() in an if let statement.

The problem occurs when it's the last expression of the scope and is resolved by making it a statement.
I'm not sure if this is a bug or limitation in the borrow checker, but either way the error message is confusing.

rust play link

fn does_not_compile() {
    let container = RefCell::new(0);
    if let Ok(_) = container.try_borrow() { }
}

fn compiles() {
    let container = RefCell::new(0);
    if let Ok(_) = container.try_borrow() { };
}

rustc 1.16.0 (30cf806 2017-03-10)
error: container does not live long enough
--> :6:1
|
5 | if let Ok(_) = container.try_borrow() { }
| --------- borrow occurs here
6 | }
| ^ container dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created

error: aborting due to previous error

@Havvy
Copy link
Contributor

Havvy commented Apr 24, 2017

My own findings show that this does not happen with if, only with if let.

Playpen

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

fn passes_compile() {
    let container = RefCell::new(0);
    if container.try_borrow().is_ok() { }
}

fn fails_compile_if_let_true() {
    let container = RefCell::new(0);
    if let true = container.try_borrow().is_ok() { }
}

fn fails_compile_match() {
    let container = RefCell::new(0);
    match container.try_borrow().is_ok() {
        true => (),
        _ => ()
    }
}
rustc 1.16.0 (30cf806ef 2017-03-10)
error: `container` does not live long enough
  --> <anon>:12:1
   |
11 |     if let true = container.try_borrow().is_ok() { }
   |                   --------- borrow occurs here
12 | }
   | ^ `container` dropped here while still borrowed
   |
   = note: values in a scope are dropped in the opposite order they are created

error: `container` does not live long enough
  --> <anon>:20:1
   |
16 |     match container.try_borrow().is_ok() {
   |           --------- borrow occurs here
...
20 | }
   | ^ `container` dropped here while still borrowed
   |
   = note: values in a scope are dropped in the opposite order they are created

error: aborting due to 2 previous errors

Furthermore, the Rust reference says that An if let expression is semantically equivalent to an if expression, so the mismatch between the first and second functions in this comment has to be a bug.

@eddyb
Copy link
Member

eddyb commented Apr 25, 2017

Closing as duplicate of #21114 (comment). The reference is just wrong, only syntax is similar.

@eddyb eddyb closed this as completed Apr 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants