@@ -16,7 +16,7 @@ use syn::{
1616
1717use crate :: {
1818 diagnostics:: { DiagCtxt , ErrorGuaranteed } ,
19- util:: { Binder , LifetimeExt , TypeExt } ,
19+ util:: { Binder , GenericsExt , LifetimeExt , TypeExt } ,
2020} ;
2121
2222pub ( crate ) mod kw {
@@ -293,14 +293,48 @@ pub(crate) fn pin_data(
293293 }
294294 }
295295
296+ // Create a lifetime parameter for each field.
297+ let field_lts: Vec < _ > = fields
298+ . iter ( )
299+ . filter ( |f| f. borrowed . is_some ( ) )
300+ . map ( |f| Lifetime :: from_ident ( f. field . ident . as_ref ( ) . unwrap ( ) ) )
301+ . collect ( ) ;
302+ let field_lt_generics = Generics {
303+ lt_token : Some ( Default :: default ( ) ) ,
304+ params : field_lts
305+ . iter ( )
306+ . zip ( std:: iter:: once ( None ) . chain ( field_lts. iter ( ) . map ( Some ) ) )
307+ . map ( |( lt, prev) | {
308+ GenericParam :: Lifetime ( LifetimeParam {
309+ attrs : Vec :: new ( ) ,
310+ lifetime : lt. clone ( ) ,
311+ colon_token : prev. map ( |_| Default :: default ( ) ) ,
312+ bounds : prev. iter ( ) . map ( |& lt| lt. clone ( ) ) . collect ( ) ,
313+ } )
314+ } )
315+ . collect ( ) ,
316+ gt_token : Some ( Default :: default ( ) ) ,
317+ where_clause : None ,
318+ } ;
319+
296320 let struct_def = generate_struct_def ( & struct_, & fields) ;
297321 let unpin_impl = generate_unpin_impl ( & struct_. ident , & struct_. generics , & fields) ;
298322 let drop_impl = generate_drop_impl ( & struct_. ident , & struct_. generics , args) ;
299- let drop_check = generate_drop_check ( dcx, & struct_, & fields) ;
300- let projections =
301- generate_projections ( & struct_. vis , & struct_. ident , & struct_. generics , & fields) ;
302- let the_pin_data =
303- generate_the_pin_data ( & struct_. vis , & struct_. ident , & struct_. generics , & fields) ;
323+ let drop_check = generate_drop_check ( dcx, & struct_, & fields, & field_lt_generics) ;
324+ let projections = generate_projections (
325+ & struct_. vis ,
326+ & struct_. ident ,
327+ & struct_. generics ,
328+ & fields,
329+ & field_lt_generics,
330+ ) ;
331+ let the_pin_data = generate_the_pin_data (
332+ & struct_. vis ,
333+ & struct_. ident ,
334+ & struct_. generics ,
335+ & fields,
336+ & field_lt_generics,
337+ ) ;
304338
305339 Ok ( quote ! {
306340 #struct_def
@@ -518,6 +552,7 @@ fn generate_drop_check(
518552 dcx : & mut DiagCtxt ,
519553 struct_ : & ItemStruct ,
520554 fields : & [ FieldInfo < ' _ > ] ,
555+ field_lt_generics : & Generics ,
521556) -> TokenStream {
522557 let struct_name = & struct_. ident ;
523558 // If the struct is not self-referential then we can just skip. However, still leave a
@@ -554,22 +589,12 @@ fn generate_drop_check(
554589 }
555590 }
556591
557- // Create a lifetime parameter for each field.
558- let field_lt_params: Vec < _ > = fields
559- . iter ( )
560- . filter ( |f| f. borrowed . is_some ( ) )
561- . map ( |f| {
562- GenericParam :: Lifetime ( LifetimeParam :: new ( Lifetime :: from_ident (
563- f. field . ident . as_ref ( ) . unwrap ( ) ,
564- ) ) )
565- } )
566- . collect ( ) ;
567-
568592 let mut generics_with_field_lt = struct_. generics . clone ( ) ;
569593 generics_with_field_lt
570594 . params
571- . extend ( field_lt_params . iter ( ) . cloned ( ) ) ;
595+ . extend ( field_lt_generics . params . iter ( ) . cloned ( ) ) ;
572596
597+ let field_lt_for_generics = field_lt_generics. for_generics ( ) ;
573598 let ( _, ty_generics_with_field_lt, _) = generics_with_field_lt. split_for_impl ( ) ;
574599 let ( impl_generics, ty_generics, whr) = struct_. generics . split_for_impl ( ) ;
575600
@@ -668,7 +693,7 @@ fn generate_drop_check(
668693 fn __drop_check #impl_generics (
669694 // This must be present so the function can observe the implied bounds.
670695 _: & #struct_name #ty_generics,
671- f: impl for <# ( #field_lt_params , ) * > :: core:: ops:: FnOnce ( __DropCheck #ty_generics_with_field_lt)
696+ f: impl #field_lt_for_generics :: core:: ops:: FnOnce ( __DropCheck #ty_generics_with_field_lt)
672697 ) #whr {
673698 #( #guards) *
674699
@@ -684,6 +709,7 @@ fn generate_projections(
684709 ident : & Ident ,
685710 generics : & Generics ,
686711 fields : & [ FieldInfo < ' _ > ] ,
712+ field_lt_generics : & Generics ,
687713) -> TokenStream {
688714 let pin_lt = Lifetime :: new ( "'__pin" , Span :: mixed_site ( ) ) ;
689715
@@ -695,19 +721,11 @@ fn generate_projections(
695721 ) ;
696722 let ( _, ty_generics_with_pin_lt, whr) = generics_with_pin_lt. split_for_impl ( ) ;
697723
698- let field_lt_params: Vec < _ > = fields
699- . iter ( )
700- . filter ( |f| f. borrowed . is_some ( ) )
701- . map ( |f| {
702- GenericParam :: Lifetime ( LifetimeParam :: new ( Lifetime :: from_ident (
703- f. field . ident . as_ref ( ) . unwrap ( ) ,
704- ) ) )
705- } )
706- . collect ( ) ;
707724 let mut generics_with_field_lt = generics. clone ( ) ;
708725 generics_with_field_lt
709726 . params
710- . extend ( field_lt_params. iter ( ) . cloned ( ) ) ;
727+ . extend ( field_lt_generics. params . iter ( ) . cloned ( ) ) ;
728+ let field_lt_for_generics = field_lt_generics. for_generics ( ) ;
711729 let ( _, ty_generics_with_field_lt, _) = generics_with_field_lt. split_for_impl ( ) ;
712730
713731 let mut generics_with_pin_field_lt = generics_with_field_lt. clone ( ) ;
@@ -1008,7 +1026,7 @@ fn generate_projections(
10081026 #[ inline]
10091027 #vis fn with_project<' __pin, R >(
10101028 self : :: core:: pin:: Pin <& ' __pin mut Self >,
1011- f: impl for <# ( #field_lt_params , ) * > :: core:: ops:: FnOnce ( __ProjectionLt #ty_generics_with_pin_field_lt) -> R
1029+ f: impl #field_lt_for_generics :: core:: ops:: FnOnce ( __ProjectionLt #ty_generics_with_pin_field_lt) -> R
10121030 ) -> R {
10131031 // SAFETY: we only give access to `&mut` for fields not structurally pinned.
10141032 let #this = unsafe { :: core:: pin:: Pin :: get_unchecked_mut( self ) } ;
@@ -1028,22 +1046,14 @@ fn generate_the_pin_data(
10281046 struct_name : & Ident ,
10291047 generics : & Generics ,
10301048 fields : & [ FieldInfo < ' _ > ] ,
1049+ field_lt_generics : & Generics ,
10311050) -> TokenStream {
1032- let field_lt_params: Vec < _ > = fields
1033- . iter ( )
1034- . filter ( |f| f. borrowed . is_some ( ) )
1035- . map ( |f| {
1036- GenericParam :: Lifetime ( LifetimeParam :: new ( Lifetime :: from_ident (
1037- f. field . ident . as_ref ( ) . unwrap ( ) ,
1038- ) ) )
1039- } )
1040- . collect ( ) ;
1041-
10421051 let mut generics_with_field_lt = generics. clone ( ) ;
10431052 generics_with_field_lt
10441053 . params
1045- . extend ( field_lt_params . iter ( ) . cloned ( ) ) ;
1054+ . extend ( field_lt_generics . params . iter ( ) . cloned ( ) ) ;
10461055
1056+ let field_lt_for_generics = field_lt_generics. for_generics ( ) ;
10471057 let ( impl_generics_with_lt, ty_generics_with_field_lt, _) =
10481058 generics_with_field_lt. split_for_impl ( ) ;
10491059 let ( impl_generics, ty_generics, whr) = generics. split_for_impl ( ) ;
@@ -1189,14 +1199,14 @@ fn generate_the_pin_data(
11891199 #[ inline( always) ]
11901200 #vis fn __make_closure<__F, __E>( self , f: __F) -> __F
11911201 where
1192- __F: for <# ( #field_lt_params , ) * > :: core:: ops:: FnOnce ( * mut #struct_name #ty_generics, __PinDataLt #ty_generics_with_field_lt) ->
1202+ __F: #field_lt_for_generics :: core:: ops:: FnOnce ( * mut #struct_name #ty_generics, __PinDataLt #ty_generics_with_field_lt) ->
11931203 :: core:: result:: Result <:: pin_init:: __internal:: InitOk , __E>,
11941204 {
11951205 f
11961206 }
11971207
11981208 #[ inline( always) ]
1199- fn __with_lt<# ( #field_lt_params , ) * > ( self ) -> __PinDataLt #ty_generics_with_field_lt {
1209+ fn __with_lt #field_lt_generics ( self ) -> __PinDataLt #ty_generics_with_field_lt {
12001210 __PinDataLt { __phantom: :: core:: marker:: PhantomData }
12011211 }
12021212 }
0 commit comments