@@ -7,7 +7,7 @@ use syn::{
77 parse_quote, parse_quote_spanned,
88 spanned:: Spanned ,
99 visit_mut:: VisitMut ,
10- Field , Generics , Ident , Item , PathSegment , Type , TypePath , Visibility , WhereClause ,
10+ Attribute , Field , Generics , Ident , Item , PathSegment , Type , TypePath , Visibility , WhereClause ,
1111} ;
1212
1313use crate :: diagnostics:: { DiagCtxt , ErrorGuaranteed } ;
@@ -38,6 +38,7 @@ impl Parse for Args {
3838struct FieldInfo < ' a > {
3939 field : & ' a Field ,
4040 pinned : bool ,
41+ cfg_attrs : Vec < & ' a Attribute > ,
4142}
4243
4344pub ( crate ) fn pin_data (
@@ -86,9 +87,16 @@ pub(crate) fn pin_data(
8687 field. attrs . retain ( |a| !a. path ( ) . is_ident ( "pin" ) ) ;
8788 let pinned = len != field. attrs . len ( ) ;
8889
90+ let cfg_attrs = field
91+ . attrs
92+ . iter ( )
93+ . filter ( |a| a. path ( ) . is_ident ( "cfg" ) )
94+ . collect ( ) ;
95+
8996 FieldInfo {
9097 field : & * field,
9198 pinned,
99+ cfg_attrs,
92100 }
93101 } )
94102 . collect ( ) ;
@@ -171,7 +179,15 @@ fn generate_unpin_impl(
171179 else {
172180 unreachable ! ( )
173181 } ;
174- let pinned_fields = fields. iter ( ) . filter ( |f| f. pinned ) . map ( |f| f. field ) ;
182+ let pinned_fields = fields. iter ( ) . filter ( |f| f. pinned ) . map ( |f| {
183+ let ident = f. field . ident . as_ref ( ) . unwrap ( ) ;
184+ let ty = & f. field . ty ;
185+ let cfg_attrs = & f. cfg_attrs ;
186+ quote ! (
187+ #( #cfg_attrs) *
188+ #ident: #ty
189+ )
190+ } ) ;
175191 quote ! {
176192 // This struct will be used for the unpin analysis. It is needed, because only structurally
177193 // pinned fields are relevant whether the struct should implement `Unpin`.
@@ -259,39 +275,32 @@ fn generate_projections(
259275 let ( fields_decl, fields_proj) : ( Vec < _ > , Vec < _ > ) = fields
260276 . iter ( )
261277 . map ( |field| {
262- let Field {
263- vis,
264- ident,
265- ty,
266- attrs,
267- ..
268- } = & field. field ;
269-
270- let mut no_doc_attrs = attrs. clone ( ) ;
271- no_doc_attrs. retain ( |a| !a. path ( ) . is_ident ( "doc" ) ) ;
278+ let Field { vis, ident, ty, .. } = & field. field ;
279+ let cfg_attrs = & field. cfg_attrs ;
280+
272281 let ident = ident
273282 . as_ref ( )
274283 . expect ( "only structs with named fields are supported" ) ;
275284 if field. pinned {
276285 (
277286 quote ! (
278- #( #attrs ) *
287+ #( #cfg_attrs ) *
279288 #vis #ident: :: core:: pin:: Pin <& ' __pin mut #ty>,
280289 ) ,
281290 quote ! (
282- #( #no_doc_attrs ) *
291+ #( #cfg_attrs ) *
283292 // SAFETY: this field is structurally pinned.
284293 #ident: unsafe { :: core:: pin:: Pin :: new_unchecked( & mut #this. #ident) } ,
285294 ) ,
286295 )
287296 } else {
288297 (
289298 quote ! (
290- #( #attrs ) *
299+ #( #cfg_attrs ) *
291300 #vis #ident: & ' __pin mut #ty,
292301 ) ,
293302 quote ! (
294- #( #no_doc_attrs ) *
303+ #( #cfg_attrs ) *
295304 #ident: & mut #this. #ident,
296305 ) ,
297306 )
@@ -358,13 +367,8 @@ fn generate_the_pin_data(
358367 let field_accessors = fields
359368 . iter ( )
360369 . map ( |f| {
361- let Field {
362- vis,
363- ident,
364- ty,
365- attrs,
366- ..
367- } = f. field ;
370+ let Field { vis, ident, ty, .. } = f. field ;
371+ let cfg_attrs = & f. cfg_attrs ;
368372
369373 let field_name = ident
370374 . as_ref ( )
@@ -381,7 +385,7 @@ fn generate_the_pin_data(
381385 /// - `(*slot).#field_name` is properly aligned.
382386 /// - `(*slot).#field_name` points to uninitialized and exclusively accessed
383387 /// memory.
384- #( #attrs ) *
388+ #( #cfg_attrs ) *
385389 #[ inline( always) ]
386390 #vis unsafe fn #field_name(
387391 self ,
0 commit comments