8282//! error you can pass the same input to [pin-project] to receive a helpful
8383//! description of the compile error.
8484//!
85- //! ## Different: No support for custom Drop implementation
86- //!
87- //! pin-project supports this by [`#[pinned_drop]`][pinned-drop].
88- //!
8985//! ## Different: No support for custom Unpin implementation
9086//!
9187//! pin-project supports this by [`UnsafeUnpin`][unsafe-unpin] and [`!Unpin`][not-unpin].
9692//!
9793//! [not-unpin]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unpin
9894//! [pin-project]: https://github.com/taiki-e/pin-project
99- //! [pinned-drop]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#pinned_drop
10095//! [unsafe-unpin]: https://docs.rs/pin-project/1/pin_project/attr.pin_project.html#unsafeunpin
10196
10297#![ no_std]
@@ -331,6 +326,7 @@ macro_rules! __pin_project_internal {
331326 $field_vis: vis $field: ident: $field_ty: ty
332327 ) ,+
333328 }
329+ $( impl $( $pinned_drop: tt) * ) ?
334330 ) => {
335331 $( #[ $attrs] ) *
336332 $vis struct $ident $( $def_generics) *
@@ -374,6 +370,7 @@ macro_rules! __pin_project_internal {
374370 [ make_proj_field_replace]
375371 [ $ident]
376372 [ $( $impl_generics) * ] [ $( $ty_generics) * ] [ $( where $( $where_clause) * ) ?]
373+ [ $( impl $( $pinned_drop) * ) ?]
377374 {
378375 $(
379376 $( #[ $pin] ) ?
@@ -422,6 +419,7 @@ macro_rules! __pin_project_internal {
422419 [ make_proj_field_replace]
423420 [ $ident]
424421 [ $( $impl_generics) * ] [ $( $ty_generics) * ] [ $( where $( $where_clause) * ) ?]
422+ [ $( impl $( $pinned_drop) * ) ?]
425423 {
426424 $(
427425 $( #[ $pin] ) ?
@@ -484,6 +482,7 @@ macro_rules! __pin_project_internal {
484482 $crate:: __pin_project_internal! { @make_drop_impl;
485483 [ $ident]
486484 [ $( $impl_generics) * ] [ $( $ty_generics) * ] [ $( where $( $where_clause) * ) ?]
485+ $( impl $( $pinned_drop) * ) ?
487486 }
488487
489488 // Ensure that it's impossible to use pin projections on a #[repr(packed)] struct.
@@ -538,6 +537,7 @@ macro_rules! __pin_project_internal {
538537 } ) ?
539538 ) ,+
540539 }
540+ $( impl $( $pinned_drop: tt) * ) ?
541541 ) => {
542542 $( #[ $attrs] ) *
543543 $vis enum $ident $( $def_generics) *
@@ -594,6 +594,7 @@ macro_rules! __pin_project_internal {
594594 [ make_proj_field_replace]
595595 [ $ident]
596596 [ $( $impl_generics) * ] [ $( $ty_generics) * ] [ $( where $( $where_clause) * ) ?]
597+ [ $( impl $( $pinned_drop) * ) ?]
597598 {
598599 $(
599600 $variant $( {
@@ -682,6 +683,7 @@ macro_rules! __pin_project_internal {
682683 $crate:: __pin_project_internal! { @make_drop_impl;
683684 [ $ident]
684685 [ $( $impl_generics) * ] [ $( $ty_generics) * ] [ $( where $( $where_clause) * ) ?]
686+ $( impl $( $pinned_drop) * ) ?
685687 }
686688
687689 // We don't need to check for '#[repr(packed)]',
@@ -765,6 +767,7 @@ macro_rules! __pin_project_internal {
765767 [ $make_proj_field: ident]
766768 [ $ident: ident]
767769 [ $( $impl_generics: tt) * ] [ $( $ty_generics: tt) * ] [ $( where $( $where_clause: tt) * ) ?]
770+ [ $( impl $( $pinned_drop: tt) * ) ?]
768771 $( $field: tt) *
769772 ) => { } ;
770773 ( @struct =>make_proj_replace_ty=>unnamed;
@@ -773,15 +776,16 @@ macro_rules! __pin_project_internal {
773776 [ $make_proj_field: ident]
774777 [ $ident: ident]
775778 [ $( $impl_generics: tt) * ] [ $( $ty_generics: tt) * ] [ $( where $( $where_clause: tt) * ) ?]
779+ [ $( impl $( $pinned_drop: tt) * ) ?]
776780 $( $field: tt) *
777- ) => {
778- } ;
781+ ) => { } ;
779782 ( @struct =>make_proj_replace_ty=>named;
780783 [ $proj_vis: vis]
781784 [ $proj_ty_ident: ident]
782785 [ $make_proj_field: ident]
783786 [ $ident: ident]
784787 [ $( $impl_generics: tt) * ] [ $( $ty_generics: tt) * ] [ $( where $( $where_clause: tt) * ) ?]
788+ [ ]
785789 {
786790 $(
787791 $( #[ $pin: ident] ) ?
@@ -811,6 +815,7 @@ macro_rules! __pin_project_internal {
811815 [ $make_proj_field: ident]
812816 [ $ident: ident]
813817 [ $( $impl_generics: tt) * ] [ $( $ty_generics: tt) * ] [ $( where $( $where_clause: tt) * ) ?]
818+ [ $( impl $( $pinned_drop: tt) * ) ?]
814819 $( $field: tt) *
815820 ) => { } ;
816821 // =============================================================================================
@@ -872,6 +877,7 @@ macro_rules! __pin_project_internal {
872877 [ $make_proj_field: ident]
873878 [ $ident: ident]
874879 [ $( $impl_generics: tt) * ] [ $( $ty_generics: tt) * ] [ $( where $( $where_clause: tt) * ) ?]
880+ [ ]
875881 {
876882 $(
877883 $variant: ident $( {
@@ -909,6 +915,7 @@ macro_rules! __pin_project_internal {
909915 [ $make_proj_field: ident]
910916 [ $ident: ident]
911917 [ $( $impl_generics: tt) * ] [ $( $ty_generics: tt) * ] [ $( where $( $where_clause: tt) * ) ?]
918+ [ $( impl $( $pinned_drop: tt) * ) ?]
912919 $( $variant: tt) *
913920 ) => { } ;
914921
@@ -1193,6 +1200,90 @@ macro_rules! __pin_project_internal {
11931200
11941201 // =============================================================================================
11951202 // make_drop_impl
1203+ ( @make_drop_impl;
1204+ [ $_ident: ident]
1205+ [ $( $_impl_generics: tt) * ] [ $( $_ty_generics: tt) * ] [ $( where $( $_where_clause: tt) * ) ?]
1206+ impl $( <
1207+ $( $lifetime: lifetime $( : $lifetime_bound: lifetime) ? ) ,* $( , ) ?
1208+ $( $generics: ident
1209+ $( : $generics_bound: path) ?
1210+ $( : ?$generics_unsized_bound: path) ?
1211+ $( : $generics_lifetime_bound: lifetime) ?
1212+ ) ,*
1213+ >) ? PinnedDrop for $self_ty: ty
1214+ $( where
1215+ $( $where_clause_ty: ty
1216+ $( : $where_clause_bound: path) ?
1217+ $( : ?$where_clause_unsized_bound: path) ?
1218+ $( : $where_clause_lifetime_bound: lifetime) ?
1219+ ) ,*
1220+ ) ?
1221+ {
1222+ fn drop( $( $arg: ident) +: Pin <& mut Self >) {
1223+ $( $tt: tt) *
1224+ }
1225+ }
1226+ ) => {
1227+ impl $( <
1228+ $( $lifetime $( : $lifetime_bound) ? , ) *
1229+ $( $generics
1230+ $( : $generics_bound) ?
1231+ $( : ?$generics_unsized_bound) ?
1232+ $( : $generics_lifetime_bound) ?
1233+ ) ,*
1234+ >) ? $crate:: __private:: Drop for $self_ty
1235+ $( where
1236+ $( $where_clause_ty
1237+ $( : $where_clause_bound) ?
1238+ $( : ?$where_clause_unsized_bound) ?
1239+ $( : $where_clause_lifetime_bound) ?
1240+ ) ,*
1241+ ) ?
1242+ {
1243+ fn drop( & mut self ) {
1244+ // Implementing `__DropInner::__drop_inner` is safe, but calling it is not safe.
1245+ // This is because destructors can be called multiple times in safe code and
1246+ // [double dropping is unsound](https://github.com/rust-lang/rust/pull/62360).
1247+ //
1248+ // `__drop_inner` is defined as a safe method, but this is fine since
1249+ // `__drop_inner` is not accessible by the users and we call `__drop_inner` only
1250+ // once.
1251+ //
1252+ // Users can implement [`Drop`] safely using `pin_project!` and can drop a
1253+ // type that implements `PinnedDrop` using the [`drop`] function safely.
1254+ fn __drop_inner $( <
1255+ $( $lifetime $( : $lifetime_bound) ? , ) *
1256+ $( $generics
1257+ $( : $generics_bound) ?
1258+ $( : ?$generics_unsized_bound) ?
1259+ $( : $generics_lifetime_bound) ?
1260+ ) ,*
1261+ >) ? (
1262+ $( $arg) +: $crate:: __private:: Pin <& mut $self_ty>,
1263+ )
1264+ $( where
1265+ $( $where_clause_ty
1266+ $( : $where_clause_bound) ?
1267+ $( : ?$where_clause_unsized_bound) ?
1268+ $( : $where_clause_lifetime_bound) ?
1269+ ) ,*
1270+ ) ?
1271+ {
1272+ // A dummy `__drop_inner` function to prevent users call outer `__drop_inner`.
1273+ fn __drop_inner( ) { }
1274+ $( $tt) *
1275+ }
1276+
1277+ // Safety - we're in 'drop', so we know that 'self' will
1278+ // never move again.
1279+ let pinned_self: $crate:: __private:: Pin <& mut Self >
1280+ = unsafe { $crate:: __private:: Pin :: new_unchecked( self ) } ;
1281+ // We call `__drop_inner` only once. Since `__DropInner::__drop_inner`
1282+ // is not accessible by the users, it is never called again.
1283+ __drop_inner( pinned_self) ;
1284+ }
1285+ }
1286+ } ;
11961287 ( @make_drop_impl;
11971288 [ $ident: ident]
11981289 [ $( $impl_generics: tt) * ] [ $( $ty_generics: tt) * ] [ $( where $( $where_clause: tt) * ) ?]
@@ -1414,6 +1505,7 @@ macro_rules! __pin_project_internal {
14141505 $field_vis: vis $field: ident: $field_ty: ty
14151506 ) ,+ $( , ) ?
14161507 }
1508+ $( impl $( $pinned_drop: tt) * ) ?
14171509 ) => {
14181510 $crate:: __pin_project_internal! { @struct =>internal;
14191511 [ $( $proj_mut_ident) ?]
@@ -1450,6 +1542,7 @@ macro_rules! __pin_project_internal {
14501542 $field_vis $field: $field_ty
14511543 ) ,+
14521544 }
1545+ $( impl $( $pinned_drop) * ) ?
14531546 }
14541547 } ;
14551548 (
@@ -1480,6 +1573,7 @@ macro_rules! __pin_project_internal {
14801573 $field_vis: vis $field: ident: $field_ty: ty
14811574 ) ,+ $( , ) ?
14821575 }
1576+ $( impl $( $pinned_drop: tt) * ) ?
14831577 ) => {
14841578 $crate:: __pin_project_internal! { @struct =>internal;
14851579 [ $( $proj_mut_ident) ?]
@@ -1516,6 +1610,7 @@ macro_rules! __pin_project_internal {
15161610 $field_vis $field: $field_ty
15171611 ) ,+
15181612 }
1613+ $( impl $( $pinned_drop) * ) ?
15191614 }
15201615 } ;
15211616 // enum
@@ -1552,6 +1647,7 @@ macro_rules! __pin_project_internal {
15521647 } ) ?
15531648 ) ,+ $( , ) ?
15541649 }
1650+ $( impl $( $pinned_drop: tt) * ) ?
15551651 ) => {
15561652 $crate:: __pin_project_internal! { @enum =>internal;
15571653 [ $( $proj_mut_ident) ?]
@@ -1593,6 +1689,7 @@ macro_rules! __pin_project_internal {
15931689 } ) ?
15941690 ) ,+
15951691 }
1692+ $( impl $( $pinned_drop) * ) ?
15961693 }
15971694 } ;
15981695 (
@@ -1628,6 +1725,7 @@ macro_rules! __pin_project_internal {
16281725 } ) ?
16291726 ) ,+ $( , ) ?
16301727 }
1728+ $( impl $( $pinned_drop: tt) * ) ?
16311729 ) => {
16321730 $crate:: __pin_project_internal! { @enum =>internal;
16331731 [ $( $proj_mut_ident) ?]
@@ -1669,6 +1767,7 @@ macro_rules! __pin_project_internal {
16691767 } ) ?
16701768 ) ,+
16711769 }
1770+ $( impl $( $pinned_drop) * ) ?
16721771 }
16731772 } ;
16741773}
0 commit comments