mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] rust: pin-init: internal: pin_data: use HRTB to work around `trivial_bounds` for `Unpin`
@ 2026-09-22 21:13 Gary Guo
  2026-09-25 11:43 ` Gary Guo
  0 siblings, 1 reply; 2+ messages in thread
From: Gary Guo @ 2026-09-22 21:13 UTC (permalink / raw)
  To: Benno Lossin, Gary Guo, Miguel Ojeda, Boqun Feng,
	Björn Roy Baron, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan
  Cc: rust-for-linux, linux-kernel

From: Gary Guo <gary@garyguo.net>

`#[pin_data]` generates a `Unpin` implementation for the user, which
requires reasoning using field types. This is rejected by rustc as "trivial
bounds", which can only be specified using the
`#![feature(trivial_bounds)]`.

Currently we use an extra lifetime in `__Unpin` to work around this; use
HRTB to introduce a dummy lifetime can achieve the same, which the
`Zeroable` implementation already uses.

Unify the `Unpin` impl to also use the same HRTB trick that `Zeroable`
uses. This produces slightly better error message and slightly shorter
expansion.

Signed-off-by: Gary Guo <gary@garyguo.net>
---
 rust/pin-init/internal/src/pin_data.rs | 35 +++++++++-----------------
 rust/pin-init/src/__internal.rs        | 16 ------------
 2 files changed, 12 insertions(+), 39 deletions(-)

diff --git a/rust/pin-init/internal/src/pin_data.rs b/rust/pin-init/internal/src/pin_data.rs
index 8cd9bf139567..55c627499b35 100644
--- a/rust/pin-init/internal/src/pin_data.rs
+++ b/rust/pin-init/internal/src/pin_data.rs
@@ -5,10 +5,10 @@
 use syn::{
     parse::{End, Nothing, Parse},
     parse_quote, parse_quote_spanned,
+    punctuated::Punctuated,
     spanned::Spanned,
     visit_mut::VisitMut,
     Field, Fields, Generics, Ident, Index, Item, Member, PathSegment, Type, TypePath, Visibility,
-    WhereClause,
 };
 
 use crate::{
@@ -231,21 +231,11 @@ fn generate_unpin_impl(
     generics: &Generics,
     fields: &[FieldInfo<'_>],
 ) -> TokenStream {
-    let (_, ty_generics, _) = generics.split_for_impl();
-    let mut generics_with_pin_lt = generics.clone();
-    generics_with_pin_lt.params.insert(0, parse_quote!('__pin));
-    generics_with_pin_lt.make_where_clause();
-    let (
-        impl_generics_with_pin_lt,
-        ty_generics_with_pin_lt,
-        Some(WhereClause {
-            where_token,
-            predicates,
-        }),
-    ) = generics_with_pin_lt.split_for_impl()
-    else {
-        unreachable!()
-    };
+    let (impl_generics, ty_generics, whr) = generics.split_for_impl();
+    let predicates = whr
+        .map(|x| &x.predicates)
+        .unwrap_or(const { &Punctuated::new() });
+
     let pinned_fields = fields.iter().filter(|f| f.pinned).map(|f| {
         let ident = f.member.as_ident();
         let ty = &f.field.ty;
@@ -260,19 +250,18 @@ fn generate_unpin_impl(
             dead_code, // The fields below are never used.
             non_snake_case // The warning will be emitted on the struct definition.
         )]
-        struct __Unpin #generics_with_pin_lt
-        #where_token
-            #predicates
+        struct __Unpin #generics #whr
         {
-            __phantom_pin: ::pin_init::__internal::PhantomInvariantLifetime<'__pin>,
             __phantom: ::pin_init::__internal::PhantomInvariant<#ident #ty_generics>,
             #(#pinned_fields),*
         }
 
         #[doc(hidden)]
-        impl #impl_generics_with_pin_lt ::core::marker::Unpin for #ident #ty_generics
-        #where_token
-            __Unpin #ty_generics_with_pin_lt: ::core::marker::Unpin,
+        impl #impl_generics ::core::marker::Unpin for #ident #ty_generics
+        where
+            // the `for<'__dummy>` HRTB makes this not error without the `trivial_bounds`
+            // feature <https://github.com/rust-lang/rust/issues/48214#issuecomment-2557829956>.
+            for<'__dummy> __Unpin #ty_generics: ::core::marker::Unpin,
             #predicates
         {}
     }
diff --git a/rust/pin-init/src/__internal.rs b/rust/pin-init/src/__internal.rs
index 8e9fd18b993f..67a354fa29c4 100644
--- a/rust/pin-init/src/__internal.rs
+++ b/rust/pin-init/src/__internal.rs
@@ -42,22 +42,6 @@ pub const fn new() -> Self {
     }
 }
 
-/// Zero-sized type used to mark a lifetime as invariant.
-///
-/// This is a polyfill for the [unstable type] in the standard library of the same name.
-///
-/// [unstable type]: https://doc.rust-lang.org/nightly/std/marker/struct.PhantomInvariantLifetime.html
-#[repr(transparent)]
-#[derive(Clone, Copy, Default)]
-pub struct PhantomInvariantLifetime<'a>(PhantomInvariant<&'a ()>);
-
-impl PhantomInvariantLifetime<'_> {
-    #[inline(always)]
-    pub const fn new() -> Self {
-        Self(PhantomInvariant::new())
-    }
-}
-
 /// Token type to signify successful initialization.
 ///
 /// Can only be constructed via the unsafe [`Self::new`] function. The initializer macros use this

base-commit: dfb6a037fd586f1ffcba3b143dab58f5c88294d1
-- 
2.54.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] rust: pin-init: internal: pin_data: use HRTB to work around `trivial_bounds` for `Unpin`
  2026-09-22 21:13 [PATCH] rust: pin-init: internal: pin_data: use HRTB to work around `trivial_bounds` for `Unpin` Gary Guo
@ 2026-09-25 11:43 ` Gary Guo
  0 siblings, 0 replies; 2+ messages in thread
From: Gary Guo @ 2026-09-25 11:43 UTC (permalink / raw)
  To: Gary Guo, Benno Lossin, Miguel Ojeda, Boqun Feng,
	Björn Roy Baron, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan
  Cc: rust-for-linux, linux-kernel

On Tue Sep 22, 2026 at 10:13 PM BST, Gary Guo wrote:
> From: Gary Guo <gary@garyguo.net>
>
> `#[pin_data]` generates a `Unpin` implementation for the user, which
> requires reasoning using field types. This is rejected by rustc as "trivial
> bounds", which can only be specified using the
> `#![feature(trivial_bounds)]`.
>
> Currently we use an extra lifetime in `__Unpin` to work around this; use
> HRTB to introduce a dummy lifetime can achieve the same, which the
> `Zeroable` implementation already uses.
>
> Unify the `Unpin` impl to also use the same HRTB trick that `Zeroable`
> uses. This produces slightly better error message and slightly shorter
> expansion.
>
> Signed-off-by: Gary Guo <gary@garyguo.net>

Applied to pin-init-next.

Best,
Gary

> ---
>  rust/pin-init/internal/src/pin_data.rs | 35 +++++++++-----------------
>  rust/pin-init/src/__internal.rs        | 16 ------------
>  2 files changed, 12 insertions(+), 39 deletions(-)

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-09-25 11:43 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-22 21:13 [PATCH] rust: pin-init: internal: pin_data: use HRTB to work around `trivial_bounds` for `Unpin` Gary Guo
2026-09-25 11:43 ` Gary Guo

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®