rust-lang / rust-lang/rust-clippy

`mut-mut` causes type error

Open
#15,837 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug I-suggestion-causes-error
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

Using the following flags

--force-warn clippy::mut-mut

this code:

//@ edition:2021
//@ run-pass

// Test that we can mutate a place through a mut-borrow
// that is captured by the closure

// Check that we can mutate when one deref is required
fn mut_ref_1() {
    let mut x = String::new();
    let rx = &mut x;

    let mut c = || {
        *rx = String::new();
    };

    c();
}

// Similar example as mut_ref_1, we don't deref the imm-borrow here,
// and so we are allowed to mutate.
fn mut_ref_2() {
    let x = String::new();
    let y = String::new();
    let mut ref_x = &x;
    let m_ref_x = &mut ref_x;

    let mut c = || {
        *m_ref_x = &y;
    };

    c();
}

// Check that we can mutate when multiple derefs of mut-borrows are required to reach
// the target place.
// It works because all derefs are mutable, if either of them was an immutable
// borrow, then we would not be able to deref.
fn mut_mut_ref() {
    let mut x = String::new();
    let mut mref_x = &mut x;
    let m_mref_x = &mut mref_x;

    let mut c = || {
        **m_mref_x = String::new();
    };

    c();
}

fn main() {
    mut_ref_1();
    mut_ref_2();
    mut_mut_ref();
}

caused the following diagnostics:

    Checking _mut_ref v0.1.0 (/tmp/icemaker_global_tempdir.paNtiJF6jVLU/icemaker_clippyfix_tempdir.0ccTF3z2m3ib/_mut_ref)
warning: this expression mutably borrows a mutable reference
  --> src/main.rs:41:20
   |
41 |     let m_mref_x = &mut mref_x;
   |                    ^^^^^^^^^^^ help: reborrow instead: `&mut *mref_x`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#mut_mut
   = note: requested on the command line with `--force-warn clippy::mut-mut`

warning: `_mut_ref` (bin "_mut_ref") generated 1 warning
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.28s

However after applying these diagnostics, the resulting code:

//@ edition:2021
//@ run-pass

// Test that we can mutate a place through a mut-borrow
// that is captured by the closure

// Check that we can mutate when one deref is required
fn mut_ref_1() {
    let mut x = String::new();
    let rx = &mut x;

    let mut c = || {
        *rx = String::new();
    };

    c();
}

// Similar example as mut_ref_1, we don't deref the imm-borrow here,
// and so we are allowed to mutate.
fn mut_ref_2() {
    let x = String::new();
    let y = String::new();
    let mut ref_x = &x;
    let m_ref_x = &mut ref_x;

    let mut c = || {
        *m_ref_x = &y;
    };

    c();
}

// Check that we can mutate when multiple derefs of mut-borrows are required to reach
// the target place.
// It works because all derefs are mutable, if either of them was an immutable
// borrow, then we would not be able to deref.
fn mut_mut_ref() {
    let mut x = String::new();
    let mut mref_x = &mut x;
    let m_mref_x = &mut *mref_x;

    let mut c = || {
        **m_mref_x = String::new();
    };

    c();
}

fn main() {
    mut_ref_1();
    mut_ref_2();
    mut_mut_ref();
}

no longer compiled:

    Checking _mut_ref v0.1.0 (/tmp/icemaker_global_tempdir.paNtiJF6jVLU/icemaker_clippyfix_tempdir.0ccTF3z2m3ib/_mut_ref)
error[E0308]: mismatched types
  --> src/main.rs:44:22
   |
44 |         **m_mref_x = String::new();
   |         ----------   ^^^^^^^^^^^^^ expected `str`, found `String`
   |         |
   |         expected due to the type of this binding

error[E0277]: the size for values of type `str` cannot be known at compilation time
  --> src/main.rs:44:9
   |
44 |         **m_mref_x = String::new();
   |         ^^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `str`
   = note: the left-hand-side of an assignment must have a statically known size

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `_mut_ref` (bin "_mut_ref" test) due to 2 previous errors
warning: build failed, waiting for other jobs to finish...
error: could not compile `_mut_ref` (bin "_mut_ref") due to 2 previous errors

Version:

rustc 1.92.0-nightly (4a54b26d3 2025-10-07)
binary: rustc
commit-hash: 4a54b26d30dac43778afb0e503524b763fce0eee
commit-date: 2025-10-07
host: x86_64-unknown-linux-gnu
release: 1.92.0-nightly
LLVM version: 21.1.2

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 by reproducing the issue with the provided clippy::mut-mut example and compare the original code with the suggested reborrow. Trace the mut-mut lint implementation and its diagnostic suggestion logic. Done means the suggested rewrite preserves the original program's types and compilation behavior, with regression coverage for the nested mutable-reference case.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.