Skip to content

question_mark suggesting incorrect code when type is behind Deref (missing parentheses) #14615

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

Closed
SirMangler opened this issue Apr 15, 2025 · 1 comment · Fixed by #14655
Closed
Assignees
Labels
C-bug Category: Clippy is not doing the correct thing

Comments

@SirMangler
Copy link

SirMangler commented Apr 15, 2025

Summary

The question_mark lint suggests incorrect code when the return type is behind Deref. I first noticed this when using parking_lot::Mutex<Option<_>>::lock() which returns a MutexGuard<'_, RawMutex, Option<_>>. Specifically, it forgets to include the parentheses to dereference the type before applying the question mark operator.

Here is a minimal reproduction in rust playground:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=1d714214fc7983d0785b99ffd7d3eab4

Thanks!

Reproducer

I tried this code:

use parking_lot::Mutex;

fn main() {
    let a = Mutex::new(Some(0));
    println!("{:?}", format_a(a));
}

fn format_a(a: Mutex<Option<u32>>) -> Option<String> {
    let Some(a) = *a.lock() else {
        return None;
    };
    
    Some(format!("{}", a))
}

I expected to see this happen:

warning: this `let...else` may be rewritten with the `?` operator
  --> src/main.rs:9:5
   |
9  | /     let Some(a) = *a.lock() else {
10 | |         return None;
11 | |     };
   | |______^ help: replace it with: `let a = (*a.lock())?;`

Instead, this happened:

warning: this `let...else` may be rewritten with the `?` operator
  --> src/main.rs:9:5
   |
9  | /     let Some(a) = *a.lock() else {
10 | |         return None;
11 | |     };
   | |______^ help: replace it with: `let a = *a.lock()?;`
error[E0277]: the `?` operator can only be applied to values that implement `Try`
 --> src/main.rs:9:14
  |
9 |     let a = *a.lock()?;
  |              ^^^^^^^^^ the `?` operator cannot be applied to type `parking_lot::lock_api::MutexGuard<'_, parking_lot::RawMutex, Option<u32>>`
  |
  = help: the trait `Try` is not implemented for `parking_lot::lock_api::MutexGuard<'_, parking_lot::RawMutex, Option<u32>>`

Version

rustc 1.87.0-nightly (ce36a966c 2025-02-17)
binary: rustc
commit-hash: ce36a966c79e109dabeef7a47fe68e5294c6d71e
commit-date: 2025-02-17
host: x86_64-unknown-linux-gnu
release: 1.87.0-nightly
LLVM version: 20.1.0

Additional Labels

No response

@SirMangler SirMangler added the C-bug Category: Clippy is not doing the correct thing label Apr 15, 2025
@alex-semenyuk
Copy link
Member

@rustbot claim

github-merge-queue bot pushed a commit that referenced this issue Apr 22, 2025
…heses (#14655)

Close #14615

changelog: [`question_mark`]: when type is behind Deref include
parentheses
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants