Skip to content
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

New Lint: Use question mark instead of Option::and_then #6436

Open
camsteffen opened this issue Dec 9, 2020 · 6 comments · May be fixed by #14051
Open

New Lint: Use question mark instead of Option::and_then #6436

camsteffen opened this issue Dec 9, 2020 · 6 comments · May be fixed by #14051
Assignees
Labels
A-lint Area: New lints good-first-issue These issues are a good way to get started with Clippy L-style Lint: Belongs in the style lint group T-middle Type: Probably requires verifiying types

Comments

@camsteffen
Copy link
Contributor

camsteffen commented Dec 9, 2020

What it does

Detect functions that end with Option::and_then or Result::and_then and suggest using a question mark instead.

Categories

  • Kind: style, maybe pedantic

It is simpler and more idiomatic.

Drawbacks

None.

Example

fn test(opt: Option<i32>) -> Option<i32> {
    opt.and_then(|n| {
        if n > 1 {
            Some(n + 1)
        } else {
            None
        }
    })
}

Could be written as:

fn test(opt: Option<i32>) -> Option<i32> {
    let n = opt?;
    if n > 1 {
        Some(n + 1)
    } else {
        None
    }
}

The and_then call should be the very last expression of the function (not inside an if block, for example).

More Questionable Cases

Single expression lambda (no block)

fn test(opt: Option<i32>) -> Option<i32> {
    opt.and_then(|n| foo(n))
}

At the end of a call chain

fn foo() -> Option<i32> {
    vec![1, 2, 3]
       .iter()
       .last()
       .and_then(|n| {
           // ...
       })
}

Personally I think those cases should still be linted. Maybe it can be configurable.

@camsteffen camsteffen added the A-lint Area: New lints label Dec 9, 2020
@camsteffen camsteffen added good-first-issue These issues are a good way to get started with Clippy L-style Lint: Belongs in the style lint group T-middle Type: Probably requires verifiying types labels Feb 7, 2021
@hristotanev
Copy link

hristotanev commented May 3, 2023

just checking if this is still good to be worked on? i am aware it has been a while since this was raised! if it is, i don't mind picking it up :)!

cc: @flip1995 @Manishearth @giraffate (sorry if i've overtagged someone)

@Manishearth
Copy link
Member

Manishearth commented May 3, 2023

Should be fine. We should figure out the name and the lint level but you can start work on it before we decide.

I'm open to the level being style or complexity as long as lintcheck isn't too noisy

@hristotanev
Copy link

hristotanev commented May 3, 2023

yeah, that sounds good. as you said, both of those things shouldn't require a lot of re-work if i start on this now. will get a bit familiarised with the tool and we can continue the discussion either here or when i raise the pr (about naming and lint level). thanks again :).

@hristotanev
Copy link

@rustbot claim

@sbdchd
Copy link

sbdchd commented Jan 4, 2025

I found myself rewriting:

let select = paren_select(p);
match select {
    Some(cm) => {
        if p.at_ts(COMPOUND_SELECT_FIRST) {
            opt_compound_select(p, cm)
        } else {
            Some(cm)
        }
    }
    None => None,
}

as

paren_select(p).and_then(|cm| {
    if p.at_ts(COMPOUND_SELECT_FIRST) {
        opt_compound_select(p, cm)
    } else {
        Some(cm)
    }
})

before switching to the question mark:

let cm = paren_select(p)?;
if p.at_ts(COMPOUND_SELECT_FIRST) {
    opt_compound_select(p, cm)
} else {
    Some(cm)
}

@aaron-ang
Copy link
Contributor

@rustbot claim

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: New lints good-first-issue These issues are a good way to get started with Clippy L-style Lint: Belongs in the style lint group T-middle Type: Probably requires verifiying types
Projects
None yet
5 participants