Skip to content

Misleading compiler suggestion: Add semicolon in rustlib due to missing ; in user code #139049

@jjl9807

Description

@jjl9807

Code

use std::fmt::{self, Display};

struct Mutex;

impl Mutex {
    fn lock(&self) -> MutexGuard {
        MutexGuard(self)
    }
}

struct MutexGuard<'a>(&'a Mutex);

impl<'a> Drop for MutexGuard<'a> {
    fn drop(&mut self) {
    }
}

struct Out;

impl Out {
    fn write_fmt(&self, _args: fmt::Arguments) {}
}

impl<'a> Display for MutexGuard<'a> {
    fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
        Ok(())
    }
}

fn main() {
    let _write = {
        let mutex = Mutex;
        write!(Out, "{}", mutex.lock())
    };
}

Current output

error[E0597]: `mutex` does not live long enough
  --> .\test.rs:35:27
   |
34 |         let mutex = Mutex;
   |             ----- binding `mutex` declared here
35 |         write!(Out, "{}", mutex.lock())
   |                           ^^^^^-------
   |                           |
   |                           borrowed value does not live long enough
   |                           a temporary with access to the borrow is created here ...
36 |     };
   |     -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `MutexGuard`
   |     |
   |     `mutex` dropped here while still borrowed
   |
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
  --> C:\Users\jjl98\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\macros\mod.rs:650:55
   |
650|         $dst.write_fmt($crate::format_args!($($arg)*));
   |                                                       +

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0597`.

Desired output

error[E0597]: `mutex` does not live long enough
  --> .\test.rs:35:27
   |
34 |         let mutex = Mutex;
   |             ----- binding `mutex` declared here
35 |         write!(Out, "{}", mutex.lock())
   |                           ^^^^^-------
   |                           |
   |                           borrowed value does not live long enough
   |                           a temporary with access to the borrow is created here ...
36 |     };
   |     -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `MutexGuard`
   |     |
   |     `mutex` dropped here while still borrowed
   |
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
  --> .\test.rs:35:40
   |
35 |         write!(Out, "{}", mutex.lock());
   |                                        +

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0597`.

Rationale and extra context

No response

Other cases

Rust Version

rustc 1.85.1 (4eb161250 2025-03-15)
binary: rustc
commit-hash: 4eb161250e340c8f48f66e2b929ef4a5bed7c181
commit-date: 2025-03-15
host: x86_64-pc-windows-msvc
release: 1.85.1
LLVM version: 19.1.7

Anything else?

No response

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsA-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions