Thread (12 messages) 12 messages, 4 authors, 2026-02-27

Re: [RFC PATCH 0/7] Introduce HasField infrastructure

From: "Gary Guo" <gary@garyguo.net>
Date: 2026-02-04 14:20:15
Also in: lkml, rcu

On Wed Jan 28, 2026 at 9:53 PM GMT, Boqun Feng wrote:
Currently we have a few similar places where we use a `Has*` trait to
describe that a data structure has some types of field in it so that the
containing type can do something with it. There are also a `impl_has_*!`
macro to help implement the trait. While it's working, but it's less
ergonomic to me, especially considering the amount of the work we need
to do for something new (e.g. rcu_head).

Therefore here is the effort to unify them into a proc-macro based
solution. `Field` and `HasField` traits are introduced to generify the
"Has A" relationship, and a derive macro `#[derive(HasField)]` is also
added to support automatically implementing `HasField` trait.

This series convert a few users (Work, HrTimer) and introduce a new
`Field` type `RcuHead`. These improvements demonstrate how this
infrastructure can be used.

Some future work is still needed: using `HasField` for `DelayedWork` and
`ListLink` is still missing. Also it's possible to clean up `HasWork`
trait as well.

One known issue is that `#[derive(HasField)]` doesn't play alone with
`#[pin_data]` at the moment, for example:

    #[derive(HasField)]
    #[pin_data]
    struct Foo { .. }

works, but 

    #[pin_data]
    #[derive(HasField)]
    struct Foo { .. }

doesn't. Maybe it's by design or maybe something could be improved by
pin-init.


The patchset is based on today's rust/rust-next, top commit is:

	a7c013f77953 ('Merge patch series "refactor Rust proc macros with `syn`"')

Regards,
Boqun
Hi Boqun,

Thanks for working on this.

You currently divide things into two traits, `Field<T>` which doesn't seem to be
doing anything (actually, why does this need to exist at all?) and
`HasField<T, F>` which defines all the field projection.

For some prior art that attempts to have fields, e.g. my field-projection
experiemnt crate

    https://docs.rs/field-projection

and Benno's work on field-representing-types in the Rust language, we opt to
have a type to represent each field instead.

I think we should have a unified projection infrastructure in the kernel, for
both intrusive data structure and I/O projection and others, so I think it's
useful to have types representing fields (and projection in general, this could
also extend to the `register!` macro). For clarity, let me refer to this as
`field_of!(Base, foo)` and the trait is `Projection`.

With this infra, the `HasField` trait would simply looks like this:

    trait HasField<Base, FieldType> {
        type Field: Projection<Base = Base, Type = FieldType>;
    }

and the macro derive would generate something like

    impl HasField<MyStruct, Work<MyStruct>> {
        type Field = field_of!(MyStruct, name_of_work_field);
    }

Best,
Gary






Boqun Feng (7):
  rust: types: Introduce HasField trait and derive macro
  rust: time: hrtimer: Make `HasField` a super-trait of `HasHrTimer`
  rust: workqueue: Add HasField support for Work
  drivers: android: binder: Replace `impl_has_work!` with
    `#[derive(HasField)]`
  rust: sync: Completion: Replace `impl_has_work!` with
    `#[derive(HasField)]`
  rust: work: Remove `impl_has_work!`
  rust: sync: rcu: Introduce RcuHead

 drivers/android/binder/process.rs |   6 +-
 rust/kernel/field.rs              |  73 ++++++++++++++++++++
 rust/kernel/lib.rs                |   1 +
 rust/kernel/prelude.rs            |   4 +-
 rust/kernel/sync/completion.rs    |   8 +--
 rust/kernel/sync/rcu.rs           |  69 ++++++++++++++++++-
 rust/kernel/time/hrtimer.rs       |  70 ++++---------------
 rust/kernel/workqueue.rs          | 109 +++++++++++-------------------
 rust/macros/field.rs              |  85 +++++++++++++++++++++++
 rust/macros/lib.rs                |  11 +++
 10 files changed, 299 insertions(+), 137 deletions(-)
 create mode 100644 rust/kernel/field.rs
 create mode 100644 rust/macros/field.rs
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help