rust-lang / rust-lang/rust-clippy

Unnecessary use of `.ok()` followed by method equivalently defined on both `Option` and `Result`

Open
#8,994 2 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-lint
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

What it does

There is an existing lint, ok_expect, that warns against the following code:

res.ok().expect("msg")

saying that the .ok() can be removed and expect called directly. This can be generalized to other methods that can be called on both Option and Result.

The methods I could find that this could apply to include:

  • expect
  • unwrap, unwrap_or, unwrap_or_default, unwrap_unchecked
  • iter, iter_mut, into_iter
  • map_or

I'm sure I've missed some, please add any others that could be included!

The lazily evaluated _else methods could also be included with the minor modification of adding a ignored argument to the closure for the error, e.g. res.ok().unwrap_or_else(|| 4) becomes res.unwrap_or_else(|_| 4).

This could also be applied to calls to methods with multiple arguments if .ok() is called on both (e.g. .or(), .and(), .cmp()), though this is likely less common.

The reverse lint could also be implemented, e.g. unnecessary use of ok_or(_else) on an Option followed by a method above that will never construct the Err. The call to ok_or_else could have side effects, however, making the suggested code not equivalent.

Lint Name

unnecessary_ok

Category

complexity, perf

Advantage
  • Removes unnecessary code, improving clarity
  • Removes an unnecessary conversion (I don't know much about compiler internals---this may be a nonexistent performance change)
Drawbacks

Might not be a common enough pattern to be worth it. I've personally seen .ok().map_or.

The unwrap_* methods require that the Err variant implement Debug, which otherwise wouldn't be necessary.

Example
let value = <Result<_, i32>>::Ok(4);
value.ok().unwrap(); // or any of the above methods

Could be written as:

let value = <Result<_, i32>>::Ok(4);
value.unwrap();

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 examining the existing ok_expect lint and the Option and Result methods listed in the issue. Determine which conversions can be removed while preserving behavior, including the noted closure and Debug constraints. Done means defining the scope of unnecessary_ok and implementing consistent diagnostics for the supported cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
devtools
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.