rust-lang / rust-lang/rust

false positive for `if-let-rescope` on enums when the pattern exhaustively matches all cases with significant-drop fields

Open
#137,376 4 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

A-diagnostics A-edition-2024 A-lints C-enhancement I-edition-triaged L-false-positive L-if_let_rescope T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Coming from https://github.com/rust-lang/rust/issues/133167#issuecomment-2672704736 and from this new forum thread, my takeaway of some remaining clear false positives is:

  • if the if let matches on an enum and only some enum variant(s) have fields with potentially-significant destructor, but those are exhaustively matched in the non-else case of the if let, then there can be no actual change in behavior, because the else case is only reached in case the drop is not significant

  • in the case of cargo-edit, this was if let Some(…irrefutable…) = expr on an Option<T>

  • in the urlo thread, I’ve identified the case of if let Err(…irrefutable…) on a Result<(), E>

Here’s a simple repro for an Option case:

Code
#![allow(unused)]
#![warn(if_let_rescope)]

struct Struct;
impl Drop for Struct {
    fn drop(&mut self) {}
}

fn f(option_s: Option<Struct>) {
    if let Some(s) = option_s {
        // …
    } else {
        // …
    }
}

Here’s the code in the playground.

Current output
warning: `if let` assigns a shorter lifetime since Edition 2024
  --> src/lib.rs:10:8
   |
10 |     if let Some(s) = option_s {
   |        ^^^^^^^^^^^^^^--------
   |                      |
   |                      this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
   |
   = warning: this changes meaning in Rust 2024
   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
help: the value is now dropped here in Edition 2024
  --> src/lib.rs:12:5
   |
12 |     } else {
   |     ^
note: the lint level is defined here
  --> src/lib.rs:2:9
   |
2  | #![warn(if_let_rescope)]
   |         ^^^^^^^^^^^^^^
help: a `match` with a single arm can preserve the drop order up to Edition 2021
   |
10 ~     match option_s { Some(s) => {
11 |         // …
12 ~     } _ => {
13 |         // …
14 ~     }}
   |

@rustbot label A-edition-2024, A-lints, L-if_let_rescope, C-enhancement

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 with the src/lib.rs reproduction and the if_let_rescope lint behavior described in the issue. Trace how exhaustive enum patterns are analyzed, then verify that the Option and Result cases no longer produce a warning while cases with a real drop-order change still do.

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
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.