rust-lang / rust-lang/rust-clippy

Inside try blocks, `if_then_some_else_none` triggers even if the `Some` branch contains `?`

Open
#17,596 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug I-false-positive I-suggestion-causes-error
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

Summary

Usually if_then_some_else_none does not trigger if the "then" branch producing a Some has control flow, but this seems to not work as expected with ? inside try blocks. I have not tried other control-flow operations like continue or break.

Lint Name

if_then_some_else_none

Reproducer

I tried this code (playground):

#![feature(try_blocks)]
#![deny(clippy::if_then_some_else_none)]

fn foo(x: u32) -> Option<Option<u32>> {
    try {
        if x > 0 {
            Some(x.checked_sub(2)?)
        } else {
            None
        }
    }
}

I saw this happen:

error: this could be simplified with `bool::then`
  --> src/main.rs:6:9
   |
 6 | /         if x > 0 {
 7 | |             Some(x.checked_sub(2)?)
 8 | |         } else {
 9 | |             None
10 | |         }
   | |_________^ help: try: `(x > 0).then(|| x.checked_sub(2)?)`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none
note: the lint level is defined here
  --> src/main.rs:2:9

If the suggested replacement is made then there is a compiler error about the closure not returning a Try type.

I expected to see this happen:
The lint should not trigger.

Version

Additional Labels

@rustbot label +I-suggestion-causes-error

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 at the if_then_some_else_none lint entry point and run the supplied try-block reproducer. Trace how the lint handles ? in the Some branch; done means it no longer emits the suggestion for this case and the suggested replacement does not produce the reported compiler error.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.