summaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
authorGary Guo <gary@garyguo.net>2026-09-16 13:11:34 +0100
committerGary Guo <gary@garyguo.net>2026-09-18 12:21:06 +0100
commitfb3d5c6b4cca465c68472a918b861b2296768dad (patch)
tree5b0ab9819b72b43ee4907f587496491610201c7a /rust
parent7f849c19e22f105c756b32a6a00dfee9cc1a2c2c (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.rs13
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.