Skip to content

Commit 6f36e08

Browse files
committed
Merge PinnedDrop and DropInner
1 parent c8de7a8 commit 6f36e08

File tree

2 files changed

+23
-59
lines changed

2 files changed

+23
-59
lines changed

src/lib.rs

Lines changed: 19 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -596,34 +596,17 @@ macro_rules! __pin_project_internal {
596596
)?
597597
{
598598
fn drop(&mut self) {
599-
// Safety - we're in 'drop', so we know that 'self' will
600-
// never move again.
601-
let pinned_self = unsafe { $crate::__private::Pin::new_unchecked(self) };
602-
// We call `pinned_drop` only once. Since `PinnedDrop::drop`
603-
// is an unsafe method and a private API, it is never called again in safe
604-
// code *unless the user uses a maliciously crafted macro*.
605-
unsafe {
606-
$crate::__private::PinnedDrop::drop(pinned_self);
607-
}
608-
}
609-
}
610-
impl $(<
611-
$( $generics
612-
$(: $generics_bound)?
613-
$(: ?$generics_unsized_bound)?
614-
$(: $generics_lifetime_bound)?
615-
),*
616-
>)? $crate::__private::PinnedDrop for $self_ty
617-
$(where
618-
$( $where_clause_ty
619-
$(: $where_clause_bound)?
620-
$(: ?$where_clause_unsized_bound)?
621-
$(: $where_clause_lifetime_bound)?
622-
),*
623-
)?
624-
{
625-
unsafe fn drop(self: $crate::__private::Pin<&mut Self>) {
626-
trait __InnerDrop {
599+
// Implementing `__DropInner::__drop_inner` is safe, but calling it is not safe.
600+
// This is because destructors can be called multiple times in safe code and
601+
// [double dropping is unsound](https://github.com/rust-lang/rust/pull/62360).
602+
//
603+
// `__drop_inner` is defined as a safe method, but this is fine since
604+
// `__drop_inner` is not accessible by the users and we call `__drop_inner` only
605+
// once.
606+
//
607+
// Users can implement [`Drop`] safely using `pin_project!` and can drop a
608+
// type that implements `PinnedDrop` using the [`drop`] function safely.
609+
trait __DropInner {
627610
fn __drop_inner(self: $crate::__private::Pin<&mut Self>);
628611
}
629612
impl $(<
@@ -632,7 +615,7 @@ macro_rules! __pin_project_internal {
632615
$(: ?$generics_unsized_bound)?
633616
$(: $generics_lifetime_bound)?
634617
),*
635-
>)? __InnerDrop for $self_ty
618+
>)? __DropInner for $self_ty
636619
$(where
637620
$( $where_clause_ty
638621
$(: $where_clause_bound)?
@@ -645,7 +628,13 @@ macro_rules! __pin_project_internal {
645628
$($tt)*
646629
}
647630
}
648-
__InnerDrop::__drop_inner(self);
631+
632+
// Safety - we're in 'drop', so we know that 'self' will
633+
// never move again.
634+
let pinned_self = unsafe { $crate::__private::Pin::new_unchecked(self) };
635+
// We call `__drop_inner` only once. Since `__DropInner::__drop_inner`
636+
// is not accessible by the users, it is never called again.
637+
__DropInner::__drop_inner(pinned_self);
649638
}
650639
}
651640
};
@@ -741,24 +730,6 @@ pub mod __private {
741730
pin::Pin,
742731
};
743732

744-
// Implementing `PinnedDrop::drop` is safe, but calling it is not safe.
745-
// This is because destructors can be called multiple times in safe code and
746-
// [double dropping is unsound](https://github.com/rust-lang/rust/pull/62360).
747-
//
748-
// Ideally, it would be desirable to be able to forbid manual calls in
749-
// the same way as [`Drop::drop`], but the library cannot do it. So, by using
750-
// macros and replacing them with private traits, we prevent users from
751-
// calling `PinnedDrop::drop`.
752-
//
753-
// Users can implement [`Drop`] safely using `#[pinned_drop]` and can drop a
754-
// type that implements `PinnedDrop` using the [`drop`] function safely.
755-
// **Do not call or implement this trait directly.**
756-
#[doc(hidden)]
757-
pub trait PinnedDrop {
758-
#[doc(hidden)]
759-
unsafe fn drop(self: Pin<&mut Self>);
760-
}
761-
762733
// This is an internal helper struct used by `pin_project!`.
763734
#[doc(hidden)]
764735
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)