From: Gary Guo <gary@garyguo.net>
To: "Benno Lossin" <lossin@kernel.org>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Boqun Feng" <boqun@kernel.org>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>,
"Daniel Almeida" <daniel.almeida@collabora.com>,
"Tamir Duberstein" <tamird@kernel.org>,
"Alexandre Courbot" <acourbot@nvidia.com>,
"Onur Özkan" <work@onurozkan.dev>
Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
Gary Guo <gary@garyguo.net>
Subject: [PATCH 3/5] rust: pin-init: internal: use `HasInitData` to provide inference help only
Date: Wed, 23 Sep 2026 19:20:16 +0100 [thread overview]
Message-ID: <20260923-dev-pin-data-diag-v1-3-e4d7193569e5@garyguo.net> (raw)
In-Reply-To: <20260923-dev-pin-data-diag-v1-0-e4d7193569e5@garyguo.net>
Currently, type inference of the initialized type is done by use the
function calling syntax `PATH::__pin_data` or `PATH::__init_data` to obtain
the required init data type, without needing the user to explicitly mention
all generics. Switch to always use `HasInitData::__init_data` to provide
that inference, which will not produce method-not-found errors as it is
always available.
Change `__pin_data` to take `InitData<Self>` as the receiver, so for types
that require `HasPinData`, `HasPinData::__pin_data(data)` can be used to
obtain the needed type without having to mention the user-provided path
again. The expanded code also uses the span of the type, so diagnostics
will hint to user that the type is causing the issue.
With this change, the error message when `HasPinData` is not implemented
changes from
error[E0599]: no associated function or constant named `__pin_data` found for struct `Foo` in the current scope
--> tests/ui/compile-fail/init/missing_pin_data.rs:9:9
|
3 | struct Foo {
| ---------- associated function or constant `__pin_data` not found for this struct
...
9 | pin_init!(Self { a: 42 })
| ^^^^^^^^^^^^^^^^^^^^^^^^^ associated function or constant not found in `Foo`
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `__pin_data`, perhaps you need to implement it:
candidate #1: `pin_init::__internal::HasPinData`
to
error[E0277]: the trait bound `Foo: pin_init::__internal::HasPinData` is not satisfied
--> tests/ui/compile-fail/init/missing_pin_data.rs:9:19
|
9 | pin_init!(Self { a: 42 })
| ^^^^ unsatisfied trait bound
|
help: the trait `pin_init::__internal::HasPinData` is not implemented for `Foo`
--> tests/ui/compile-fail/init/missing_pin_data.rs:3:1
|
3 | struct Foo {
| ^^^^^^^^^^
Signed-off-by: Gary Guo <gary@garyguo.net>
---
rust/pin-init/internal/src/init.rs | 22 ++++++++++++----------
rust/pin-init/internal/src/pin_data.rs | 2 +-
rust/pin-init/src/__internal.rs | 2 +-
rust/pin-init/src/lib.rs | 3 ++-
4 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/rust/pin-init/internal/src/init.rs b/rust/pin-init/internal/src/init.rs
index 1957be83a196..e98182c65447 100644
--- a/rust/pin-init/internal/src/init.rs
+++ b/rust/pin-init/internal/src/init.rs
@@ -269,18 +269,17 @@ fn expand(
},
|(_, err)| Box::new(err),
);
- let (has_data_trait, get_data, init_from_closure) = if pinned {
+ let (get_pin_data, init_from_closure) = if pinned {
(
- format_ident!("HasPinData"),
- format_ident!("__pin_data"),
+ Some(
+ quote_spanned! { path.span().resolved_at(Span::mixed_site()) =>
+ let data = ::pin_init::__internal::HasPinData::__pin_data(data);
+ },
+ ),
format_ident!("pin_init_from_closure"),
)
} else {
- (
- format_ident!("HasInitData"),
- format_ident!("__init_data"),
- format_ident!("init_from_closure"),
- )
+ (None, format_ident!("init_from_closure"))
};
let init_kind = get_init_kind(rest, dcx);
let zeroable_check = match init_kind {
@@ -313,11 +312,14 @@ fn assert_zeroable<T: ?::core::marker::Sized>(_: *mut T)
Ok(quote_spanned! { Span::mixed_site() => {
// Get the data about fields from the supplied type.
let data = {
- use ::pin_init::__internal::#has_data_trait;
+ use ::pin_init::__internal::HasInitData;
// 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()
+ #path::__init_data()
};
+
+ #get_pin_data
+
// Ensure that `data` really is of type `data` and help with type inference:
let init = data.__make_closure::<_, #error>(
move |slot| {
diff --git a/rust/pin-init/internal/src/pin_data.rs b/rust/pin-init/internal/src/pin_data.rs
index 30d9b8b54d8a..a12e5a44a512 100644
--- a/rust/pin-init/internal/src/pin_data.rs
+++ b/rust/pin-init/internal/src/pin_data.rs
@@ -538,7 +538,7 @@ unsafe impl #impl_generics ::pin_init::__internal::HasPinData for #struct_name #
type PinData = __ThePinData #ty_generics;
#[inline]
- fn __pin_data() -> Self::PinData {
+ fn __pin_data(_: ::pin_init::__internal::InitData<Self>) -> Self::PinData {
__ThePinData { __phantom: ::pin_init::__internal::PhantomInvariant::new() }
}
}
diff --git a/rust/pin-init/src/__internal.rs b/rust/pin-init/src/__internal.rs
index 15eca4869bc3..f236db47d18b 100644
--- a/rust/pin-init/src/__internal.rs
+++ b/rust/pin-init/src/__internal.rs
@@ -86,7 +86,7 @@ pub unsafe fn new() -> Self {
pub unsafe trait HasPinData {
type PinData;
- fn __pin_data() -> Self::PinData;
+ fn __pin_data(_: InitData<Self>) -> Self::PinData;
}
/// This trait is automatically implemented for every type.
diff --git a/rust/pin-init/src/lib.rs b/rust/pin-init/src/lib.rs
index 4110590348c6..319485dc18ce 100644
--- a/rust/pin-init/src/lib.rs
+++ b/rust/pin-init/src/lib.rs
@@ -920,7 +920,8 @@ macro_rules! assert_pinned {
($ty:ty, $field:ident, $field_ty:ty, inline) => {
// SAFETY: This code is unreachable.
let _ = move |ptr: *mut $ty| unsafe {
- let data = <$ty as $crate::__internal::HasPinData>::__pin_data();
+ let data = <$ty as $crate::__internal::HasInitData>::__init_data();
+ let data = $crate::__internal::HasPinData::__pin_data(data);
_ = data
.$field(ptr)
.init($crate::__internal::AlwaysFail::<$field_ty>::new());
--
2.54.0
next prev parent reply other threads:[~2026-09-23 18:20 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-23 18:20 [PATCH 0/5] rust: pin-init: improve diagnostics of missing `#[pin_data]` and `#[pin]` Gary Guo
2026-09-23 18:20 ` [PATCH 1/5] rust: pin-init: internal: make `__init_data` and `__pin_data` safe Gary Guo
2026-09-23 18:20 ` [PATCH 2/5] rust: pin-init: internal: remove associated type of `HasInitData` Gary Guo
2026-09-23 18:20 ` Gary Guo [this message]
2026-09-23 18:20 ` [PATCH 4/5] rust: pin-init: internal: add custom diagnostic when `#[pin_data]` is not implemented Gary Guo
2026-09-23 18:20 ` [PATCH 5/5] rust: pin-init: add diagnostic attribute for `PinInit` and `Init` Gary Guo
2026-09-25 20:41 ` [PATCH 0/5] rust: pin-init: improve diagnostics of missing `#[pin_data]` and `#[pin]` Gary Guo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260923-dev-pin-data-diag-v1-3-e4d7193569e5@garyguo.net \
--to=gary@garyguo.net \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tamird@kernel.org \
--cc=tmgross@umich.edu \
--cc=work@onurozkan.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®