Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clippy::mut_mutex_lock after an immutable reference is held #9854

Closed
Will-Low opened this issue Nov 15, 2022 · 2 comments · Fixed by #13122
Closed

clippy::mut_mutex_lock after an immutable reference is held #9854

Will-Low opened this issue Nov 15, 2022 · 2 comments · Fixed by #13122
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have

Comments

@Will-Low
Copy link

Summary

When an immutable reference is held, Clippy still suggests using get_mut() instead of lock() for Mutexes, even though this does not work, since it cannot borrow a mutable reference at the same time as an immutable reference.

Lint Name

mut_mutex_lock

Reproducer

I tried this code:

use std::sync::Mutex;
use std::thread;

fn main() {
    let val = Box::leak(Box::new(Mutex::new("my value".to_string())));
    new_thread(val);
    val.lock().unwrap().push('z');
}

fn new_thread(val: &'static Mutex<String>) {
    thread::spawn(move || loop {
        println!("{}", val.lock().unwrap());
    });
}

I saw this happen:

    Checking playground v0.0.1 (/playground)
warning: calling `&mut Mutex::lock` unnecessarily locks an exclusive (mutable) reference
 --> src/main.rs:7:9
  |
7 |     val.lock().unwrap().push('z');
  |         ^^^^ help: change this to: `get_mut`
  |
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#mut_mutex_lock
  = note: `#[warn(clippy::mut_mutex_lock)]` on by default

warning: `playground` (bin "playground") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.92s

When following Clippy's suggestion:

Checking playground v0.0.1 (/playground)
error[[E0502]](https://doc.rust-lang.org/stable/error-index.html#E0502): cannot borrow `*val` as mutable because it is also borrowed as immutable
 --> src/main.rs:7:5
  |
6 |     new_thread(val);
  |     ---------------
  |     |          |
  |     |          immutable borrow occurs here
  |     argument requires that `*val` is borrowed for `'static`
7 |     val.get_mut().unwrap().push('z');
  |     ^^^^^^^^^^^^^ mutable borrow occurs here

For more information about this error, try `rustc --explain E0502`.
error: could not compile `playground` due to previous error

I expected to see this happen:
No lint suggested

Version

rustc 1.65.0 (897e37553 2022-11-02)
binary: rustc
commit-hash: 897e37553bba8b42751c67658967889d11ecd120
commit-date: 2022-11-02
host: aarch64-apple-darwin
release: 1.65.0
LLVM version: 15.0.0

Additional Labels

No response

@Will-Low Will-Low added C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have labels Nov 15, 2022
@hsghn
Copy link

hsghn commented Nov 15, 2022

Yes

@sgdxbc
Copy link

sgdxbc commented Feb 27, 2024

+1 when writing impl &'_ Mutex<T> {...} block

rshearman added a commit to rshearman/rust-clippy that referenced this issue Jul 18, 2024
When there is a pointer chain where one of the pointers isn't mutable
then this results in a false-positive for `mut_mutex_lock` as it only
checks the mutability of the first pointer level.

Fix this by using `peel_mid_ty_refs_is_mutable` which correctly
determines whether the pointer is ultimately mutable and thus whether
`Mutex::get_lock()` can actually be used.

Fixes rust-lang#9854
rshearman added a commit to rshearman/rust-clippy that referenced this issue Jul 18, 2024
When there is are multiple references where one of the references
isn't mutable then this results in a false-positive for
`mut_mutex_lock` as it only checks the mutability of the first
reference level.

Fix this by using `peel_mid_ty_refs_is_mutable` which correctly
determines whether the reference is ultimately mutable and thus
whether `Mutex::get_lock()` can actually be used.

Fixes rust-lang#9854
bors added a commit that referenced this issue Oct 1, 2024
Fix `mut_mutex_lock` when reference not ultimately mutable

When there is are multiple references where one of the references isn't mutable then this results in a false-positive for `mut_mutex_lock` as it only checks the mutability of the first reference level.

Fix this by using `peel_mid_ty_refs_is_mutable` which correctly determines whether the reference is ultimately mutable and thus whether `Mutex::get_lock()` can actually be used.

Fixes #9854

changelog: [`mut_mutex_lock`]: No longer lints if the mutex is behind multiple references and one of those references isn't mutable
@bors bors closed this as completed in c88cb08 Oct 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants