Skip to content

Commit 07ce0bd

Browse files
committed
improve Pin::new_unchecked docs
1 parent b0b3a28 commit 07ce0bd

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

library/core/src/pin.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,21 +1227,24 @@ impl<Ptr: Deref<Target: Unpin>> Pin<Ptr> {
12271227

12281228
impl<Ptr: Deref> Pin<Ptr> {
12291229
/// Construct a new `Pin<Ptr>` around a reference to some data of a type that
1230-
/// may or may not implement `Unpin`.
1230+
/// may or may not implement [`Unpin`].
12311231
///
1232-
/// If `pointer` dereferences to an `Unpin` type, `Pin::new` should be used
1232+
/// If `pointer` dereferences to an [`Unpin`] type, [`Pin::new`] should be used
12331233
/// instead.
12341234
///
12351235
/// # Safety
12361236
///
12371237
/// This constructor is unsafe because we cannot guarantee that the data
1238-
/// pointed to by `pointer` is pinned, meaning that the data will not be moved or
1239-
/// its storage invalidated until it gets dropped. If the constructed `Pin<Ptr>` does
1240-
/// not guarantee that the data `Ptr` points to is pinned, that is a violation of
1241-
/// the API contract and may lead to undefined behavior in later (safe) operations.
1238+
/// pointed to by `pointer` is pinned. At its core, pinning a value means making the
1239+
/// guarantee that the value's data will not be moved nor have its storage invalidated until
1240+
/// it gets dropped. For a more thorough explanation of pinning, see the [`pin` module docs].
12421241
///
1243-
/// By using this method, you are making a promise about the `Ptr::Deref` and
1244-
/// `Ptr::DerefMut` implementations, if they exist. Most importantly, they
1242+
/// If the caller that is constructing this `Pin<Ptr>` does not ensure that the data `Ptr`
1243+
/// points to is pinned, that is a violation of the API contract and may lead to undefined
1244+
/// behavior in later (even safe) operations.
1245+
///
1246+
/// By using this method, you are also making a promise about the [`Deref`] and
1247+
/// [`DerefMut`] implementations of `Ptr`, if they exist. Most importantly, they
12451248
/// must not move out of their `self` arguments: `Pin::as_mut` and `Pin::as_ref`
12461249
/// will call `DerefMut::deref_mut` and `Deref::deref` *on the pointer type `Ptr`*
12471250
/// and expect these methods to uphold the pinning invariants.
@@ -1252,7 +1255,9 @@ impl<Ptr: Deref> Pin<Ptr> {
12521255
///
12531256
/// For example, calling `Pin::new_unchecked` on an `&'a mut T` is unsafe because
12541257
/// while you are able to pin it for the given lifetime `'a`, you have no control
1255-
/// over whether it is kept pinned once `'a` ends:
1258+
/// over whether it is kept pinned once `'a` ends, and therefore cannot uphold the
1259+
/// guarantee that a value, once pinned, remains pinned until it is dropped:
1260+
///
12561261
/// ```
12571262
/// use std::mem;
12581263
/// use std::pin::Pin;
@@ -1286,7 +1291,7 @@ impl<Ptr: Deref> Pin<Ptr> {
12861291
/// // ...
12871292
/// }
12881293
/// drop(pin);
1289-
1294+
///
12901295
/// let content = Rc::get_mut(&mut x).unwrap(); // Potential UB down the road ⚠️
12911296
/// // Now, if `x` was the only reference, we have a mutable reference to
12921297
/// // data that we pinned above, which we could use to move it as we have
@@ -1347,6 +1352,7 @@ impl<Ptr: Deref> Pin<Ptr> {
13471352
/// ```
13481353
///
13491354
/// [`mem::swap`]: crate::mem::swap
1355+
/// [`pin` module docs]: self
13501356
#[lang = "new_unchecked"]
13511357
#[inline(always)]
13521358
#[rustc_const_unstable(feature = "const_pin", issue = "76654")]

0 commit comments

Comments
 (0)