Skip to content

mut-mut causes type error #15837

@matthiaskrgr

Description

@matthiaskrgr

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-suggestion-causes-errorIssue: The suggestions provided by this Lint cause an ICE/error when applied

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions