Attribute Macro pin_project::pinned_drop
source · [−]#[pinned_drop]
Expand description
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:
drop
method takesPin
<&mut Self>
- Name of the trait is
PinnedDrop
.
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 std::pin::Pin;
use pin_project::{pin_project, pinned_drop};
#[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
.