aboutsummaryrefslogtreecommitdiffstats
path: root/rust
diff options
authorGary Guo <gary@garyguo.net>2026-05-12 13:09:49 +0100
committerGary Guo <gary@garyguo.net>2026-05-18 12:18:06 +0100
commitdf1827babd665ea7039383dbc5c671b66a65c1ec (patch)
tree7f485ce6138653e3a6e172862f48a2212c8e9ca4 /rust
parentfea304ec875454360a3be106e0baad96032bf9fe (diff)
downloadlinux-next-history-df1827babd665ea7039383dbc5c671b66a65c1ec.tar.gz
rust: pin-init: internal: init: handle code blocks early
`InitializerKind::Code` is a special case where it does not initialize a field, and thus generate no guard and accessors. Handle it earlier and make the rest of the code more linear. Signed-off-by: Gary Guo <gary@garyguo.net>
Diffstat (limited to 'rust')
-rw-r--r--rust/pin-init/internal/src/init.rs100
1 files changed, 55 insertions, 45 deletions
diff --git a/rust/pin-init/internal/src/init.rs b/rust/pin-init/internal/src/init.rs
index b0bfe44695e19..7eda1bcf0f28b 100644
--- a/rust/pin-init/internal/src/init.rs
+++ b/rust/pin-init/internal/src/init.rs
@@ -231,6 +231,20 @@ fn init_fields(
cfgs.retain(|attr| attr.path().is_ident("cfg"));
cfgs
};
+
+ let ident = match kind {
+ InitializerKind::Value { ident, .. } => ident,
+ InitializerKind::Init { ident, .. } => ident,
+ InitializerKind::Code { block, .. } => {
+ res.extend(quote! {
+ #(#attrs)*
+ #[allow(unused_braces)]
+ #block
+ });
+ continue;
+ }
+ };
+
let init = match kind {
InitializerKind::Value { ident, value } => {
let mut value_ident = ident.clone();
@@ -283,55 +297,51 @@ fn init_fields(
}
}
}
- InitializerKind::Code { block: value, .. } => quote! {
- #(#attrs)*
- #[allow(unused_braces)]
- #value
- },
+ InitializerKind::Code { .. } => unreachable!(),
};
- res.extend(init);
- if let Some(ident) = kind.ident() {
- // `mixed_site` ensures that the guard is not accessible to the user-controlled code.
- let guard = format_ident!("__{ident}_guard", span = Span::mixed_site());
- // NOTE: The reference is derived from the guard so that it only lives as long as the
- // guard does and cannot escape the scope. If it's created via `&mut (*#slot).#ident`
- // like the unaligned field guard, it will become effectively `'static`.
- let accessor = if pinned {
- let project_ident = format_ident!("__project_{ident}");
- quote! {
- // SAFETY: the initialization is pinned.
- unsafe { #data.#project_ident(#guard.let_binding()) }
- }
- } else {
- quote! {
- #guard.let_binding()
- }
- };
+ // `mixed_site` ensures that the guard is not accessible to the user-controlled code.
+ let guard = format_ident!("__{ident}_guard", span = Span::mixed_site());
- res.extend(quote! {
- #(#cfgs)*
- // Create the drop guard.
- //
- // SAFETY:
- // - `&raw mut (*slot).#ident` is valid.
- // - `make_field_check` checks that `&raw mut (*slot).#ident` is properly aligned.
- // - `(*slot).#ident` has been initialized above.
- // - We only need the ownership to the pointee back when initialization has
- // succeeded, where we `forget` the guard.
- let mut #guard = unsafe {
- ::pin_init::__internal::DropGuard::new(
- &raw mut (*slot).#ident
- )
- };
+ // NOTE: The reference is derived from the guard so that it only lives as long as the
+ // guard does and cannot escape the scope. If it's created via `&mut (*#slot).#ident`
+ // like the unaligned field guard, it will become effectively `'static`.
+ let accessor = if pinned {
+ let project_ident = format_ident!("__project_{ident}");
+ quote! {
+ // SAFETY: the initialization is pinned.
+ unsafe { #data.#project_ident(#guard.let_binding()) }
+ }
+ } else {
+ quote! {
+ #guard.let_binding()
+ }
+ };
- #(#cfgs)*
- #[allow(unused_variables)]
- let #ident = #accessor;
- });
- guards.push(guard);
- guard_attrs.push(cfgs);
- }
+ res.extend(quote! {
+ #init
+
+ #(#cfgs)*
+ // Create the drop guard.
+ //
+ // SAFETY:
+ // - `&raw mut (*slot).#ident` is valid.
+ // - `make_field_check` checks that `&raw mut (*slot).#ident` is properly aligned.
+ // - `(*slot).#ident` has been initialized above.
+ // - We only need the ownership to the pointee back when initialization has
+ // succeeded, where we `forget` the guard.
+ let mut #guard = unsafe {
+ ::pin_init::__internal::DropGuard::new(
+ &raw mut (*slot).#ident
+ )
+ };
+
+ #(#cfgs)*
+ #[allow(unused_variables)]
+ let #ident = #accessor;
+ });
+ guards.push(guard);
+ guard_attrs.push(cfgs);
}
quote! {
#res