Rollup merge of #156935 - Darksonn:pin-safe-pointer, r=Mark-Simulacrum Introduce a `PinSafePointer` trait that generalizes `PinCoerceUnsized` This PR renames `PinCoerceUnsized` to `PinSafePointer` and adds several new safety requirements about the implementations of various safe traits. Closes: #152667 Closes: #147794 ~~With this merged, the only remaining soundness issues with `Pin` are:~~ * #134407 * The fact that `CoercePointee` may be implemented on `Pin<LocalType>` in downstream crates. (unstable only) For your convenience here are the docs for the new trait: # `PinSafePointer` Trait that indicates that this is a pointer that does not misbehave when combined with `Pin`. Note that for backwards compatibility reasons, it is possible to create a `Pin<P>` for pointer types `P` that do not implement this trait. However, this can only be done safely if `<P as Deref>::Target` implements `Unpin`, which means that pinning has no effect. # Safety Types that implement this trait must not provide "malicious" implementations of any safe traits used by `Pin`. ## The pointer must always reference the same object Calls to [`deref`]/[`deref_mut`] on the same `Pin<P>` instance must always refer to the same object. That is, the address returned by these methods must not change. This applies even if the pointer type is moved. Furthermore, if the pointer type can participate in unsizing coercions or dynamic dispatch, then these coercions must also not change the underlying concrete type. Here, the concrete type of a trait object is the type that the vtable corresponds to. The concrete type of a slice is an array of the same element type and the length specified in the metadata. The concrete type of a sized type is the type itself. As an example, after unsizing coercing a pinned pointer, `deref_mut` must not return a `#[repr(transparent)]` wrapper around the value it referenced before being unsized, even if the address is unchanged. ## The pointer must not move its pointee The [`deref_mut`] method and the pointer type's destructor are called with a `&mut self` receiver, but they must behave as-if it was a `self: Pin<&mut Self>` receiver. That is, they must not move out of the underlying value. As an example, `deref_mut` must not invoke `swap` on the inner value. ## Shared access to the pointer If this pointer type uses `&P` references as evidence that this value is not pinned, then it must not treat the `&self` argument passed to [`Clone`] or the formatting traits (`fmt::Debug`, `fmt::Display`, `fmt::Pointer`) as such evidence. As an example, given a `Pin<Arc<T>>` there is no way to obtain an `&Arc<T>` (note that `Deref` just gives a `&T`). Because of this, the [`Arc`] type can assume that an `&Arc<T>` value can only exist if the `T` is not pinned, which justifies the soundness of the [`Arc::get_mut`] method. ## Cloning pinned pointers When a `Pin<P>` is cloned, the `P` pointer value returned by `clone` is passed to [`Pin::new_unchecked`]. The implementation of [`Clone`] must return a value such that this is sound. For example, when a `Pin<&T>` is cloned, the resulting `&T` points at the same value. The value is known to be pinned since a `Pin<&T>` to it exists, so it is safe to wrap the `&T` returned by `clone` in `Pin`. [`deref`]: https://doc.rust-lang.org/stable/core/ops/trait.Deref.html#tymethod.deref [`deref_mut`]: https://doc.rust-lang.org/stable/core/ops/trait.DerefMut.html#tymethod.deref_mut [`clone`]: https://doc.rust-lang.org/stable/core/clone/trait.Clone.html#tymethod.clone [`Clone`]: https://doc.rust-lang.org/stable/core/clone/trait.Clone.html [`Arc`]: https://doc.rust-lang.org/stable/std/sync/struct.Arc.html [`Arc::get_mut`]: https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.get_mut [`Pin::new_unchecked`]: https://doc.rust-lang.org/stable/std/pin/struct.Pin.html#method.new_unchecked r? lcnr