From: Mohamad Alsadhan Date: Tue, 12 May 2026 12:09:47 +0000 (+0100) Subject: rust: pin-init: internal: pin_data: add struct to record field info X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=4b60f38cd2a4b2d3288377f25100f8d67015988a;p=thirdparty%2Flinux.git rust: pin-init: internal: pin_data: add struct to record field info Introduce `FieldInfo` struct to encapsulate field and other relevant data, instead of carrying a pair of `(pinned, field)` in all places. This allows us to add more information to the struct in the future. Signed-off-by: Mohamad Alsadhan Co-developed-by: Gary Guo Link: https://patch.msgid.link/20260512-pin-init-sync-v1-2-81963130dfbd@garyguo.net Signed-off-by: Gary Guo --- diff --git a/rust/pin-init/internal/src/pin_data.rs b/rust/pin-init/internal/src/pin_data.rs index 1a7098a4c6e06..0199d01433086 100644 --- a/rust/pin-init/internal/src/pin_data.rs +++ b/rust/pin-init/internal/src/pin_data.rs @@ -35,6 +35,11 @@ impl Parse for Args { } } +struct FieldInfo<'a> { + field: &'a Field, + pinned: bool, +} + pub(crate) fn pin_data( args: Args, input: Item, @@ -73,24 +78,30 @@ pub(crate) fn pin_data( replacer.visit_generics_mut(&mut struct_.generics); replacer.visit_fields_mut(&mut struct_.fields); - let fields: Vec<(bool, &Field)> = struct_ + let fields: Vec> = struct_ .fields .iter_mut() .map(|field| { let len = field.attrs.len(); field.attrs.retain(|a| !a.path().is_ident("pin")); - (len != field.attrs.len(), &*field) + let pinned = len != field.attrs.len(); + + FieldInfo { + field: &*field, + pinned, + } }) .collect(); - for (pinned, field) in &fields { - if !pinned && is_phantom_pinned(&field.ty) { + for field in &fields { + let ident = field.field.ident.as_ref().unwrap(); + + if !field.pinned && is_phantom_pinned(&field.field.ty) { dcx.warn( - field, + field.field, format!( - "The field `{}` of type `PhantomPinned` only has an effect \ + "The field `{ident}` of type `PhantomPinned` only has an effect \ if it has the `#[pin]` attribute", - field.ident.as_ref().unwrap(), ), ); } @@ -143,7 +154,7 @@ fn is_phantom_pinned(ty: &Type) -> bool { fn generate_unpin_impl( ident: &Ident, generics: &Generics, - fields: &[(bool, &Field)], + fields: &[FieldInfo<'_>], ) -> TokenStream { let (_, ty_generics, _) = generics.split_for_impl(); let mut generics_with_pin_lt = generics.clone(); @@ -160,7 +171,7 @@ fn generate_unpin_impl( else { unreachable!() }; - let pinned_fields = fields.iter().filter_map(|(b, f)| b.then_some(f)); + let pinned_fields = fields.iter().filter(|f| f.pinned).map(|f| f.field); quote! { // This struct will be used for the unpin analysis. It is needed, because only structurally // pinned fields are relevant whether the struct should implement `Unpin`. @@ -238,7 +249,7 @@ fn generate_projections( vis: &Visibility, ident: &Ident, generics: &Generics, - fields: &[(bool, &Field)], + fields: &[FieldInfo<'_>], ) -> TokenStream { let (impl_generics, ty_generics, _) = generics.split_for_impl(); let mut generics_with_pin_lt = generics.clone(); @@ -249,21 +260,21 @@ fn generate_projections( let (fields_decl, fields_proj): (Vec<_>, Vec<_>) = fields .iter() - .map(|(pinned, field)| { + .map(|field| { let Field { vis, ident, ty, attrs, .. - } = field; + } = &field.field; let mut no_doc_attrs = attrs.clone(); no_doc_attrs.retain(|a| !a.path().is_ident("doc")); let ident = ident .as_ref() .expect("only structs with named fields are supported"); - if *pinned { + if field.pinned { ( quote!( #(#attrs)* @@ -291,12 +302,12 @@ fn generate_projections( .collect(); let structurally_pinned_fields_docs = fields .iter() - .filter_map(|(pinned, field)| pinned.then_some(field)) - .map(|Field { ident, .. }| format!(" - `{}`", ident.as_ref().unwrap())); + .filter(|f| f.pinned) + .map(|f| format!(" - `{}`", f.field.ident.as_ref().unwrap())); let not_structurally_pinned_fields_docs = fields .iter() - .filter_map(|(pinned, field)| (!pinned).then_some(field)) - .map(|Field { ident, .. }| format!(" - `{}`", ident.as_ref().unwrap())); + .filter(|f| !f.pinned) + .map(|f| format!(" - `{}`", f.field.ident.as_ref().unwrap())); let docs = format!(" Pin-projections of [`{ident}`]"); quote! { #[doc = #docs] @@ -338,7 +349,7 @@ fn generate_the_pin_data( vis: &Visibility, struct_name: &Ident, generics: &Generics, - fields: &[(bool, &Field)], + fields: &[FieldInfo<'_>], ) -> TokenStream { let (impl_generics, ty_generics, whr) = generics.split_for_impl(); @@ -349,20 +360,20 @@ fn generate_the_pin_data( // The functions are `unsafe` to prevent accidentally calling them. let field_accessors = fields .iter() - .map(|(pinned, field)| { + .map(|f| { let Field { vis, ident, ty, attrs, .. - } = field; + } = f.field; let field_name = ident .as_ref() .expect("only structs with named fields are supported"); let project_ident = format_ident!("__project_{field_name}"); - let (init_ty, init_fn, project_ty, project_body, pin_safety) = if *pinned { + let (init_ty, init_fn, project_ty, project_body, pin_safety) = if f.pinned { ( quote!(PinInit), quote!(__pinned_init),