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?