rust-lang / rust-lang/rust-clippy
borrow_as_ptr false positive on sequence of pointer casts
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Description
Summary
Clippy prefers that I make the following change:
- unsafe { &*(&**thing as *const T as *const U) }
+ unsafe { &*(ptr::addr_of!(**thing) as *const U) }
I consider this a false positive because the suggested code is only more brittle compared to the original code:
-
In the original code, it's clear without even showing the definition of
thingthat**thingis of typeT, as otherwise we could not cast from&Tto*const T. It's unlikely that you could have written too few or too many*and still get something that compiles, so this is "type safe". -
In the suggested code,
addr_of!will take whatever almost arbitrary place expression you give it and take its address, that then gets casted to*const U. If you got too many or too few*in there, this code will silently or not-so-silently or not-so-harmlessly do the wrong thing. If you got the right number of*today but tomorrowthingchanges type, that code becomes almost certainly wrong without any compile error.
This use case is minimized from real-world code in https://github.com/dtolnay/cargo-tally/blob/1.0.2/src/arena.rs#L81.
Lint Name
borrow_as_ptr
Reproducer
#![deny(clippy::pedantic)]
#![allow(clippy::cast_ptr_alignment, clippy::ptr_as_ptr)]
#[derive(Debug)]
#[repr(C)]
struct Thing { _i: i32 }
fn main() {
let thing = &Box::new(1i32);
let reference = unsafe { &*(&**thing as *const i32 as *const Thing) };
println!("{:?}", reference);
}
$ cargo clippy
error: borrow as raw pointer
--> src/main.rs:11:33
|
11 | let reference = unsafe { &*(&**thing as *const i32 as *const Thing) };
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of!(**thing)`
|
note: the lint level is defined here
--> src/main.rs:1:9
|
1 | #![deny(clippy::pedantic)]
| ^^^^^^^^^^^^^^^^
= note: `#[deny(clippy::borrow_as_ptr)]` implied by `#[deny(clippy::pedantic)]`
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr
Version
rustc 1.60.0-nightly (ad46af247 2022-01-14)
binary: rustc
commit-hash: ad46af24713115e7b9b258346e66b9b2d14eacfc
commit-date: 2022-01-14
host: x86_64-unknown-linux-gnu
release: 1.60.0-nightly
LLVM version: 13.0.0
Additional Labels
No response
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
Start with the borrow_as_ptr lint and the Rust reproducer in the issue, then run cargo clippy to confirm the current suggestion. Trace how the sequence of pointer casts is recognized and determine the expected behavior for this case; done means the false positive is handled without breaking the lint's existing checks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100