RS.CLIPPY.ONLY_USED_IN_RECURSION

Arguments that is only used in recursion can be removed

This checker is a Clippy lint created by The Rust Project Contributors. The documentation shown here is a copy of the original documentation for: only_used_in_recursion. Copyright ©2025 The Rust Team. All rights reserved.

What it does

Checks for arguments that are only used in recursion with no side-effects.

Why is this bad?

It could contain a useless calculation and can make function simpler.

The arguments can be involved in calculations and assignments but as long as the calculations have no side-effects (function calls or mutating dereference) and the assigned variables are also only in recursion, it is useless.

Known problems

Too many code paths in the linting code are currently untested and prone to produce false positives or are prone to have performance implications.

In some cases, this would not catch all useless arguments.

fn foo(a: usize, b: usize) -> usize {
    let f = |x| x + 1;

    if a == 0 {
        1
    } else {
        foo(a - 1, f(b))
    }
}

For example, the argument b is only used in recursion, but the lint would not catch it.

List of some examples that can not be caught:

  • binary operation of non-primitive types
  • closure usage
  • some break relative operations
  • struct pattern binding

Also, when you recurse the function name with path segments, it is not possible to detect.

Example

fn f(a: usize, b: usize) -> usize {
    if a == 0 {
        1
    } else {
        f(a - 1, b + 1)
    }
}

Use instead:

fn f(a: usize) -> usize {
    if a == 0 {
        1
    } else {
        f(a - 1)
    }
}