[−][src]Attribute Macro pin_project_internal::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:
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 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
.