Missing Warning for Unneeded mut?

Just ran into this: why does neither rustc nor clippy warn me that I have an extra mut in there, that is not needed?

fn main() {
    let (mut tx, _) = std::sync::mpsc::channel();
    test_sender(&mut tx);
}

fn test_sender(tx: &mut std::sync::mpsc::Sender<u32>) {
    tx.send(32).unwrap();
}

The unused_mut lint only warns for bindings that are declared as mutable, but don't have to be. It does not warn for &mut T that could be &T.

1 Like

An unneeded mutable binding has no effect and can always be removed without thinking about it.

A mutable reference isn't quite the same. In addition to allowing for mutation, a mutable reference guarantees exclusive access. It could be that you want test_sender to ensure there are no other references to tx for whatever reason, even if you don't use the mutability aspect of &mut. In addition, changing a &mut T to &T in a function signature is a breaking change, meaning every user of the function would have to change every test_sender(&mut tx) to test_sender(&tx).
These are probably the main reasons there's no such lint (by default anyway, I don't know if an optional one exists or not).

5 Likes

Requiring &mut in function arguments may not be a mistake, even if mutability isn't directly used. &mut also ensures uniqueness, so for example you could want a guarantee that nobody can send anything on the same sender while you're using it.

1 Like