rust-lang / rust-lang/rust-clippy

`option_if_let_else` misses lint on `mut` version of function

Open
#8,967 1 comment 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug I-false-negative L-nursery
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

Summary

The nursery lint option_if_let_else will correctly catch a function working with Option<&T> but will not catch a nearly identical function working with Option<&mut T>.

Lint Name

option-if-let-else

Reproducer

I tried this code:

#![warn(clippy::option_if_let_else)]

pub struct HashStack {
    scope: Vec<i32>,
    parent: Option<Box<Self>>,
}

impl HashStack {
    pub fn lookup(&self, index: usize) -> Option<&i32> {
        if let Some(val) = self.scope.get(index) {
            Some(val)
        } else {
            self.parent.as_ref().and_then(|p| p.lookup(index))
        }
    }

    pub fn lookup_mut(&mut self, index: usize) -> Option<&mut i32> {
        if let Some(val) = self.scope.get_mut(index) {
            Some(val)
        } else {
            self.parent.as_mut().and_then(|p| p.lookup_mut(index))
        }
    }
}

The lint warns on the first method, and suggests this fix:

self.scope.get(index).map_or_else(
    || self.parent.as_ref().and_then(|p| p.lookup(index)),
    |val| Some(val),
)

However, it does not warn on the second method. I expected it to warn and suggest this similar fix:

self.scope.get_mut(index).map_or_else(
    || self.parent.as_mut().and_then(|p| p.lookup_mut(index)),
    |val| Some(val),
)
Version
rustc 1.61.0 (fe5b13d68 2022-05-18)
binary: rustc
commit-hash: fe5b13d681f25ee6474be29d748c65adcd91f69e
commit-date: 2022-05-18
host: x86_64-pc-windows-msvc
release: 1.61.0
LLVM version: 14.0.0

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 option-if-let-else lint implementation and its existing coverage for Option<&T>. Compare how the lint handles the Option<&mut T> reproducer, then add equivalent warning and suggestion behavior for lookup_mut. Done means the mutable example emits the lint and produces the shown map_or_else suggestion without regressing the existing case.

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.