Skip to content

Commit

Permalink
docs: document PinnedDrop
Browse files Browse the repository at this point in the history
  • Loading branch information
jbr committed Mar 29, 2024
1 parent 1ec31c8 commit acdd245
Showing 1 changed file with 75 additions and 1 deletion.
76 changes: 75 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ impl<T, U> Struct<T, U> {
}
```
### Enums
To use [`pin_project!`] on enums, you need to name the projection type
returned from the method.
Expand Down Expand Up @@ -69,6 +71,30 @@ impl<T, U> Enum<T, U> {
}
```
### Pinned Drop
```rust
use pin_project_lite::pin_project;
pin_project! {
pub struct Struct<'a> {
was_dropped: &'a mut bool,
#[pin]
field: u8,
}
impl PinnedDrop for Struct<'_> {
fn drop(this: Pin<&mut Self>) { // <----- NOTE: this is not `self`
**this.project().was_dropped = true;
}
}
}
let mut was_dropped = false;
drop(Struct { was_dropped: &mut was_dropped, field: 42 });
assert!(was_dropped);
```
## [pin-project] vs pin-project-lite
Here are some similarities and differences compared to [pin-project].
Expand Down Expand Up @@ -100,7 +126,8 @@ description of the compile error.
### Different: No support for custom Unpin implementation
pin-project supports this by [`UnsafeUnpin`][unsafe-unpin]. (`!Unpin` is supported by both [pin-project][not-unpin] and [pin-project-lite][not-unpin-lite].)
pin-project supports this by [`UnsafeUnpin`][unsafe-unpin]. (`!Unpin` is supported by both
[pin-project][not-unpin] and [pin-project-lite][not-unpin-lite].)
### Different: No support for tuple structs and tuple variants
Expand Down Expand Up @@ -329,6 +356,53 @@ pin-project supports this.
/// Note that using [`PhantomPinned`] without `#[pin]` or `#[project(!Unpin)]`
/// attribute has no effect.
///
/// # Pinned Drop
///
/// In order to correctly implement pin projections, a type’s [`Drop`] impl must not move out of any
/// structurally pinned fields. Unfortunately, [`Drop::drop`] takes `&mut Self`, not `Pin<&mut
/// Self>`.
///
/// To implement [`Drop`] for type that has pin, add an `impl PinnedDrop` block at the end of the
/// [`pin_project`] macro block. PinnedDrop has the following interface:
///
/// ```rust
/// # use std::pin::Pin;
/// trait PinnedDrop {
/// fn drop(this: Pin<&mut Self>);
/// }
/// ```
///
/// Note that the argument to `PinnedDrop::drop` cannot be named `self`.
///
/// `pin_project_lite` implements the actual [`Drop`] trait via PinnedDrop you implemented. To
/// explicitly drop a type that implements PinnedDrop, use the [drop] function just like dropping a
/// type that directly implements [Drop].
///
/// `PinnedDrop::drop` will never be called more than once, just like [`Drop::drop`].
///
/// ```rust
/// use pin_project_lite::pin_project;
///
/// pin_project! {
/// pub struct Struct<'a> {
/// was_dropped: &'a mut bool,
/// #[pin]
/// field: u8,
/// }
///
/// impl PinnedDrop for Struct<'_> {
/// fn drop(this: Pin<&mut Self>) { // <----- NOTE: this is not `self`
/// **this.project().was_dropped = true;
/// }
/// }
/// }
///
/// let mut was_dropped = false;
/// drop(Struct { was_dropped: &mut was_dropped, field: 42 });
/// assert!(was_dropped);
/// ```
///
///
/// [`PhantomPinned`]: core::marker::PhantomPinned
/// [`Pin::as_mut`]: core::pin::Pin::as_mut
/// [`Pin`]: core::pin::Pin
Expand Down

0 comments on commit acdd245

Please sign in to comment.