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

E0597: lock does not live long enough (surprising error, the message could be more helpful) #70844

Open
ghost opened this issue Apr 6, 2020 · 2 comments
Labels
A-borrow-checker Area: The borrow checker C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@ghost
Copy link

ghost commented Apr 6, 2020

I tried compiling this code:

fn main() {
    let lock = std::sync::Mutex::new(10);
    if let Ok(_) = lock.try_lock() {}
}

Error:

error[E0597]: `lock` does not live long enough
 --> src/main.rs:3:20
  |
3 |     if let Ok(_) = lock.try_lock() {}
  |                    ^^^^-----------
  |                    |
  |                    borrowed value does not live long enough
  |                    a temporary with access to the borrow is created here ...
4 | }
  | -
  | |
  | `lock` dropped here while still borrowed
  | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `std::result::Result<std::sync::MutexGuard<'_, i32>, std::sync::TryLockError<std::sync::MutexGuard<'_, i32>>>`
  |
  = note: The temporary is part of an expression at the end of a block. Consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped.

error: aborting due to previous error

For more information about this error, try `rustc --explain E0597`.
error: could not compile `tmp`.

To learn more, run the command again with --verbose.

I'm surprised that this does not compile!

The error message suggests adding a semicolon after the expression, but it's not obvious to me what exactly the expression is and where the semicolon should go. A suggestion on where to place the semicolon would be helpful.

The solution is this and compiles just fine:

fn main() {
    let lock = std::sync::Mutex::new(10);
    if let Ok(_) = lock.try_lock() {};
}
@ghost ghost added the C-bug Category: This is a bug. label Apr 6, 2020
@estebank estebank added A-borrow-checker Area: The borrow checker A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. D-papercut Diagnostics: An error or lint that needs small tweaks. labels Apr 6, 2020
@comex
Copy link
Contributor

comex commented Apr 8, 2020

This isn't just a diagnostic issue; the compiler should definitely accept the version without the semicolon.

@estebank estebank removed A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. D-papercut Diagnostics: An error or lint that needs small tweaks. labels Apr 16, 2020
@pnkfelix
Copy link
Member

cc #15023
cc #46413

estebank added a commit to estebank/rust that referenced this issue Apr 29, 2020
Address the diagnostics part of rust-lang#70844.

```
error[E0597]: `counter` does not live long enough
  --> $DIR/issue-54556-niconii.rs:22:20
   |
LL |     if let Ok(_) = counter.lock() { }
   |                    ^^^^^^^-------
   |                    |
   |                    borrowed value does not live long enough
   |                    a temporary with access to the borrow is created here ...
...
LL | }
   | -
   | |
   | `counter` dropped here while still borrowed
   | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `std::result::Result<MutexGuard<'_>, ()>`
   |
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
   |
LL |     if let Ok(_) = counter.lock() { };
   |                                      ^
```
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Apr 29, 2020
Suggest `;` or assignment to drop borrows in tail exprs

Address the diagnostics part of rust-lang#70844.

```
error[E0597]: `counter` does not live long enough
  --> $DIR/issue-54556-niconii.rs:22:20
   |
LL |     if let Ok(_) = counter.lock() { }
   |                    ^^^^^^^-------
   |                    |
   |                    borrowed value does not live long enough
   |                    a temporary with access to the borrow is created here ...
...
LL | }
   | -
   | |
   | `counter` dropped here while still borrowed
   | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `std::result::Result<MutexGuard<'_>, ()>`
   |
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
   |
LL |     if let Ok(_) = counter.lock() { };
   |                                      ^
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants