Skip to content

Lint function inputs being shadowed with a mutable variable #17868

Open

Description

@orowith2os

What it does

If a variable is taken as input immutably, and then shadowed with let mut, suggest binding in the function arguments with mut instead.

Advantage

Cleanliness, mostly.

Drawbacks

N/A?

Example

fn mut_shadow(x: u32) -> u32 {
    let mut x = x;
    x++;
    return x;
}

Could be written as:

fn mut_shadow(mut x: u32) -> u32 {
    x += 1;
    return x;
}

Comparison with existing lints

Semi related to #11704, but for function arguments. Roll both into one issue?

Additional Context

An argument being taken in that's Copy or Clone doesn't need to really worry about messing with the caller, since the variable either copied or moved into the function's scope and the caller doesn't have to worry about it from that point on.

Activity

  1. mi2ebi commented on Oct 12, 2026

    @mi2ebi

    what if you really don't want to mutate x? that's true more often for me at least

  2. Fulgen301 commented on Oct 12, 2026

    @Fulgen301

    I'm not convinced this adds cleanliness in all cases. Even ignoring misunderstandings what a mutable parameter means, like the referenced PR originally had, there are reasons why keeping mut out of the function header might be preferred:

    • The function header might be very long (long types, many parameters while staying under the limit clippy would lint against anyway), where mut would add more noise that would get lost.
    • If the function implements a trait method, adding mut would add differences to the original signature.
    • The intent of a mutable parameter may not be as obvious to code reviewers as an explicit let mut x = x; binding in the body - the linked PR originally had a comment explaining the meaning of mut by that parameter; while the explanation was incorrect, it serves as an indicator that the intent may not be clear enough to lint against, at least by default.
  3. orowith2os commented on Oct 12, 2026

    @orowith2os
    Author

    what if you really don't want to mutate x? that's true more often for me at least

    Then don't bind it as mut. let mut x = x; isn't the same as let x = &mut x, which isn't the same as let mut x = &mut x;, and I would expect somebody to know this when writing Rust. I don't see this as any different from using let.

  4. mi2ebi commented on Oct 12, 2026

    @mi2ebi

    should've clarified, i may want to not mutate the parameter x but still want to make a let mut x = x;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintArea: New lints

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions