rust-lang / rust-lang/rust-clippy
Lint on Using `as_ptr()` or `as_ptr_mut()` on a MutexGuard if the Guard is Dropped After the Call
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Description
What it does
This lint warns you if you unlock a mutex after getting access to a pointer to the object inside, as in:
let my_pointer = mutex.lock().unwrap().as_ptr();
or even more suspiciously:
let mut my_pointer = mutex.lock().unwrap().as_mut_ptr();
My suggestion is that doing this is a clear enough sign that you are planning to use that pointer soon in a way unguarded by the mutex that it warrants a lint.
Lint Name
Obtained Pointer to Contents of Unlocked Mutex?
Category
suspicious
Advantage
This bit me with this code:
pub fn get_frame(&self, frame:&mut [u8]) {
let source = self.front_buffer.lock().unwrap().as_ptr();
unsafe {
let destination = frame.as_mut_ptr();
ptr::copy_nonoverlapping(source, destination, frame.len());
}
}
If it had been a Clippy lint, I would have avoided this problem because I'm using real-time Clippy analysis through the CLion IDE.
Drawbacks
Calling as_ptr() or as_ptr_mut() is perfectly safe in isolation, so it might produce false positives in code that wants to do something that only involves the pointer addresses rather that the things they are pointing at.
It could also encourage in such cases for people to work around the lint by locking the mutex longer than necessary:
let my_pointer = mutex.lock().unwrap().as_ptr();`
// perfectly safe code
to:
let guard = mutex.lock().unwrap();`
let my_pointer = guard.as_ptr();
// perfectly safe code, but mutex is still locked and doesn't need to be
Example
pub fn get_frame(&self, frame:&mut [u8]) {
let source = self.front_buffer.lock().unwrap().as_ptr();
unsafe {
let destination = frame.as_mut_ptr();
ptr::copy_nonoverlapping(source, destination, frame.len());
}
}
Could be written as:
pub fn get_frame(&self, frame:&mut [u8]) {
let source = self.front_buffer.lock().unwrap();
unsafe {
let destination = frame.as_mut_ptr();
ptr::copy_nonoverlapping(source.as_ptr(), destination, frame.len());
}
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The issue names no implementation files or tests. Start by locating Clippy's lint entry points and existing mutex-related lint tests, then define the cases the lint should diagnose and the cases it should avoid. Done means the behavior is implemented with coverage for the shown pointer patterns and false-positive concerns.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100