From: Gary Guo Date: Tue, 12 May 2026 12:09:49 +0000 (+0100) Subject: rust: pin-init: internal: init: handle code blocks early X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=df1827babd665ea7039383dbc5c671b66a65c1ec;p=thirdparty%2Flinux.git 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 --- 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