Skip to content

Commit b5a4d79

Browse files
committed
Merge PinnedDrop and DropInner
1 parent da512da commit b5a4d79

File tree

2 files changed

+23
-60
lines changed

2 files changed

+23
-60
lines changed

src/lib.rs

Lines changed: 19 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -708,35 +708,17 @@ macro_rules! __pin_project_internal {
708708
)?
709709
{
710710
fn drop(&mut self) {
711-
// Safety - we're in 'drop', so we know that 'self' will
712-
// never move again.
713-
let pinned_self = unsafe { $crate::__private::Pin::new_unchecked(self) };
714-
// We call `pinned_drop` only once. Since `PinnedDrop::drop`
715-
// is an unsafe method and a private API, it is never called again in safe
716-
// code *unless the user uses a maliciously crafted macro*.
717-
unsafe {
718-
$crate::__private::PinnedDrop::drop(pinned_self);
719-
}
720-
}
721-
}
722-
impl $(<
723-
$( $lifetime $(: $lifetime_bound)? ),*
724-
$( $generics
725-
$(: $generics_bound)?
726-
$(: ?$generics_unsized_bound)?
727-
$(: $generics_lifetime_bound)?
728-
),*
729-
>)? $crate::__private::PinnedDrop for $self_ty
730-
$(where
731-
$( $where_clause_ty
732-
$(: $where_clause_bound)?
733-
$(: ?$where_clause_unsized_bound)?
734-
$(: $where_clause_lifetime_bound)?
735-
),*
736-
)?
737-
{
738-
unsafe fn drop(self: $crate::__private::Pin<&mut Self>) {
739-
trait __InnerDrop {
711+
// Implementing `__DropInner::__drop_inner` is safe, but calling it is not safe.
712+
// This is because destructors can be called multiple times in safe code and
713+
// [double dropping is unsound](https://github.com/rust-lang/rust/pull/62360).
714+
//
715+
// `__drop_inner` is defined as a safe method, but this is fine since
716+
// `__drop_inner` is not accessible by the users and we call `__drop_inner` only
717+
// once.
718+
//
719+
// Users can implement [`Drop`] safely using `pin_project!` and can drop a
720+
// type that implements `PinnedDrop` using the [`drop`] function safely.
721+
trait __DropInner {
740722
fn __drop_inner(self: $crate::__private::Pin<&mut Self>);
741723
}
742724
impl $(<
@@ -746,7 +728,7 @@ macro_rules! __pin_project_internal {
746728
$(: ?$generics_unsized_bound)?
747729
$(: $generics_lifetime_bound)?
748730
),*
749-
>)? __InnerDrop for $self_ty
731+
>)? __DropInner for $self_ty
750732
$(where
751733
$( $where_clause_ty
752734
$(: $where_clause_bound)?
@@ -759,7 +741,13 @@ macro_rules! __pin_project_internal {
759741
$($tt)*
760742
}
761743
}
762-
__InnerDrop::__drop_inner(self);
744+
745+
// Safety - we're in 'drop', so we know that 'self' will
746+
// never move again.
747+
let pinned_self = unsafe { $crate::__private::Pin::new_unchecked(self) };
748+
// We call `__drop_inner` only once. Since `__DropInner::__drop_inner`
749+
// is not accessible by the users, it is never called again.
750+
__DropInner::__drop_inner(pinned_self);
763751
}
764752
}
765753
};
@@ -871,24 +859,6 @@ pub mod __private {
871859
pin::Pin,
872860
};
873861

874-
// Implementing `PinnedDrop::drop` is safe, but calling it is not safe.
875-
// This is because destructors can be called multiple times in safe code and
876-
// [double dropping is unsound](https://github.com/rust-lang/rust/pull/62360).
877-
//
878-
// Ideally, it would be desirable to be able to forbid manual calls in
879-
// the same way as [`Drop::drop`], but the library cannot do it. So, by using
880-
// macros and replacing them with private traits, we prevent users from
881-
// calling `PinnedDrop::drop`.
882-
//
883-
// Users can implement [`Drop`] safely using `#[pinned_drop]` and can drop a
884-
// type that implements `PinnedDrop` using the [`drop`] function safely.
885-
// **Do not call or implement this trait directly.**
886-
#[doc(hidden)]
887-
pub trait PinnedDrop {
888-
#[doc(hidden)]
889-
unsafe fn drop(self: Pin<&mut Self>);
890-
}
891-
892862
// This is an internal helper struct used by `pin_project!`.
893863
#[doc(hidden)]
894864
pub struct AlwaysUnpin<T: ?Sized>(PhantomData<T>);

tests/expand/tests/expand/pinned_drop-struct.expanded.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,23 +61,16 @@ const _: () = {
6161
}
6262
impl<T, U> ::pin_project_lite::__private::Drop for Struct<T, U> {
6363
fn drop(&mut self) {
64-
let pinned_self = unsafe { ::pin_project_lite::__private::Pin::new_unchecked(self) };
65-
unsafe {
66-
::pin_project_lite::__private::PinnedDrop::drop(pinned_self);
67-
}
68-
}
69-
}
70-
impl<T, U> ::pin_project_lite::__private::PinnedDrop for Struct<T, U> {
71-
unsafe fn drop(self: ::pin_project_lite::__private::Pin<&mut Self>) {
72-
trait __InnerDrop {
64+
trait __DropInner {
7365
fn __drop_inner(self: ::pin_project_lite::__private::Pin<&mut Self>);
7466
}
75-
impl<T, U> __InnerDrop for Struct<T, U> {
67+
impl<T, U> __DropInner for Struct<T, U> {
7668
fn __drop_inner(self: ::pin_project_lite::__private::Pin<&mut Self>) {
7769
let _this = self;
7870
}
7971
}
80-
__InnerDrop::__drop_inner(self);
72+
let pinned_self = unsafe { ::pin_project_lite::__private::Pin::new_unchecked(self) };
73+
__DropInner::__drop_inner(pinned_self);
8174
}
8275
}
8376
#[deny(safe_packed_borrows)]

0 commit comments

Comments
 (0)