-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
The transmute_ptr_to_ptr lint fires on transmute<T, U> when
both T and U are reference types. The docs say:
Why this is bad
Transmutes are dangerous, and these can instead be written as casts.
But this doesn’t explain anything. These casts are just as unsafe as the
transmute. In fact, transmute can be written in terms of such
casts:
pub unsafe fn transmute<T, U>(t: T) -> U {
std::ptr::read(&t as *const T as *const U)
}…so clearly they don’t bring any safety benefit.
I am aware that the docs for transmute itself also mention that you
can use as-casts in place of transmute. But those docs also
offer no explanation. They were added in rust-lang/rust#34609, where
@sfackler voiced the same concern but received no response.
(@sfackler also points out that transmute::<&T, &U> at least checks
statically that &T and &U have the same size, which pointer casts do
not. See size-checking example.)
Some veteran programmers on my team have suggested using transmute in
these cases for clarity, and I have to agree that it’s clearer:
unsafe { std::mem::transmute::<&str, &Tag>(s.as_ref()) }
// versus
unsafe { &*(s.as_ref() as *const str as *const Tag) }The former says what it’s doing right on the tin. In the latter, you
have to make sure that your &s and *s are all matching, and it’s
less self-documenting.
Does this lint exist for a reason other than safety theater or cargo
culting? If so, could you please add an explanation to the docs?