diff options
| author | Gary Guo <gary@garyguo.net> | 2026-09-16 13:11:34 +0100 |
|---|---|---|
| committer | Gary Guo <gary@garyguo.net> | 2026-09-18 12:21:06 +0100 |
| commit | fb3d5c6b4cca465c68472a918b861b2296768dad (patch) | |
| tree | 5b0ab9819b72b43ee4907f587496491610201c7a /rust | |
| parent | 7f849c19e22f105c756b32a6a00dfee9cc1a2c2c (diff) | |
rust: pin-init: internal: init: provide span for slot projection
When initializing a field, pin-init first projects the full slot to a slot
of the field, then initialize it by invoking a method. Currently the span
location is not explicitly set, so the error message points to the full
macro invocation.
Improve it by provide a span, so Rust will point to the specific fields
causing the error when type check fails.
Old error message:
error[E0308]: mismatched types
--> tests/ui/compile-fail/init/field_value_wrong_type.rs:8:28
|
8 | let _ = init!(Foo { a: () });
| ---------------^^---
| | |
| | expected `usize`, found `()`
| arguments to this method are incorrect
New error message:
error[E0308]: mismatched types
--> tests/ui/compile-fail/init/field_value_wrong_type.rs:8:28
|
8 | let _ = init!(Foo { a: () });
| ---^^
| | |
| | expected `usize`, found `()`
| arguments to this method are incorrect
Link: https://patch.msgid.link/20260916-dev-hygiene-v1-3-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 | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/rust/pin-init/internal/src/init.rs b/rust/pin-init/internal/src/init.rs index a77ffef9926b..1d2db93dd33d 100644 --- a/rust/pin-init/internal/src/init.rs +++ b/rust/pin-init/internal/src/init.rs @@ -404,9 +404,10 @@ fn init_fields(fields: &Punctuated<InitializerField, Token![,]>, pinned: bool) - } }; let ident = member.as_ident(); + let span = Span::mixed_site().located_at(ident.span()); let slot = if pinned { - quote_spanned! { Span::mixed_site() => + quote_spanned! { span => // SAFETY: // - `slot` is valid and properly aligned. // - `make_field_check` checks that `&raw mut (*slot).#member` is properly aligned. @@ -415,7 +416,7 @@ fn init_fields(fields: &Punctuated<InitializerField, Token![,]>, pinned: bool) - (unsafe { data.#ident(slot) }) } } else { - quote_spanned! { Span::mixed_site() => + quote_spanned! { span => // For `init!()` macro, everything is unpinned. // SAFETY: // - `&raw mut (*slot).#member` is valid. @@ -432,6 +433,7 @@ fn init_fields(fields: &Punctuated<InitializerField, Token![,]>, pinned: bool) - // `mixed_site` ensures that the guard is not accessible to the user-controlled code. let guard = format_ident!("__{ident}_guard", span = Span::mixed_site()); + let full_span = kind.span(); let init = match kind { InitializerKind::Value { value, .. } => { @@ -440,14 +442,13 @@ fn init_fields(fields: &Punctuated<InitializerField, Token![,]>, pinned: bool) - .map(|(_, value)| quote!(#value)) .unwrap_or_else(|| quote!(#member)); - quote! { + quote_spanned! { full_span => #(#attrs)* let mut #guard = #slot.write(#value); - } } InitializerKind::Init { value, .. } => { - quote! { + quote_spanned! { full_span => #(#attrs)* let mut #guard = #slot.init(#value)?; } @@ -458,7 +459,7 @@ fn init_fields(fields: &Punctuated<InitializerField, Token![,]>, pinned: bool) - // A tuple field has no name that could be bound here (the `_0` identifiers are considered // implementation detail and not user-facing). let binding = match member { - Member::Named(ident) => quote! { + Member::Named(ident) => quote_spanned! { span => #(#cfgs)* // Allow `non_snake_case` since the same warning is going to be reported for the // struct field. |
