@@ -831,6 +831,17 @@ macro_rules! __pin_data {
831
831
$( $fields) *
832
832
}
833
833
834
+ $crate:: __pin_data!( make_pin_projections:
835
+ @vis( $vis) ,
836
+ @name( $name) ,
837
+ @impl_generics( $( $impl_generics) * ) ,
838
+ @ty_generics( $( $ty_generics) * ) ,
839
+ @decl_generics( $( $decl_generics) * ) ,
840
+ @where ( $( $whr) * ) ,
841
+ @pinned( $( $pinned) * ) ,
842
+ @not_pinned( $( $not_pinned) * ) ,
843
+ ) ;
844
+
834
845
// We put the rest into this const item, because it then will not be accessible to anything
835
846
// outside.
836
847
const _: ( ) = {
@@ -980,6 +991,47 @@ macro_rules! __pin_data {
980
991
stringify!( $( $rest) * ) ,
981
992
) ;
982
993
} ;
994
+ ( make_pin_projections:
995
+ @vis( $vis: vis) ,
996
+ @name( $name: ident) ,
997
+ @impl_generics( $( $impl_generics: tt) * ) ,
998
+ @ty_generics( $( $ty_generics: tt) * ) ,
999
+ @decl_generics( $( $decl_generics: tt) * ) ,
1000
+ @where ( $( $whr: tt) * ) ,
1001
+ @pinned( $( $( #[ $( $p_attr: tt) * ] ) * $pvis: vis $p_field: ident : $p_type: ty) ,* $( , ) ?) ,
1002
+ @not_pinned( $( $( #[ $( $attr: tt) * ] ) * $fvis: vis $field: ident : $type: ty) ,* $( , ) ?) ,
1003
+ ) => {
1004
+ $crate:: macros:: paste! {
1005
+ #[ doc( hidden) ]
1006
+ $vis struct [ < $name Projection >] <' __pin, $( $decl_generics) * > {
1007
+ $( $pvis $p_field : :: core:: pin:: Pin <& ' __pin mut $p_type>, ) *
1008
+ $( $fvis $field : & ' __pin mut $type, ) *
1009
+ ___pin_phantom_data: :: core:: marker:: PhantomData <& ' __pin mut ( ) >,
1010
+ }
1011
+
1012
+ impl <$( $impl_generics) * > $name<$( $ty_generics) * >
1013
+ where $( $whr) *
1014
+ {
1015
+ /// Pin-projects all fields of `Self`.
1016
+ pub fn project<' __pin>(
1017
+ self : :: core:: pin:: Pin <& ' __pin mut Self >,
1018
+ ) -> [ < $name Projection >] <' __pin, $( $ty_generics) * > {
1019
+ // SAFETY: we only give access to `&mut` for fields not structurally pinned.
1020
+ let this = unsafe { :: core:: pin:: Pin :: get_unchecked_mut( self ) } ;
1021
+ [ < $name Projection >] {
1022
+ $(
1023
+ // SAFETY: `$p_field` is structurally pinned.
1024
+ $p_field : unsafe { :: core:: pin:: Pin :: new_unchecked( & mut this. $p_field) } ,
1025
+ ) *
1026
+ $(
1027
+ $field : & mut this. $field,
1028
+ ) *
1029
+ ___pin_phantom_data: :: core:: marker:: PhantomData ,
1030
+ }
1031
+ }
1032
+ }
1033
+ }
1034
+ } ;
983
1035
( make_pin_data:
984
1036
@pin_data( $pin_data: ident) ,
985
1037
@impl_generics( $( $impl_generics: tt) * ) ,
0 commit comments