Rollup merge of #95547 - RalfJung:ptr-int-transmutes, r=scottmcm

caution against ptr-to-int transmutes

I don't know how strong of a statement we want to make here, but I am very concerned that the current docs could be interpreted as saying that ptr-to-int transmutes are just as okay as transmuting `*mut T` into an `&mut T`.

Examples [like this](https://github.com/rust-lang/unsafe-code-guidelines/issues/286#issuecomment-1085144431) show that ptr-to-int transmutes are deeply suspicious -- they are either UB, or they don't round-trip properly, or we have to basically say that `transmute` will actively look for pointers and do all the things a ptr-to-int cast does (which includes a global side-effect of marking the pointed-to allocation as 'exposed').

Another alternative might be to simply not talk about them... but we *do* want people to use casts rather than transmutes for this.

Cc `@rust-lang/lang`
This commit is contained in:
Dylan DPC 2022-04-05 22:58:56 +02:00 committed by GitHub
commit e597d06144
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -991,6 +991,16 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
/// let ptr_num_cast = ptr as *const i32 as usize;
/// ```
///
/// Note that using `transmute` to turn a pointer to a `usize` is (as noted above) [undefined
/// behavior][ub] in `const` contexts. Also outside of consts, this operation might not behave
/// as expected -- this is touching on many unspecified aspects of the Rust memory model.
/// Depending on what the code is doing, the following alternatives are preferrable to
/// pointer-to-integer transmutation:
/// - If the code just wants to store data of arbitrary type in some buffer and needs to pick a
/// type for that buffer, it can use [`MaybeUninit`][mem::MaybeUninit].
/// - If the code actually wants to work on the address the pointer points to, it can use `as`
/// casts or [`ptr.addr()`][pointer::addr].
///
/// Turning a `*mut T` into an `&mut T`:
///
/// ```