diff options
| author | Gary Guo <gary@garyguo.net> | 2026-09-16 13:11:33 +0100 |
|---|---|---|
| committer | Gary Guo <gary@garyguo.net> | 2026-09-18 12:21:02 +0100 |
| commit | 7f849c19e22f105c756b32a6a00dfee9cc1a2c2c (patch) | |
| tree | 880565b4e896e0012e9aa3c979f05cb93088c07d /rust | |
| parent | e30decc3f9a0ded621d5b0f19a5253b84d21be0c (diff) | |
| download | linux-next-7f849c19e22f105c756b32a6a00dfee9cc1a2c2c.tar.gz linux-next-7f849c19e22f105c756b32a6a00dfee9cc1a2c2c.zip | |
rust: pin-init: internal: init: use `slot` identifier directly with mixed site
Use `quote_spanned!(Span::mixed_site() => ...)` directly instead of
creating `slot` identifier and interpolate it later. Do the same for
`__data`, too.
This is needed so that we can customize the location of the span without
having the `slot` identifier getting in the way. For example:
quote_spanned!(Span::mixed_site().located_at(loc) => ...)
with `slot` mentioned directly will have the diagnostic pointing to the
desired location, while `#slot` won't.
Link: https://patch.msgid.link/20260916-dev-hygiene-v1-2-dfb6ae2588ba@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
Diffstat (limited to 'rust')
| -rw-r--r-- | rust/pin-init/internal/src/init.rs | 31 |
1 files changed, 12 insertions, 19 deletions
diff --git a/rust/pin-init/internal/src/init.rs b/rust/pin-init/internal/src/init.rs index 6ade192d27e6..a77ffef9926b 100644 --- a/rust/pin-init/internal/src/init.rs +++ b/rust/pin-init/internal/src/init.rs @@ -269,7 +269,6 @@ fn expand( }, |(_, err)| Box::new(err), ); - let slot = Ident::new("slot", Span::mixed_site()); let (has_data_trait, get_data, init_from_closure) = if pinned { ( format_ident!("HasPinData"), @@ -286,7 +285,7 @@ fn expand( let init_kind = get_init_kind(rest, dcx); let zeroable_check = match init_kind { InitKind::Normal => quote!(), - InitKind::Zeroing => quote! { + InitKind::Zeroing => quote_spanned! { Span::mixed_site() => // The user specified `..Zeroable::zeroed()` at the end of the list of fields. // Therefore we check if the struct implements `Zeroable` and then zero the memory. // This allows us to also remove the check that all fields are present (since we @@ -295,9 +294,9 @@ fn expand( where T: ::pin_init::Zeroable {} // Ensure that the struct is indeed `Zeroable`. - assert_zeroable(#slot); + assert_zeroable(slot); // SAFETY: The type implements `Zeroable` by the check above. - unsafe { ::core::ptr::write_bytes(#slot, 0, 1) }; + unsafe { ::core::ptr::write_bytes(slot, 0, 1) }; }, }; let this = match this { @@ -309,20 +308,19 @@ fn expand( }, }; // `mixed_site` ensures that the data is not accessible to the user-controlled code. - let data = Ident::new("__data", Span::mixed_site()); - let init_fields = init_fields(&fields, pinned, &data, &slot); + let init_fields = init_fields(&fields, pinned); let field_check = make_field_check(&fields, init_kind, &path); Ok(quote_spanned! { Span::mixed_site() => { // Get the data about fields from the supplied type. // SAFETY: TODO - let #data = unsafe { + let data = unsafe { use ::pin_init::__internal::#has_data_trait; // Can't use `<#path as #has_data_trait>::#get_data`, since the user is able to omit // generics (which need to be present with that syntax). #path::#get_data() }; - // Ensure that `#data` really is of type `#data` and help with type inference: - let init = #data.__make_closure::<_, #error>( + // Ensure that `data` really is of type `data` and help with type inference: + let init = data.__make_closure::<_, #error>( move |slot| { #zeroable_check #this @@ -380,12 +378,7 @@ fn get_init_kind(rest: Option<(Token![..], Expr)>, dcx: &mut DiagCtxt) -> InitKi } /// Generate the code that initializes the fields of the struct using the initializers in `field`. -fn init_fields( - fields: &Punctuated<InitializerField, Token![,]>, - pinned: bool, - data: &Ident, - slot: &Ident, -) -> TokenStream { +fn init_fields(fields: &Punctuated<InitializerField, Token![,]>, pinned: bool) -> TokenStream { let mut guards = vec![]; let mut guard_attrs = vec![]; let mut res = TokenStream::new(); @@ -413,16 +406,16 @@ fn init_fields( let ident = member.as_ident(); let slot = if pinned { - quote! { + quote_spanned! { Span::mixed_site() => // SAFETY: // - `slot` is valid and properly aligned. // - `make_field_check` checks that `&raw mut (*slot).#member` is properly aligned. // - `make_field_check` prevents `#member` from being used twice, therefore // `(*slot).#member` is exclusively accessed and has not been initialized. - (unsafe { #data.#ident(#slot) }) + (unsafe { data.#ident(slot) }) } } else { - quote! { + quote_spanned! { Span::mixed_site() => // For `init!()` macro, everything is unpinned. // SAFETY: // - `&raw mut (*slot).#member` is valid. @@ -431,7 +424,7 @@ fn init_fields( // `(*slot).#member` is exclusively accessed and has not been initialized. (unsafe { ::pin_init::__internal::Slot::<::pin_init::__internal::Unpinned, _>::new( - &raw mut (*#slot).#member + &raw mut (*slot).#member ) }) } |
