[][src]Attribute Macro pin_project::pinned_drop

#[pinned_drop]

An attribute for annotating an impl block that implements [Drop].

This attribute is only needed when you wish to provide a [Drop] impl for your type.

This impl block acts just like a normal [Drop] impl, except for the following two:

pub trait PinnedDrop {
    fn drop(self: Pin<&mut Self>);
}

#[pin_project] implements the actual [Drop] trait via PinnedDrop you implemented. To drop a type that implements PinnedDrop, use the [drop] function just like dropping a type that directly implements [Drop].

In particular, it will never be called more than once, just like [Drop::drop].

Example

use pin_project::{pin_project, pinned_drop};
use std::pin::Pin;

#[pin_project(PinnedDrop)]
struct Foo {
    #[pin]
    field: u8,
}

#[pinned_drop]
impl PinnedDrop for Foo {
    fn drop(self: Pin<&mut Self>) {
        println!("Dropping: {}", self.field);
    }
}

fn main() {
    let _x = Foo { field: 50 };
}

See also "pinned-drop" section of #[pin_project] attribute.

Why #[pinned_drop] attribute is needed?

Implementing PinnedDrop::drop is safe, but calling it is not safe. double dropping is unsound.

Ideally, it would be desirable to be able to forbid manual calls in the same way as [Drop::drop], but the library cannot do it. So, by using macros and replacing them with private traits like the following, we prevent users from calling PinnedDrop::drop in safe code.

pub trait PinnedDrop {
    unsafe fn drop(self: Pin<&mut Self>);
}

This allows implementing [Drop] safely using #[pinned_drop]. Also by using the [drop] function just like dropping a type that directly implements [Drop], can drop safely a type that implements PinnedDrop.