@@ -1080,9 +1080,8 @@ pub use self::unsafe_pinned::UnsafePinned;
10801080/// [subtle-details]: self#subtle-details-and-the-drop-guarantee "pin subtle details"
10811081/// [`unsafe`]: ../../std/keyword.unsafe.html "keyword unsafe"
10821082//
1083- // Note: the `Clone` derive below causes unsoundness as it's possible to implement
1084- // `Clone` for mutable references.
1085- // See <https://internals.rust-lang.org/t/unsoundness-in-pin/11311> for more details.
1083+ // Note: the `Clone` derive below is sound because either `Ptr: PinSafePointer`
1084+ // or the pointee is `Unpin`.
10861085#[ stable( feature = "pin" , since = "1.33.0" ) ]
10871086#[ lang = "pin" ]
10881087#[ fundamental]
@@ -1097,7 +1096,8 @@ pub struct Pin<Ptr> {
10971096// issues. `&self.pointer` should not be accessible to untrusted trait
10981097// implementations.
10991098//
1100- // See <https://internals.rust-lang.org/t/unsoundness-in-pin/11311/73> for more details.
1099+ // See <https://internals.rust-lang.org/t/unsoundness-in-pin/11311/73> and the
1100+ // `PinSafePointer` trait for more details.
11011101
11021102#[ stable( feature = "pin_trait_impls" , since = "1.41.0" ) ]
11031103impl < Ptr : Deref , Q : Deref > PartialEq < Pin < Q > > for Pin < Ptr >
@@ -1230,11 +1230,15 @@ impl<Ptr: Deref> Pin<Ptr> {
12301230 /// points to is pinned, that is a violation of the API contract and may lead to undefined
12311231 /// behavior in later (even safe) operations.
12321232 ///
1233- /// By using this method, you are also making a promise about the [`Deref`],
1234- /// [`DerefMut`], and [`Drop`] implementations of `Ptr`, if they exist. Most importantly, they
1235- /// must not move out of their `self` arguments: `Pin::as_mut` and `Pin::as_ref`
1236- /// will call `DerefMut::deref_mut` and `Deref::deref` *on the pointer type `Ptr`*
1237- /// and expect these methods to uphold the pinning invariants.
1233+ /// By using this method, you are also making a promise about several trait
1234+ /// implementations of `Ptr` itself, if they exist. Most importantly, they
1235+ /// must not move out of their `self` arguments: `Pin::as_mut` and
1236+ /// `Pin::as_ref` will call `DerefMut::deref_mut` and `Deref::deref` *on the
1237+ /// pointer type `Ptr`* and expect these methods to uphold the pinning
1238+ /// invariants. These requirements are specified in more detail on the
1239+ /// [`PinSafePointer`] trait, and `Ptr` must abide by the safety
1240+ /// requirements of that trait.
1241+ ///
12381242 /// Moreover, by calling this method you promise that the reference `Ptr`
12391243 /// dereferences to will not be moved out of again; in particular, it
12401244 /// must not be possible to obtain a `&mut Ptr::Target` and then
@@ -1690,7 +1694,7 @@ impl<Ptr: [const] Deref> const Deref for Pin<Ptr> {
16901694mod helper {
16911695 /// Helper that prevents downstream crates from implementing `DerefMut` for `Pin`.
16921696 ///
1693- /// The `Pin` type implements the unsafe trait `PinCoerceUnsized `, which essentially requires
1697+ /// The `Pin` type implements the unsafe trait `PinSafePointer `, which essentially requires
16941698 /// that the type does not have a malicious `Deref` or `DerefMut` impl. However, without this
16951699 /// helper module, downstream crates are able to write `impl DerefMut for Pin<LocalType>` as
16961700 /// long as it does not overlap with the impl provided by stdlib. This is because `Pin` is
@@ -1781,6 +1785,10 @@ unsafe impl<Ptr: DerefPure> DerefPure for Pin<Ptr> {}
17811785#[ unstable( feature = "legacy_receiver_trait" , issue = "none" ) ]
17821786impl < Ptr : LegacyReceiver > LegacyReceiver for Pin < Ptr > { }
17831787
1788+ // The following implementations allow untrusted trait implementations to access
1789+ // `&self.pointer`, which is only sound because these traits are mentioned in
1790+ // the safety requirements of `PinSafePointer`.
1791+
17841792#[ stable( feature = "pin" , since = "1.33.0" ) ]
17851793impl < Ptr : fmt:: Debug > fmt:: Debug for Pin < Ptr > {
17861794 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
@@ -1810,49 +1818,158 @@ impl<Ptr: fmt::Pointer> fmt::Pointer for Pin<Ptr> {
18101818#[ stable( feature = "pin" , since = "1.33.0" ) ]
18111819impl < Ptr , U > CoerceUnsized < Pin < U > > for Pin < Ptr >
18121820where
1813- Ptr : CoerceUnsized < U > + PinCoerceUnsized ,
1814- U : PinCoerceUnsized ,
1821+ Ptr : CoerceUnsized < U > + PinSafePointer ,
1822+ U : PinSafePointer ,
18151823{
18161824}
18171825
18181826#[ stable( feature = "pin" , since = "1.33.0" ) ]
18191827impl < Ptr , U > DispatchFromDyn < Pin < U > > for Pin < Ptr >
18201828where
1821- Ptr : DispatchFromDyn < U > + PinCoerceUnsized ,
1822- U : PinCoerceUnsized ,
1829+ Ptr : DispatchFromDyn < U > + PinSafePointer ,
1830+ U : PinSafePointer ,
18231831{
18241832}
18251833
18261834#[ unstable( feature = "pin_coerce_unsized_trait" , issue = "150112" ) ]
1827- /// Trait that indicates that this is a pointer or a wrapper for one, where
1828- /// unsizing can be performed on the pointee when it is pinned.
1835+ /// Trait that indicates that this is a pointer that does not misbehave when
1836+ /// combined with [`Pin`].
1837+ ///
1838+ /// Note that for backwards compatibility reasons, it is possible to create a
1839+ /// [`Pin<P>`] for pointer types `P` that do not implement this trait. However,
1840+ /// this can only be done safely if `<P as Deref>::Target` implements `Unpin`,
1841+ /// which means that pinning has no effect.
18291842///
18301843/// # Safety
18311844///
1832- /// Given a pointer of this type, the concrete type returned by its
1833- /// `deref` method and (if it implements `DerefMut`) its `deref_mut` method
1834- /// must be the same type and must not change without a modification.
1835- /// The following operations are not considered modifications:
1836- ///
1837- /// * Moving the pointer.
1838- /// * Performing unsizing coercions on the pointer.
1839- /// * Performing dynamic dispatch with the pointer.
1840- /// * Calling `deref` or `deref_mut` on the pointer.
1841- ///
1842- /// The concrete type of a trait object is the type that the vtable corresponds
1843- /// to. The concrete type of a slice is an array of the same element type and
1844- /// the length specified in the metadata. The concrete type of a sized type
1845- /// is the type itself.
1846- pub unsafe trait PinCoerceUnsized : Deref { }
1845+ /// Types that implement this trait must not provide "malicious" implementations
1846+ /// of any safe traits used by [`Pin`].
1847+ ///
1848+ /// ## The pointer must always reference the same object
1849+ ///
1850+ /// Calls to [`deref`]/[`deref_mut`] on the same `Pin<P>` instance must always
1851+ /// refer to the same object. That is, the address returned by these methods
1852+ /// must not change. This applies even if the pointer type is moved.
1853+ ///
1854+ /// Furthermore, if the pointer type can participate in unsizing coercions or
1855+ /// dynamic dispatch, then these coercions must also not change the underlying
1856+ /// concrete type. Here, the concrete type of a trait object is the type that
1857+ /// the vtable corresponds to. The concrete type of a slice is an array of the
1858+ /// same element type and the length specified in the metadata. The concrete
1859+ /// type of a sized type is the type itself.
1860+ ///
1861+ /// As an example, after unsizing coercing a pinned pointer, `deref_mut` must
1862+ /// not return a `#[repr(transparent)]` wrapper around the value it referenced
1863+ /// before being unsized, even if the address is unchanged.
1864+ ///
1865+ /// ## The pointer must not move its pointee
1866+ ///
1867+ /// The [`deref_mut`] method and the pointer type's destructor are called with a
1868+ /// `&mut self` receiver, but they must behave as-if it was a `self: Pin<&mut
1869+ /// Self>` receiver. That is, they must not move out of the underlying value.
1870+ ///
1871+ /// As an example, `deref_mut` must not invoke `swap` on the inner value.
1872+ ///
1873+ /// ## Shared access to the pointer
1874+ ///
1875+ /// If this pointer type uses `&P` references as evidence that this value is not
1876+ /// pinned, then it must not treat the `&self` argument passed to [`Clone`] or
1877+ /// the formatting traits ([`fmt::Debug`], [`fmt::Display`], [`fmt::Pointer`])
1878+ /// as such evidence.
1879+ ///
1880+ /// As an example, given a `Pin<Arc<T>>` there is no way to obtain an `&Arc<T>`
1881+ /// (note that `Deref` just gives a `&T`). Because of this, the [`Arc`] type can
1882+ /// assume that an `&Arc<T>` value can only exist if the `T` is not pinned,
1883+ /// which justifies the soundness of the [`Arc::get_mut`] method.
1884+ ///
1885+ /// ## Cloning pinned pointers
1886+ ///
1887+ /// When a [`Pin<P>`] is cloned, the `P` pointer value returned by `clone` is
1888+ /// passed to [`Pin::new_unchecked`]. The implementation of [`Clone`] must
1889+ /// return a value such that this is sound.
1890+ ///
1891+ /// For example, when a `Pin<&T>` is cloned, the resulting `&T` points at the
1892+ /// same value. The value is known to be pinned since a `Pin<&T>` to it exists,
1893+ /// so it is safe to wrap the `&T` returned by `clone` in `Pin`.
1894+ ///
1895+ /// [`deref`]: Deref::deref
1896+ /// [`deref_mut`]: DerefMut::deref_mut
1897+ /// [`clone`]: Clone::clone
1898+ /// [`Arc`]: ../../std/sync/struct.Arc.html "Arc"
1899+ /// [`Arc::get_mut`]: ../../std/sync/struct.Arc.html#method.get_mut "Arc::get_mut"
1900+ pub unsafe trait PinSafePointer : Deref + Sized { }
18471901
1902+ // A pointer can only be pin safe if it does not implement certain safe traits
1903+ // maliciously. Since `&T` is fundamental, downstream crates may be able to
1904+ // implement those traits for `&LocalType`, so we must carefully check that
1905+ // this is not a problem for each trait.
1906+ //
1907+ // The `&T` type always implements [`Deref`] and [`Clone`], so despite being
1908+ // fundamental, downstream crates cannot implement these traits for
1909+ // `&LocalType`.
1910+ //
1911+ // The `&T` type has a negative blanket implementations for [`DerefMut`], so
1912+ // downstream crates cannot implement `DerefMut` for `&LocalType`.
1913+ //
1914+ // Conversely, downstream crates are able to implement `Clone`, `Debug`, and
1915+ // `Display` for `&LocalType` as long as `LocalType` does not implement said
1916+ // trait. However, the existence of an `&T` is not treated as evidence that the
1917+ // `T` is not pinned, so this is not problematic.
18481918#[ stable( feature = "pin" , since = "1.33.0" ) ]
1849- unsafe impl < ' a , T : ?Sized > PinCoerceUnsized for & ' a T { }
1919+ unsafe impl < ' a , T : ?Sized > PinSafePointer for & ' a T { }
18501920
1921+ // A pointer can only be pin safe if it does not implement certain safe traits
1922+ // maliciously. Since `&mut T` is fundamental, downstream crates may be able to
1923+ // implement those traits for `&mut LocalType`, so we must carefully check that
1924+ // this is not a problem for each trait.
1925+ //
1926+ // The `&mut T` type always implements [`Deref`] and [`DerefMut`], so despite
1927+ // being fundamental, downstream crates cannot implement these traits for `&mut
1928+ // LocalType`.
1929+ //
1930+ // The `&mut T` type has a negative blanket implementations for [`Clone`], so
1931+ // downstream crates cannot implement `Clone` for `&mut LocalType`.
1932+ //
1933+ // Conversely, downstream crates are able to implement `Debug` and `Display`
1934+ // for `&LocalType` as long as `LocalType` does not implement said trait.
1935+ // However, the existence of an `&T` is not treated as evidence that the `T` is
1936+ // not pinned, so this is not problematic.
18511937#[ stable( feature = "pin" , since = "1.33.0" ) ]
1852- unsafe impl < ' a , T : ?Sized > PinCoerceUnsized for & ' a mut T { }
1938+ unsafe impl < ' a , T : ?Sized > PinSafePointer for & ' a mut T { }
18531939
1940+ // A pointer can only be pin safe if it does not implement certain safe traits
1941+ // maliciously. `Pin` implements these traits by forwarding to `P`, which also
1942+ // asserts that these implementations are not malicious, so the implementations
1943+ // provided by `core` are ok. However, since `Pin<T>` is fundamental,
1944+ // downstream crates may be able to implement those traits for `Pin<LocalType>`
1945+ // directly, so we must carefully check that if a downstream crate can
1946+ // implement these traits for `Pin<LocalType>`, then this does not lead to any
1947+ // problems for the `Pin<Pin<LocalType>>` type.
1948+ //
1949+ // The `Pin<P>` type only implements `Deref` when `P: Deref`, so downstream
1950+ // crates can implement `Deref` for `Pin<LocalType>` in cases where `LocalType:
1951+ // !Deref`. However, as `Deref` is a super-trait for `PinSafePointer`, we do
1952+ // not assert that `Pin<P>` is pin safe in that scenario.
1953+ //
1954+ // The `Pin<P>` type only implements `DerefMut` when `P: DerefMut` and
1955+ // `P::Target: Unpin`, so normally downstream crates would be able to provide
1956+ // an implementation of `DerefMut` for `Pin<LocalType>` when `LocalType` does
1957+ // not satisfy those conditions. However, a special hack is used to prevent
1958+ // such downstream implementations, so this is not a problem. See
1959+ // [#145608](https://github.com/rust-lang/rust/pull/145608) for details.
1960+ //
1961+ // Conversely, downstream crates are able to implement `Clone`, `Debug` and
1962+ // `Display` for `Pin<LocalType>` as long as `LocalType` does not implement
1963+ // said trait. However, the existence of an `&Pin<P>` is not treated as
1964+ // evidence that the value is not pinned, so this is not problematic.
1965+ //
1966+ // Furthermore, in the case of `Clone`, cloning a `Pin<Pin<P>>` will utilize
1967+ // `Pin::new_unchecked` to convert from `Pin<P>` to `Pin<Pin<P>>`. However,
1968+ // given that the implementation of `Clone` returned a `Pin<P>`, we know that
1969+ // the target value is pinned, so this conversion is okay even if `Clone` was
1970+ // implemented for `Pin<P>` by a downstream crate.
18541971#[ stable( feature = "pin" , since = "1.33.0" ) ]
1855- unsafe impl < T : PinCoerceUnsized > PinCoerceUnsized for Pin < T > { }
1972+ unsafe impl < P : PinSafePointer > PinSafePointer for Pin < P > { }
18561973
18571974/// Constructs a <code>[Pin]<[&mut] T></code>, by pinning a `value: T` locally.
18581975///
0 commit comments