rust-lang / rust-lang/rust

Consuming a value with a destructuring pattern doesn't end its borrows for drop-check.

Open
#145,032 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-borrow-checker A-destructors A-patterns C-bug T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I tried this code:

struct Fork<'a>(&'a mut i32);

impl Drop for Fork<'_> {
    fn drop(&mut self) {}
}

fn parse(mut input: i32) {
    if let Some(fork) = Some(Fork(&mut input)) {
        drop(fork);
        let _x = input;
    }
}

I expected the code to compile, but I got the following error:

error[E0503]: cannot use `input` because it was mutably borrowed
  --> src/lib.rs:10:18
   |
 8 |     if let Some(fork) = Some(Fork(&mut input)) {
   |                         ----------------------
   |                         |         |
   |                         |         `input` is borrowed here
   |                         a temporary with access to the borrow is created here ...
 9 |         drop(fork);
10 |         let _x = input;
   |                  ^^^^^ use of borrowed `input`
11 |     };
   |     - ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Option<Fork<'_>>`

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

I also tried using match instead of if let:

struct Fork<'a>(&'a mut i32);

impl Drop for Fork<'_> {
    fn drop(&mut self) {}
}

fn parse(mut input: i32) {
    match Some(Fork(&mut input)) {
        Some(fork) => {
            drop(fork);
            let _x = input;
        }
        _ => {}
    }
}

I got this error:

error[E0503]: cannot use `input` because it was mutably borrowed
  --> src/lib.rs:11:22
   |
 8 |     match Some(Fork(&mut input)) {
   |           ----------------------
   |           |         |
   |           |         `input` is borrowed here
   |           a temporary with access to the borrow is created here ...
...
11 |             let _x = input;
   |                      ^^^^^ use of borrowed `input`
...
14 |     }
   |     - ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Option<Fork<'_>>`
   |
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
   |
14 |     };
   |      +

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

In either case, adding the semicolon, as indicated in the error, doesn't fix the error.

Minimized from real code by @spikespaz in the community discord.

Meta

Reproducible on the playground with version 1.91.0-nightly (2025-08-05 ec7c02612527d185c379)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing both examples with rustc 1.91.0-nightly (2025-08-05 ec7c02612527d185c379) and compare the diagnostics with the reported output. Investigate the compiler's borrow-checking and drop-check handling for destructuring patterns and their temporary Option values. Done means the intended borrow ends after drop(fork), or the issue is resolved with a documented, correct diagnostic.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.