Skip to content

clippy::only_used_in_recursion considers self, but unused_variables does not #10370

Open
@PatchMixolydic

Description

@PatchMixolydic

Summary

clippy::only_used_in_recursion can trip on self in methods. While this is technically correct, it is inconsistent with rustc's unused_variables lint.

Lint Name

clippy::only_used_in_recursion

Reproducer

I tried this code (playground):

pub enum Expression {
    Path(usize),
    Loop(Option<Box<Expression>>),
    FnCall(Box<Expression>, Vec<Box<Expression>>),
}

impl Expression {
    pub fn is_intrinsic(&self) -> bool {
        todo!()
    }
}

pub struct LowerState;

impl LowerState {
    fn find_id(&self, expr: &Expression) -> Option<usize> {
        match expr {
            Expression::Path(id) => Some(*id),
            Expression::FnCall(_, _) => None,
            Expression::Loop(body) => body.as_ref().and_then(|expr| self.find_id(expr)),
        }
    }

    pub fn lower_expression(&self, expr: Expression) {
        match &expr {
            Expression::Loop(_) => todo!(),
            Expression::Path(_) => todo!(),

            Expression::FnCall(f, _args) => {
                if expr.is_intrinsic() {
                    let _id = self.find_id(f);
                    todo!()
                }

                todo!()
            }
        }
    }
}

I saw this happen:

warning: parameter is only used in recursion
  --> src/lib.rs:16:17
   |
16 |     fn find_id(&self, expr: &Expression) -> Option<usize> {
   |                 ^^^^
   |
note: parameter used here
  --> src/lib.rs:20:69
   |
20 |             Expression::Loop(body) => body.as_ref().and_then(|expr| self.find_id(expr)),
   |                                                                     ^^^^
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#only_used_in_recursion
   = note: `#[warn(clippy::only_used_in_recursion)]` on by default

I expected to see this happen: No warnings

Note that if the body of LowerState::find_id is replaced with todo!(), self is not marked as unused (playground):

// ...

impl LowerState {
    fn find_id(&self, expr: &Expression) -> Option<usize> {
        todo!()
    }

    // ...
}
warning: unused variable: `expr`
  --> src/lib.rs:16:23
   |
16 |     fn find_id(&self, expr: &Expression) -> Option<usize> {
   |                       ^^^^ help: if this is intentional, prefix it with an underscore: `_expr`
   |
   = note: `#[warn(unused_variables)]` on by default

Version

rustc 1.69.0-nightly (0416b1a6f 2023-02-14)
binary: rustc
commit-hash: 0416b1a6f6d5c42696494e1a3a33580fd3f669d8
commit-date: 2023-02-14
host: x86_64-unknown-linux-gnu
release: 1.69.0-nightly
LLVM version: 15.0.7

Additional Labels

No response

Metadata

Metadata

Assignees

Labels

C-bugCategory: Clippy is not doing the correct thingI-false-positiveIssue: The lint was triggered on code it shouldn't have

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions