Skip to content

Commit ba3b934

Browse files
fu5haManishearth
authored andcommittedJan 7, 2024
Fix examples, finish polishing
1 parent 8241ca6 commit ba3b934

File tree

1 file changed

+87
-48
lines changed

1 file changed

+87
-48
lines changed
 

Diff for: ‎library/core/src/pin.rs

+87-48
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@
158158
//! [`Pin<Ptr>`]. [`Pin<Ptr>`] can wrap any pointer type, forming a promise that the **pointee**
159159
//! will not be *moved* or [otherwise invalidated][self#subtle-details].
160160
//!
161+
//! We call such a [`Pin`]-wrapped pointer a **pinning pointer,** (or pinning reference, or pinning
162+
//! `Box`, etc.) because its existince is the thing that is pinning the underlying pointee in place:
163+
//! it is the metaphorical "pin" securing the data in place on the pinboard (in memory).
164+
//!
161165
//! It is important to stress that the thing in the [`Pin`] is not the value which we want to pin
162166
//! itself, but rather a pointer to that value! A [`Pin<Ptr>`] does not pin the `Ptr` but rather
163167
//! the pointer's ***pointee** value*.
@@ -190,7 +194,7 @@
190194
//!
191195
//! [`Pin<Ptr>`] also uses the [`<Ptr as Deref>::Target`][Target] type information to modify the
192196
//! interface it is allowed to provide for interacting with that data (for example, when a
193-
//! [`Pin`]-wrapped pointer points at pinned data which implements [`Unpin`], as
197+
//! pinning pointer points at pinned data which implements [`Unpin`], as
194198
//! [discussed below][self#unpin]).
195199
//!
196200
//! [`Pin<Ptr>`] requires that implementations of [`Deref`] and [`DerefMut`] on `Ptr` return a
@@ -247,7 +251,7 @@
247251
//! // 1. Create the value, not yet in an address-sensitive state
248252
//! let tracker = AddrTracker::default();
249253
//!
250-
//! // 2. Pin the value by putting it behind a Pin-wrapped pointer, thus putting
254+
//! // 2. Pin the value by putting it behind a pinning pointer, thus putting
251255
//! // it into an address-sensitive state
252256
//! let mut ptr_to_pinned_tracker: Pin<&mut AddrTracker> = pin!(tracker);
253257
//! ptr_to_pinned_tracker.as_mut().check_for_move();
@@ -263,7 +267,7 @@
263267
//!
264268
//! Note that this invariant is enforced by simply making it impossible to call code that would
265269
//! perform a move on the pinned value. This is the case since the only way to access that pinned
266-
//! value is through the [`Pin`]-wrapped [`&mut T`], which in turn restricts our access.
270+
//! value is through the pinning <code>[Pin]<[&mut] T>></code>, which in turn restricts our access.
267271
//!
268272
//! ## [`Unpin`]
269273
//!
@@ -326,15 +330,16 @@
326330
//! impl Unmovable {
327331
//! /// Create a new `Unmovable`.
328332
//! ///
329-
//! /// To ensure the data doesn't move we place it on the heap behind a Pin-wrapped pointer.
330-
//! /// Note that the data is pinned, but the pointer to that data can itself still be moved,
331-
//! /// which is important because it means we can return the pointer from the function.
333+
//! /// To ensure the data doesn't move we place it on the heap behind a pinning Box.
334+
//! /// Note that the data is pinned, but the which is pinning it can itself still be moved.
335+
//! /// This is important because it means we can return the pointer from the function, which
336+
//! /// is itself a kind of move!
332337
//! fn new() -> Pin<Box<Self>> {
333338
//! let res = Unmovable {
334339
//! data: [0; 64],
335340
//! // We only create the pointer once the data is in place
336341
//! // otherwise it will have already moved before we even started.
337-
//! slice: NonNull::dangling(),
342+
//! slice: NonNull::from(&[]),
338343
//! _pin: PhantomPinned,
339344
//! };
340345
//! // First we put the data in a box, which will be its final resting place
@@ -344,14 +349,16 @@
344349
//! // From now on we need to make sure we don't move the boxed data.
345350
//! boxed.slice = NonNull::from(&boxed.data);
346351
//!
347-
//! // To do that, we pin the data in place by pointing to it with a Pin-wrapped pointer.
348-
//! // Box::into_pin wraps the existing Box pointer to the data in-place without moving,
349-
//! // so we can safely do this now after inserting the slice pointer above, but we have to
350-
//! // take care that we haven't performed any other semantic moves of `res` in between.
351-
//! let pinned = Box::into_pin(box);
352+
//! // To do that, we pin the data in place by pointing to it with a pinning
353+
//! // (`Pin`-wrapped) pointer.
354+
//! //
355+
//! // `Box::into_pin` makes existing `Box` pin the data in-place without moving it,
356+
//! // so we can safely do this now *after* inserting the slice pointer above, but we have
357+
//! // to take care that we haven't performed any other semantic moves of `res` in between.
358+
//! let pin = Box::into_pin(boxed);
352359
//!
353-
//! // Now we can return the pinned (through a Pin-wrapped box) data
354-
//! pinned
360+
//! // Now we can return the pinned (through a pinning Box) data
361+
//! pin
355362
//! }
356363
//! }
357364
//!
@@ -360,11 +367,11 @@
360367
//! // The inner pointee `Unmovable` struct will now never be allowed to move.
361368
//! // Meanwhile, we are free to move the pointer around.
362369
//! # #[allow(unused_mut)]
363-
//! let mut still_unmoved = unmoved;
370+
//! let mut still_unmoved = unmovable;
364371
//! assert_eq!(still_unmoved.slice, NonNull::from(&still_unmoved.data));
365372
//!
373+
//! // We cannot mutably dereference a `Pin<Ptr>` unless the pointee is `Unpin` or we use unsafe.
366374
//! // Since our type doesn't implement `Unpin`, this will fail to compile.
367-
//! // We cannot mutably dereference a `Pin` to `!Unpin` data (without using `unsafe`)
368375
//! // let mut new_unmoved = Unmovable::new();
369376
//! // std::mem::swap(&mut *still_unmoved, &mut *new_unmoved);
370377
//! ```
@@ -401,7 +408,7 @@
401408
//! of the pinned data to be valid, on top of the ones that must be upheld for a non-pinned value of
402409
//! the same type:
403410
//!
404-
//! From the moment a value is pinned by constructing a [`Pin`]-wrapped pointer to it, that value
411+
//! From the moment a value is pinned by constructing a [`Pin`]ning pointer to it, that value
405412
//! must *remain, **valid***, at that same address in memory, *until its [`drop`] handler is
406413
//! called.*
407414
//!
@@ -436,8 +443,8 @@
436443
//! said storage.
437444
//!
438445
//! However, reuse can happen even if no storage is (de-)allocated. For example, if we had an
439-
//! [`Option`] which contained a [`Some(v)`] where `v` is a pinned value, then `v` would be
440-
//! invalidated by setting that option to [`None`].
446+
//! [`Option`] which contained a `Some(v)` where `v` is a pinned value, then `v` would be
447+
//! invalidated by setting that option to `None`.
441448
//!
442449
//! Similarly, if a [`Vec`] was used to store pinned values and [`Vec::set_len`] is used to manually
443450
//! "kill" some elements of a vector, all value "killed" would become invalidated.
@@ -451,18 +458,23 @@
451458
//! # use std::mem::ManuallyDrop;
452459
//! # use std::pin::Pin;
453460
//! # struct Type;
454-
//! let mut pinned = Box::pin(ManuallyDrop::new(Type));
455-
//! let inner = unsafe {
456-
//! Pin::map_unchecked_mut(Pin::as_mut(&mut pinned), |x| &mut *x)
461+
//! // Pin something inside a `ManuallyDrop`. This is fine on its own.
462+
//! let mut pin: Pin<Box<ManuallyDrop<Type>>> = Box::pin(ManuallyDrop::new(Type));
463+
//!
464+
//! // However, creating a pinning mutable reference to the type *inside*
465+
//! // the `ManuallyDrop` is not!
466+
//! let inner: Pin<&mut Type> = unsafe {
467+
//! Pin::map_unchecked_mut(pin.as_mut(), |x| &mut **x)
457468
//! };
458469
//! ```
459470
//!
460-
//! Because [`mem::ManuallyDrop`] inhibits the destructor of `Type`, it won't get run, even though
461-
//! normally [`Box<T>`] drops the `T` before freeing the storage.
471+
//! Because [`mem::ManuallyDrop`] inhibits the destructor of `Type`, it won't get run when the
472+
//! <code>[Box]<[ManuallyDrop]\<Type>></code> is dropped, thus violating the drop guarantee of the
473+
//! <code>[Pin]<[&mut] Type>></code>.
462474
//!
463475
//! Of course, *leaking* memory in such a way that its underlying storage will never get invalidated
464476
//! or re-used is still fine: [`mem::forget`]ing a [`Box<T>`] prevents its storage from ever getting
465-
//! re-used, so the [`drop`] guarantee does not apply.
477+
//! re-used, so the [`drop`] guarantee is still satisfied.
466478
//!
467479
//! # Implementing an address-sensitive type.
468480
//!
@@ -478,12 +490,12 @@
478490
//! indeed in an address-sensitive state before [`drop`] was called, it is as if the compiler
479491
//! automatically called [`Pin::get_unchecked_mut`].
480492
//!
481-
//! This can never cause a problem in safe code because implementing a type which has an
482-
//! address-sensitive state which relies on pinning for validity (for example by
483-
//! implementing some operation on <code>[Pin]<[&]Self></code> or <code>[Pin]<[&mut] Self></code>
484-
//! which would be invalid if that `self` was not pinned) has consequences for your
493+
//! This can never cause a problem in purely safe code because creating a pinning pointer to
494+
//! a type which has an address-sensitive (thus does not implement `Unpin`) requires `unsafe`,
495+
//! but it is important to note that choosing to take advantage of pinning-related guarantees
496+
//! to justify validity in the implementation of your type has consequences for that type's
485497
//! [`Drop`][Drop] implementation as well: if an element of your type could have been pinned,
486-
//! you must treat [`Drop`][Drop] as implicitly taking <code>[Pin]<[&mut] Self></code>.
498+
//! you must treat [`Drop`][Drop] as implicitly taking <code>self: [Pin]<[&mut] Self></code>.
487499
//!
488500
//! You should implement [`Drop`] as follows:
489501
//!
@@ -511,6 +523,15 @@
511523
//! that for fields that happen to be sufficiently aligned. As a consequence, you cannot use
512524
//! pinning with a [`#[repr(packed)]`][packed] type.
513525
//!
526+
//! ### Implementing [`Drop`] for pointer types which will be used as [`Pin`]ning pointers
527+
//!
528+
//! It should further be noted that creating a pinning pointer of some type `Ptr` to some underlying
529+
//! `T` which is not `Unpin` *also* carries with it implications on the way that `Ptr` type must
530+
//! implement [`Drop`] (as well as [`Deref`] and [`DerefMut`])! When implementing a pointer type
531+
//! that may be used as a pinning pointer, you must also take the same care described above not to
532+
//! *move* out of or otherwise invalidate the pointee during [`Drop`], [`Deref`], or [`DerefMut`]
533+
//! implementations.
534+
//!
514535
//! ## "Assigning" pinned data
515536
//!
516537
//! Although in general it is not valid to swap data through a [`Pin<Ptr>`], or assign from
@@ -600,14 +621,14 @@
600621
//! ### Choosing pinning *not to be* structural for `field`...
601622
//!
602623
//! While counter-intuitive, it's actually the easier choice: if a
603-
//! <code>[Pin]<[`&mut Field`]></code> is never created, nothing can go wrong (well, so long as no
624+
//! <code>[Pin]<[&mut] Field></code> is never created, nothing can go wrong (well, so long as no
604625
//! unsound `unsafe` code is written which expects the invariants of such a [`Pin`] to be upheld
605626
//! without actually using pinning to guarantee them)! So, if you decide that some field does not
606-
//! have structural pinning, all you have to ensure is that you never create [`Pin`]-wrapped
627+
//! have structural pinning, all you have to ensure is that you never create pinning
607628
//! reference to that field.
608629
//!
609630
//! Fields without structural pinning may have a projection method that turns
610-
//! <code>[Pin]<[&mut Struct][&mut]></code> into [`&mut Field`]:
631+
//! <code>[Pin]<[&mut] Struct></code> into [`&mut Field`]:
611632
//!
612633
//! ```rust,no_run
613634
//! # use std::pin::Pin;
@@ -706,7 +727,7 @@
706727
//!
707728
//! For a type like [`Vec<T>`], both possibilities (structural pinning or not) make
708729
//! sense. A [`Vec<T>`] with structural pinning could have `get_pin`/`get_pin_mut`
709-
//! methods to get [`Pin`]-wrapped references to elements. However, it could *not* allow calling
730+
//! methods to get pinning references to elements. However, it could *not* allow calling
710731
//! [`pop`][Vec::pop] on a pinned [`Vec<T>`] because that would move the (structurally
711732
//! pinned) contents! Nor could it allow [`push`][Vec::push], which might reallocate and thus also
712733
//! move the contents.
@@ -728,8 +749,8 @@
728749
//! pointer is pinned, meaning pinning is *not* structural.
729750
//!
730751
//! When implementing a [`Future`] combinator, you will usually need structural pinning
731-
//! for the nested futures, as you need to get [`Pin`]-wrapped references to them to call [`poll`].
732-
//! But if your combinator contains any other data that does not need to be pinned,
752+
//! for the nested futures, as you need to get pinning ([`Pin`]-wrapped) references to them to
753+
//! call [`poll`]. But if your combinator contains any other data that does not need to be pinned,
733754
//! you can make those fields not structural and hence freely access them with a
734755
//! mutable reference even when you just have <code>[Pin]<[`&mut Self`]></code>
735756
//! (such as in your own [`poll`] implementation).
@@ -744,6 +765,7 @@
744765
//! [`DerefMut`]: crate::ops::DerefMut "ops::DerefMut"
745766
//! [`mem::swap`]: crate::mem::swap "mem::swap"
746767
//! [`mem::forget`]: crate::mem::forget "mem::forget"
768+
//! [ManuallyDrop]: crate::mem::ManuallyDrop "ManuallyDrop"
747769
//! [RefCell]: crate::cell::RefCell "cell::RefCell"
748770
//! [`drop`]: Drop::drop
749771
//! [`ptr::write`]: crate::ptr::write "ptr::write"
@@ -785,17 +807,32 @@ use crate::{
785807
mem, ptr,
786808
};
787809

788-
/// A pointer to a pinned value.
810+
/// A pointer which pins its pointee in place.
811+
///
812+
/// [`Pin`] is a wrapper around some kind of pointer `Ptr` which makes that pointer "pin" its
813+
/// pointee value in place, thus preventing the value referenced by that pointer from being moved or
814+
/// otherwise invalidated at that place in memory unless it implements [`Unpin`].
789815
///
790-
/// This is a wrapper around any kind of pointer `P` which makes that pointer "pin" its pointee
791-
/// value in place, thus preventing the value referenced by that pointer from being moved or
792-
/// otherwise invalidated unless it implements [`Unpin`].
816+
/// ## Pinning values with [`Pin<Ptr>`]
817+
///
818+
/// In order to pin a value, we wrap a *pointer to that value* (of some type `Ptr`) in a
819+
/// [`Pin<Ptr>`]. [`Pin<Ptr>`] can wrap any pointer type, forming a promise that the **pointee**
820+
/// will not be *moved* or [otherwise invalidated][self#subtle-details].
821+
///
822+
/// We call such a [`Pin`]-wrapped pointer a **pinning pointer,** (or pinning ref, or pinning
823+
/// [`Box`], etc.) because its existince is the thing that is pinning the underlying pointee in
824+
/// place: it is the metaphorical "pin" securing the data in place on the pinboard (in memory).
825+
///
826+
/// It is important to stress that the thing in the [`Pin`] is not the value which we want to pin
827+
/// itself, but rather a pointer to that value! A [`Pin<Ptr>`] does not pin the `Ptr` but rather
828+
/// the pointer's ***pointee** value*.
793829
///
794830
/// `Pin<P>` is guaranteed to have the same memory layout and ABI as `P`.
795831
///
796-
/// *See the [`pin` module] documentation for an overview and explanation of pinning.*
832+
/// *See the [`pin` module] documentation for a more thorough exploration of pinning.*
797833
///
798834
/// [`pin` module]: self
835+
/// [`Box`]: ../../std/boxed/struct.Box.html
799836
//
800837
// Note: the `Clone` derive below causes unsoundness as it's possible to implement
801838
// `Clone` for mutable references.
@@ -982,12 +1019,14 @@ impl<P: Deref> Pin<P> {
9821019
/// use std::pin::Pin;
9831020
///
9841021
/// fn move_pinned_rc<T>(mut x: Rc<T>) {
985-
/// let pinned = unsafe { Pin::new_unchecked(Rc::clone(&x)) };
1022+
/// // This should mean the pointee can never move again.
1023+
/// let pin = unsafe { Pin::new_unchecked(Rc::clone(&x)) };
9861024
/// {
987-
/// let p: Pin<&T> = pinned.as_ref();
988-
/// // This should mean the pointee can never move again.
1025+
/// let p: Pin<&T> = pin.as_ref();
1026+
/// // ...
9891027
/// }
990-
/// drop(pinned);
1028+
/// drop(pin);
1029+
9911030
/// let content = Rc::get_mut(&mut x).unwrap(); // Potential UB down the road ⚠️
9921031
/// // Now, if `x` was the only reference, we have a mutable reference to
9931032
/// // data that we pinned above, which we could use to move it as we have
@@ -1101,7 +1140,7 @@ impl<P: DerefMut> Pin<P> {
11011140
/// ruled out by the contract of `Pin::new_unchecked`.
11021141
///
11031142
/// This method is useful when doing multiple calls to functions that consume the
1104-
/// [`Pin`]-wrapped pointer.
1143+
/// pinning pointer.
11051144
///
11061145
/// # Example
11071146
///
@@ -1293,7 +1332,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
12931332
}
12941333

12951334
impl<T: ?Sized> Pin<&'static T> {
1296-
/// Get a `Pin`-wrapped reference from a `&'static` reference.
1335+
/// Get a pinning reference from a `&'static` reference.
12971336
///
12981337
/// This is safe because `T` is borrowed immutably for the `'static` lifetime, which
12991338
/// never ends.
@@ -1346,7 +1385,7 @@ impl<'a, P: DerefMut> Pin<&'a mut Pin<P>> {
13461385
}
13471386

13481387
impl<T: ?Sized> Pin<&'static mut T> {
1349-
/// Get a `Pin`-wrapped mutable reference from a static mutable reference.
1388+
/// Get a pinning mutable reference from a static mutable reference.
13501389
///
13511390
/// This is safe because `T` is borrowed for the `'static` lifetime, which
13521391
/// never ends.

0 commit comments

Comments
 (0)