From: Gary Guo <gary@garyguo.net>
To: "Benno Lossin" <lossin@kernel.org>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Boqun Feng" <boqun@kernel.org>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>
Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
Gary Guo <gary@garyguo.net>, Mohamad Alsadhan <mo@sdhn.cc>
Subject: [PATCH 2/8] rust: pin-init: internal: pin_data: add struct to record field info
Date: Tue, 12 May 2026 13:09:47 +0100 [thread overview]
Message-ID: <20260512-pin-init-sync-v1-2-81963130dfbd@garyguo.net> (raw)
In-Reply-To: <20260512-pin-init-sync-v1-0-81963130dfbd@garyguo.net>
From: Mohamad Alsadhan <mo@sdhn.cc>
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 <mo@sdhn.cc>
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
---
rust/pin-init/internal/src/pin_data.rs | 53 ++++++++++++++++++++--------------
1 file changed, 32 insertions(+), 21 deletions(-)
diff --git a/rust/pin-init/internal/src/pin_data.rs b/rust/pin-init/internal/src/pin_data.rs
index 1a7098a4c6e0..0199d0143308 100644
--- a/rust/pin-init/internal/src/pin_data.rs
+++ b/rust/pin-init/internal/src/pin_data.rs
@@ -35,6 +35,11 @@ fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
}
}
+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<FieldInfo<'_>> = 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),
--
2.51.2
next prev parent reply other threads:[~2026-05-12 12:10 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-12 12:09 [PATCH 0/8] rust: pin-init: internal refactors Gary Guo
2026-05-12 12:09 ` [PATCH 1/8] rust: pin-init: internal: pin_data: use closure for `handle_field` Gary Guo
2026-05-12 12:09 ` Gary Guo [this message]
2026-05-12 12:09 ` [PATCH 3/8] rust: pin-init: internal: add `PhantomInvariant` and `PhantomInvariantLifetime` Gary Guo
2026-05-12 12:09 ` [PATCH 4/8] rust: pin-init: internal: init: handle code blocks early Gary Guo
2026-05-12 12:09 ` [PATCH 5/8] rust: pin-init: internal: use marker on drop guard type for pinned fields Gary Guo
2026-05-12 12:09 ` [PATCH 6/8] rust: pin-init: internal: make `make_closure` inherent methods Gary Guo
2026-05-12 12:09 ` [PATCH 7/8] rust: pin-init: internal: project slots instead of references Gary Guo
2026-05-12 12:09 ` [PATCH 8/8] rust: pin-init: internal: project using full slot Gary Guo
2026-05-14 19:15 ` Gary Guo
2026-05-14 19:31 ` (subset) [PATCH 0/8] rust: pin-init: internal refactors Gary Guo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260512-pin-init-sync-v1-2-81963130dfbd@garyguo.net \
--to=gary@garyguo.net \
--cc=a.hindborg@kernel.org \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=mo@sdhn.cc \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.