132 Commits
Author SHA1 Message Date
Gary Guo b6b9e6d4ab rust: pin-init: use irrefutable pattern for stack_pin_init
In Rust 1.100.0, `Infallible` will become an alias of `!`. The let
binding in `stack_pin_init` will thus become unreachable and produce
an "unreachable expression" warning for the subsequent match, and thus
will fail a `-Dwarnings` build. For this macro, all we need to know is
that the error type is uninhabited, so replace this with an irrefutable
pattern instead.

[ The error looks like (dummy reproducer):

      error: unreachable expression
         --> rust/kernel/sync.rs:177:5
          |
      177 |     pin_init::stack_pin_init!(let num = 42u32);
          |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          |     |
          |     unreachable expression
          |     any code following this expression is unreachable
          |
          = note: `-D unreachable-code` implied by `-D warnings`
          = help: to override `-D warnings` add `#[allow(unreachable_code)]`
          = note: this error originates in the macro `pin_init::stack_pin_init` (in Nightly builds, run with -Z macro-backtrace for more info)

    - Miguel ]

Reported-by: Mohamad Alsadhan <mo@sdhn.cc>
Closes: https://github.com/Rust-for-Linux/pin-init/pull/171
Signed-off-by: Gary Guo <gary@garyguo.net>
Cc: stable@vger.kernel.org # Needed in 7.1.y and later (for 6.12.y and 6.18.y a custom one is needed).
Link: https://patch.msgid.link/20260828155033.2101924-1-gary@kernel.org
[ Reworded for typos. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2026-09-01 01:27:55 +02:00
Gary Guo 1e26aea035 rust: pin-init: add #[inline] to small functions
Currently `pin-init` crate is missing many inline annotations. They are all
generic so still get inlined in normal builds, but are not inlined in
`-C opt-level=s` build. Mark these functions as `#[inline]` so they are
considered for inlining regardless.

Signed-off-by: Gary Guo <gary@garyguo.net>
2026-08-05 11:36:18 +01:00
Gary Guo 1f7fa1374d rust: pin-init: remove __pinned_init method for cfg(kernel)
Remove `__pinned_init` for kernel configuration, with all users gone.
Still perserve it temporarily as deprecated so other users have time to
move off it.

Link: https://patch.msgid.link/20260729-merge-init-v2-5-26adf47109e7@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-08-05 11:36:18 +01:00
Gary Guo d5492db2bf rust: pin-init: add raw_init and raw_try_init and recommend over __init
The `__init` method is not designed to be a public API (existence of "__"
is a hint for this); but currently there is no other API that allows raw
initialization on pointers. Add `raw_init` and `raw_try_init` and recommend
people to use this instead if raw pointer initialization is needed.

Link: https://patch.msgid.link/20260729-merge-init-v2-3-26adf47109e7@garyguo.net
[ Renamed from `ptr_[try_]init` to `raw_[try_]init`. - Gary ]
Reviewed-by: Benno Lossin <lossin@kernel.org>
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-08-05 11:36:16 +01:00
Gary Guo 91665820d9 rust: pin-init: merge __pinned_init and __init
These functions have the same requirements and are also required to execute
the same code. Prevent duplication by merging them to the single function
and document the additional relaxation of `Init::__init` on both the merged
function and the safety requirement of `Init`.

The existing `__pinned_init` function is deprecated and kept for
compatibility for existing users. For `cfg(kernel)`, it is soft-deprecated
for now and will be removed when all users are migrated.

Link: https://patch.msgid.link/20260729-merge-init-v2-2-26adf47109e7@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-08-03 13:36:42 +01:00
Gary Guo c998b661b7 rust: pin-init: examples: use Wrapper::pin_init instead of manual reimplementation
`UnsafeCell` gains the method via the extension trait `Wrapper`.

Link: https://patch.msgid.link/20260729-merge-init-v2-1-26adf47109e7@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-08-03 13:36:34 +01:00
Nicolás Antinori 6d0795b507 rust: pin-init: mark pin_init::zeroed and Zeroable::zeroed as #[inline]
The `pin_init::zeroed` function is a trivial wrapper around
`unsafe { core::mem::zeroed() }`, whereas `Zeroable::zeroed` is a trivial
wrapper around `pin_init::zeroed`. Mark them both as `#[inline]` to avoid
generating unnecessary symbols for them.

Signed-off-by: Nicolás Antinori <nico.antinori.7@gmail.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-07-27 11:52:08 +01:00
Nicolás Antinori 9e813b9abd rust: pin-init: docs: link Zeroable::zeroed and pin_init::zeroed in documentation
Modify the comments in the `pin_init::zeroed` and `Zeroable::zeroed`
functions to cross-reference each other and make developers aware of both
options.

This also adapts the example code in `Zeroable::zeroed` doc comments to use
that function.

Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/rust-for-linux/CANiq72kdCAyRUmXFcqQfkHpk1miG8Gagsn0_5U8p4WpKxv9d_g@mail.gmail.com/
Signed-off-by: Nicolás Antinori <nico.antinori.7@gmail.com>
[ Fix link. - Gary ]
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-07-27 11:52:08 +01:00
Gary Guo 5bbf2b2deb rust: pin-init: internal: rework how #[pin_data] handles cfg
Attribute macros are invoked without cfg being resolved. This adds quite a
bit complexity to the macro because all of the macro needs to be careful to
attach necessary cfgs. This becomes especially tricky for tuple structs.
Thus, it is convenient if cfgs are all resolved like derive macros.

The most optimal way to handle this is via `TokenStream::expand_expr`, but
that is still unstable. We can also create an internal derive macro and
transform the attribute macro invocation to be derive macro, but doing
requires us to serialize all extracted information in a form of helper
attributes; it would also make it more difficult if we want to make changes
to the struct (which the self-reference feature would need).

Implement an approach where we generate two cfg-gated macro invocations
with cfg resolved within the invocation. This would mean when the loop
falls through, all field cfgs are resolved, so remove all handling of
cfg_attrs for the rest of the macro.

Signed-off-by: Gary Guo <gary@garyguo.net>
2026-07-27 11:52:08 +01:00
Mirko Adzic 0c20f77a26 rust: pin-init: make [pin_]chain unwind safe
Add a drop guard before the call to the chained closure so that the value
initialized by the first stage is dropped if the closure errors or panics;
`mem::forget` the guard on success.

The previous code only ran cleanup on the explicit error path, leaking the
first-stage value if the chained closure panicked.

Reported-by: Gary Guo <gary@garyguo.net>
Closes: https://github.com/Rust-for-Linux/pin-init/issues/136
Suggested-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Mirko Adzic <adzicmirko97@gmail.com>
Link: https://patch.msgid.link/20260710-pin-init-sync-v1-7-8fa16cde87ae@garyguo.net
[ Fix Clippy missing safety comment false positive when `slot` and `guard`
  creation are merged in a single line. - Gary ]
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-07-13 12:11:44 +01:00
Mirko Adzic 7e4d9c946d rust: pin-init: make [pin_]init_array_from_fn unwind safe
The previous code only ran cleanup on the explicit error path. If the per-
element initializer panicked partway through, the elements already written
into the array would be leaked: their `Drop` impls would never run. This
violates the pinning requirement.

Fix the unwind safety issue by adding a guard type that drops element on
both error and panic path.

To avoid having to duplicate code between `pin_init_array_from_fn` and the
non-pin variant, extract the code to a shared `ArrayInit` type; this type
is internal and not visible via API.

Reported-by: Gary Guo <gary@garyguo.net>
Closes: https://github.com/Rust-for-Linux/pin-init/issues/136
Signed-off-by: Mirko Adzic <adzicmirko97@gmail.com>
Link: https://patch.msgid.link/20260710-pin-init-sync-v1-6-8fa16cde87ae@garyguo.net
[ Split guard type and the initializer type, move the guard type to be
  within __pinned_init. - Gary ]
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-07-13 12:11:29 +01:00
Gary Guo 751ecd5a19 rust: pin-init: internal: generate brace in macro for init code blocks
`init!` support interleaving code execution and initialization, and code
execution is done using `_: { ... }` syntax. If the code inside block is a
single statement, Rust may add a lint about unused braces, but the
suggestion will be incorrect as block is required by pin-init.

Currently we use `unused_brace` to suppress this, but this affect
everything nested inside as well. Use an alternative approach by generating
the block from the macro, then rustc will know to not emit the lint.

Reviewed-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20260710-pin-init-sync-v1-5-8fa16cde87ae@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-07-13 12:11:01 +01:00
Gary Guo c1722ae6fe rust: pin-init: internal: remove allow and expects that don't fire
Most warnings are suppressed from external macro expansions by default.
Thus remove `allow` and `expect`s for them.

Note that `unfulfilled_lint_expectations` is one of them too. This means
that all of our `expect`s inside macros do nothing, and actually mislead
people to the lints would be actually emitted without them.

Reviewed-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20260710-pin-init-sync-v1-4-8fa16cde87ae@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-07-13 12:10:05 +01:00
Gary Guo 690d82bf1d rust: pin-init: remove redundant clippy expects in doc tests
These lints are automatically suppressed inside doc tests. Previously this
is needed because kernel builds doc tests with the default set of clippy
flags; but now `clippy::disallowed_names` is globally allowed inside doc
tests.

Reviewed-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20260710-pin-init-sync-v1-3-8fa16cde87ae@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-07-13 12:10:00 +01:00
Gary Guo 554d1afffc rust: pin-init: examples: fix incorrect drop
Remove the drop and associated clippy allow. The warning reported by Clippy
here is genuine; the binding created is `Pin<&mut T>` so dropping it does
nothing. `stack_pin_init` created bindings are only dropped at the end of
scope.

Reviewed-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20260710-pin-init-sync-v1-2-8fa16cde87ae@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-07-13 12:09:41 +01:00
Luiz Georg f26f2f22c6 rust: pin-init: internal: error on duplicate #[pin] attribute
Duplicated `#[pin]` has no effect, thus error if misused.

Reported-by: Mohamad Alsadhan <mo@sdhn.cc>
Closes: https://github.com/Rust-for-Linux/pin-init/issues/119
Signed-off-by: Luiz Georg <luizgngeorg@gmail.com>
Link: https://patch.msgid.link/20260710-pin-init-sync-v1-1-8fa16cde87ae@garyguo.net
[ Reworded commit message, and change the logic so code generation still
  continue after reporting error - Gary ]
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-07-13 12:08:46 +01:00
Gary Guo d2f3092279 rust: pin_init: internal: use loop {} to produce never value
In the `init!`/`pin_init!` macros, we rely on a trick that assigns never
(`!`) values to all mentioned fields in never-executed code to let the
compiler check that all fields have been initialized.

Currently we use `::core::panic!()` to produce this value, but before Rust
1.91.0, it creates outlined `panic_cold_explicit` functions which do not
get removed by the optimizer, thus leaving dead code behind in the binary.
This has been fixed by [1], which lands in Rust 1.91.0+, higher than the
kernel minimum version 1.85.0.

This causes ~200 dead `panic_cold_explicit` instances being included in the
binary, with ~90 of them from nova-core's usage of pin-init.

Work around the issue by using `loop {}` which creates the never value
without macro expansion or function call at all. All instances of
`panic_cold_explicit` outside libcore are removed by this change in my
kernel build.

Link: https://github.com/rust-lang/rust/pull/145304 [1]
Link: https://patch.msgid.link/20260508152950.833635-1-gary@kernel.org
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-29 21:58:36 +01:00
Gary Guo f85906616e rust: pin-init: remove E from InitClosure
Move `E` from type to trait impl block. This greatly shortens the
monomorphized type names. The `__pinned_init` function name is only
slightly shortened as it still encodes the `E` as part of `PinInit<T, E>`
in the symbol.

`T` cannot be moved to trait impl block otherwise it will start to conflict
with the `impl Init<T> for T` as Rust cannot deduce that there're no types
that fulfill `T: FnOnce(*mut T)`.

Link: https://patch.msgid.link/20260527-pin-init-sync-v1-6-e20335ed2501@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-29 21:34:53 +01:00
Gary Guo 79bc923ae2 rust: pin-init: move InitClosure out from __internal
The `__internal` module is for exposing internal items publicly to
procedural macros (pin-init-internal). Types that are crate-local only can
just have proper visibility and does not need to be in `__internal`.

The type name of `InitClosure` can often shows up in symbol names, this
reduces the length slightly.

Link: https://patch.msgid.link/20260527-pin-init-sync-v1-5-e20335ed2501@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-29 21:34:53 +01:00
Xiaobo Liu 2a02b4f96f rust: pin-init: docs: fix typos in MaybeZeroable documentation
Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Link: https://patch.msgid.link/20260527-pin-init-sync-v1-4-e20335ed2501@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-29 21:34:53 +01:00
Mirko Adzic 5423ef9d4d rust: pin-init: internal: suppress non_snake_case lint in [pin_]init!
Allows `non_snake_case` lint on local variables generated in `[pin_]init!`.

Conceptually the identifiers in `[pin_]init!` just references the field
names, and are not defining them, so the warning should not be generated,
similar to how constructing a struct with non-snake-case field names do no
generate these warnings.

Reported-by: Gary Guo <gary@garyguo.net>
Closes: https://github.com/Rust-for-Linux/pin-init/issues/125
Closes: https://lore.kernel.org/rust-for-linux/DGTBJBIVFZ2K.2F1ZEFGY0G7NK@garyguo.net/
Fixes: 42415d163e ("rust: pin-init: add references to previously initialized fields")
Signed-off-by: Mirko Adzic <adzicmirko97@gmail.com>
[ Reworded commit message - Gary ]
Link: https://patch.msgid.link/20260527-pin-init-sync-v1-3-e20335ed2501@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-29 21:34:53 +01:00
Mirko Adzic e6405dca10 rust: pin-init: internal: suppress non_snake_case lint in #[pin_data]
Allows `non_snake_case` lint on struct fields generated by `#[pin_data]`.

Since the same warning will be reported by the compiler on the struct
definition, having extra warnings for the generated code is unnecessary
and confusing.

Signed-off-by: Mirko Adzic <adzicmirko97@gmail.com>
Link: https://patch.msgid.link/20260527-pin-init-sync-v1-2-e20335ed2501@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-29 21:34:53 +01:00
Martin Kletzander 28ba76f374 rust: pin-init: internal: pin_data: filter non-#[cfg] attr in generated code
When using a macro with custom attributes in a `#[pin_data]` struct it
can mess up the generated code. The generated code needs nothing more than
the `#[cfg]` attribute, thus strip away all other attributes.

[ Rebased and updated to only include `#[cfg]` instead of both `#[cfg]` and
  `#[doc]`; doc is not needed for the generated hidden items. - Gary ]

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Co-developed-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260527-pin-init-sync-v1-1-e20335ed2501@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-29 21:34:53 +01:00
Gary Guo 6fb5912c92 rust: pin-init: internal: project using full slot
Instead of projecting using pointer to a field project the full slot. This
further shifts the code generation from the initializer site to the struct
definition site, which means less code is generated overall.

It also makes the safety comment easier to justify, as now the projection
is done by the `#[pin_data]` macro which has full visibility of pinnedness
of fields.

The field alignment could also be checked on the `#[pin_data]` side;
however, since `init!()` macro works for other type of structs, we cannot
remove the alignment check from `init!`/`pin_init!` side anyway, so I opted
to still keep the alignment check in init.rs.

Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-18 12:21:28 +01:00
Gary Guo 5483a97dd2 rust: pin-init: internal: project slots instead of references
By projecting slots, the `pin_init!` and `init!` code path can be more
unified. This also reduces the amount of macro-generated code and shifts
them to the shared infrastructure.

Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-18 12:21:13 +01:00
Gary Guo 57b0a0d7e5 rust: pin-init: internal: make make_closure inherent methods
The `InitData` and `PinData` traits do not need to exist, the inference
helpers could be inherent methods instead.

There is no risk for calling the wrong methods even when user defines it,
as inherent methods take priority over trait methods.

With this change, it unlocks the possibility of attaching additional bounds
to the method per type, which is not possible for trait methods.

Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-18 12:18:06 +01:00
Gary Guo 27693a56e8 rust: pin-init: internal: use marker on drop guard type for pinned fields
Instead of projecting the created reference, simply create drop guards with
different marker types and have the `let_binding()` method of guards of
different marker produce different type instead.

This allows more flexible lifetime as this is now controlled by the guard.
This will be needed when implementing self-referential fields.

Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-18 12:18:06 +01:00
Gary Guo df1827babd rust: pin-init: internal: init: handle code blocks early
`InitializerKind::Code` is a special case where it does not initialize a
field, and thus generate no guard and accessors. Handle it earlier and make
the rest of the code more linear.

Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-18 12:18:06 +01:00
Gary Guo fea304ec87 rust: pin-init: internal: add PhantomInvariant and PhantomInvariantLifetime
Currently, the `pin_init` library has an `Invariant` type alias, and it is
instantiated using `PhantomData`. Generated code from `pin_data` on the
other hand cannot access the crate-local type alias, so it generates
`PhantomData<fn(T) -> T>` directly. This is all very inconsistent, despite
the exact same use case of ensuring invariance.

Add `PhantomInvariant` and `PhantomInvariantLifetime` and switch all users
that need to express the concept of invariance to use these. They're
polyfills of unstable types in the same names in the Rust standard library.

Link: https://patch.msgid.link/20260512-pin-init-sync-v1-3-81963130dfbd@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-14 20:18:14 +01:00
Mohamad Alsadhan 4b60f38cd2 rust: pin-init: internal: pin_data: add struct to record field info
Introduce `FieldInfo` struct to encapsulate field and other relevant data,
instead of carrying a pair of `(pinned, field)` in all places. This allows
us to add more information to the struct in the future.

Signed-off-by: Mohamad Alsadhan <mo@sdhn.cc>
Co-developed-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260512-pin-init-sync-v1-2-81963130dfbd@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-14 20:17:58 +01:00
Gary Guo 1e648c22ab rust: pin-init: internal: pin_data: use closure for handle_field
`handle_field` is currently a function, which precludes it from referencing
things in the scope of the parent function. Given that it's only called
once, inline its contents to the closure that invokes it instead, so it can
directly reference `struct_name` without having to pass in as argument.

Link: https://patch.msgid.link/20260512-pin-init-sync-v1-1-81963130dfbd@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-14 20:17:28 +01:00
Gary Guo 430654211d rust: pin-init: examples: fix useless_borrows_in_formatting clippy warning
Clippy 1.97 introduces new `useless_borrows_in_formatting` warning which
fires on the examples as we have `&*expr` where the format macro takes
reference already. Remove the extra borrow.

Link: https://patch.msgid.link/20260505115138.2466966-1-gary@kernel.org
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-10 23:00:51 +01:00
Gary Guo faed81945d rust: pin-init: internal: remove collect_tuple polyfill after MSRV bump
Tuples implement `FromIterator` since Rust 1.79. Remove the `collect_tuple`
polyfill now the MSRV is above 1.79.

To avoid over-identing the closure, I move the `Field` destructure from the
closure parameter to a let binding. This keeps the diff small.

Link: https://patch.msgid.link/20260501134445.3809731-1-gary@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-10 22:58:34 +01:00
Gary Guo e5cece9355 rust: pin-init: internal: turn PhantomPinned error into warnings
The `PhantomPinned` detection is just a lint, and is emitted as an error
because there is no `compile_warning!()` macro, and
`proc-macro-diagnostics` is not stable.

Use of `#[deprecated = ""]` attribute to approximate custom proc-macro
warnings. A new line is added before message for visual clarity.

An example warning with this trick looks like this:

    warning: use of deprecated function `_::warn`:
             The field `pin` of type `PhantomPinned` only has an effect if it has the `#[pin]` attribute
     --> test.rs:9:5
      |
    9 |     pin: marker::PhantomPinned,
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Suggested-by: Benno Lossin <lossin@kernel.org>
Link: https://github.com/Rust-for-Linux/pin-init/issues/51
Link: https://patch.msgid.link/20260428-pin-init-sync-v1-10-07f9bd3859fb@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-10 22:58:34 +01:00
Gary Guo 3dc01266cd rust: pin-init: cleanup workaround for old Rust compiler
The workaround mentions it's for Rust versions before 1.81. The minimum is
now 1.82, thus clean up.

Link: https://patch.msgid.link/20260428-pin-init-sync-v1-9-07f9bd3859fb@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-10 22:58:34 +01:00
Gary Guo 0ba33edb31 rust: pin-init: fix badge URL in README
The old CI workflow has been deleted ~1 year ago. Fix the URL to point to
the correct one.

Link: https://patch.msgid.link/20260428-pin-init-sync-v1-8-07f9bd3859fb@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-10 22:58:34 +01:00
Benno Lossin 38a07ef981 rust: pin-init: internal: adjust license identifier of zeroable.rs
The pin-init crate has been licensed under `Apache-2.0 OR MIT` since the
beginning. I introduced in commit 071cedc84e ("rust: add derive macro for
`Zeroable`") `zeroable.rs` with incompatible GPL-2.0 SPDX identifier. The
file has not been modified by other authors, so relicense it under the
above license.

Signed-off-by: Benno Lossin <lossin@kernel.org>
[ Reworded commit message - Gary ]
Link: https://patch.msgid.link/20260428-pin-init-sync-v1-7-07f9bd3859fb@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-10 22:58:34 +01:00
Gary Guo c64c793d9a rust: pin-init: internal: remove redundant #[pin] filtering
The `generate_projections` and `generate_the_pin_data` function already
receive filtered field lists, they do not need to filter out `#[pin]`
again.

Reviewed-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20260428-pin-init-sync-v1-6-07f9bd3859fb@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-10 22:58:34 +01:00
Mohamad Alsadhan 5edf8ac281 rust: pin-init: internal: add missing where clause to projection types
`#[pin_data]` failed to propagate the struct's `where` clause to the
generated projection struct. As a result, bounds written in a `where`
clause could be dropped during expansion, causing type errors when
fields depended on those bounds.

Fix this by adding the missing `where` clause to the generated
projection struct.

Reported-by: Andreas Hindborg <a.hindborg@kernel.org>
Closes: https://rust-for-linux.zulipchat.com/#narrow/channel/561532-pin-init/topic/generic.20bounds.20and.20.60.23.5Bpin_data.5D.60/with/578381591
Signed-off-by: Mohamad Alsadhan <mo@sdhn.cc>
Reviewed-by: Gary Guo <gary@garyguo.net>
[ Reworded commit message - Gary ]
Link: https://patch.msgid.link/20260428-pin-init-sync-v1-5-07f9bd3859fb@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-10 22:58:34 +01:00
Mohamad Alsadhan de54c2cb05 rust: pin-init: extend impl_zeroable_option macro to handle generics
Improve impl_zeroable_option macro to handle generic impls for types
like `&T`, `&mut T`, `NonNull<T>`, and others (for which `Option<T>`
is guaranteed to be zeroable) with similar approach to
`impl_zeroable`.

Also, update old declarations to use generics e.g. `NonZeroU8` to
`NonZero<u8>`.

Signed-off-by: Mohamad Alsadhan <mo@sdhn.cc>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260428-pin-init-sync-v1-4-07f9bd3859fb@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-10 22:58:33 +01:00
Mohamad Alsadhan 04828a538d rust: pin-init: cleanup Zeroable and ZeroableOptions
Place definitions and implementations (incl. macro invocations) of
the `Zeroable` trait first in the relevant section of `src/lib.rs`,
followed by the ZeroableOption trait and its implementations.

Rename `impl_non_zero_int_zeroable_option` to `impl_zeroable_option`
for consistency.

This commit should not introduce any functional changes.

Signed-off-by: Mohamad Alsadhan <mo@sdhn.cc>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260428-pin-init-sync-v1-3-07f9bd3859fb@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-10 22:58:33 +01:00
Gary Guo 531fdc2c34 rust: pin-init: bump minimum Rust version to 1.82
Following the kernel minimum version bump in commit f32fb9c58a ("rust:
bump Rust minimum supported version to 1.85.0 (Debian Trixie)"), bump
pin-init's minimum Rust version to 1.82.

This removes the `lint_reasons` feature which is stabilized in 1.81 and the
`raw_ref_ops` and `new_uninit` features which are stabilized in 1.82.

Given we do not use any features that are stabilized in 1.82..=1.85 range,
and pin-init crate is useful for other projects which may have their own
MSRV requirements, the minimum version is not straightly bumped to 1.85.

Reviewed-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20260428-pin-init-sync-v1-2-07f9bd3859fb@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-10 22:58:33 +01:00
Alistair Francis be7ea321a2 rust: pin-init: examples: mark as #[inline] all From::from()s for Error
There was a recent request in kernel [1] to mark as `#[inline]` the
simple `From::from()` functions implemented for `Error`.

Thus mark all of the existing

    impl From<...> for Error {
        fn from(err: ...) -> Self {
            ...
        }
    }

functions as `#[inline]`.

While in pin-init crate the relevant code is just examples, it
nevertheless does not hurt to use good practice for them.

Suggested-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/all/8403c8b7a832b5274743816eb77abfa4@garyguo.net/ [1]
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
[ Reworded commit message - Gary ]
Link: https://patch.msgid.link/20260428-pin-init-sync-v1-1-07f9bd3859fb@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
2026-05-10 22:58:33 +01:00
Gary Guo 68bf102226 rust: pin-init: fix incorrect accessor reference lifetime
When a field has been initialized, `init!`/`pin_init!` create a reference
or pinned reference to the field so it can be accessed later during the
initialization of other fields. However, the reference it created is
incorrectly `&'static` rather than just the scope of the initializer.

This means that you can do

    init!(Foo {
        a: 1,
        _: {
            let b: &'static u32 = a;
        }
    })

which is unsound.

This is caused by `&mut (*#slot).#ident`, which actually allows arbitrary
lifetime, so this is effectively `'static`. Somewhat ironically, the safety
justification of creating the accessor is.. "SAFETY: TODO".

Fix it by adding `let_binding` method on `DropGuard` to shorten lifetime.
This results in exactly what we want for these accessors. The safety and
invariant comments of `DropGuard` have been reworked; instead of reasoning
about what caller can do with the guard, express it in a way that the
ownership is transferred to the guard and `forget` takes it back, so the
unsafe operations within the `DropGuard` can be more easily justified.

Fixes: 42415d163e ("rust: pin-init: add references to previously initialized fields")
Cc: stable@vger.kernel.org
Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260427-pin-init-fix-v3-2-496a699674dd@garyguo.net
[ Reworded for missing word. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2026-04-30 22:43:32 +02:00
Gary Guo 83ac287031 rust: pin-init: internal: move alignment check to make_field_check
Instead of having the reference creation serving dual-purpose as both for
let bindings and alignment check, detangle them so that the alignment check
is done explicitly in `make_field_check`. This is more robust against
refactors that may change the way let bindings are created.

Cc: stable@vger.kernel.org
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260427-pin-init-fix-v3-1-496a699674dd@garyguo.net
[ Reworded for typo. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2026-04-30 22:43:28 +02:00
Antonio Hickey 09808839c7 rust: pin-init: replace addr_of_mut! with &raw mut
`feature(raw_ref_op)` became stable in Rust 1.82.0 which is the current
MSRV of pin-init with no default features. Earlier Rust versions will
now need to enable `raw_ref_op` to continue to work with pin-init.

This reduces visual complexity and improves consistency with existing
reference syntax.

Suggested-by: Benno Lossin <lossin@kernel.org>
Link: https://github.com/Rust-for-Linux/linux/issues/1148
Closes: https://github.com/Rust-for-Linux/pin-init/issues/99
Signed-off-by: Antonio Hickey <contact@antoniohickey.com>
Link: https://github.com/Rust-for-Linux/pin-init/commit/e27763004e2f6616b089437fbe9b3719cd72bd5c
[ Reworded commit message. - Benno ]
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260319093542.3756606-6-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
2026-03-25 10:57:53 +01:00
Hamdan-Khan aa9ec9460d rust: pin-init: implement ZeroableOption for NonZero* integer types
Add a macro for implementing `ZeroableOption` for `NonZero*` types.

`Option<NonZero*>` now automatically implements `Zeroable` trait  by
implementing `ZeroableOption` for `NonZero*` types, which serves as a
blanket impl.

Closes: https://github.com/Rust-for-Linux/pin-init/issues/95
Signed-off-by: Hamdan-Khan <hamdankhan212@gmail.com>
Link: https://github.com/Rust-for-Linux/pin-init/commit/74f772641cd9670848fa360f4ebfd20fdb40bf78
[ Fixed a typo in the commit message. - Benno ]
Link: https://patch.msgid.link/20260319093542.3756606-5-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
2026-03-25 10:57:33 +01:00
Gary Guo 44f6fa0dce rust: pin-init: doc: de-clutter documentation with fake-variadics
Currently the doc for `Zeroable` and `ZeroableOption` are filled with the
generated impl of tuples and fn pointers. Use the internal
"fake_variadics" feature to improve the rendered quality.

This makes use of an internal feature, however this is of minimal risk as
it's for documentation only, not activated during normal build, gated
behind `USE_RUSTC_FEATURES`, and can be removed at any time. This feature
is already used by serde and bevy to improve documentation quality.

For compilers that cannot use this feature, we still hide most generated
impls, and the existence of them are hinted by doc comments on the single
non-hidden impl.

Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://github.com/Rust-for-Linux/pin-init/commit/530c4eb79a449599e219821f9397f03250cc2aa4
[ Reordered `#[doc]` attributes and safety comments to avoid errors in
  older versions of clippy. - Benno ]
Link: https://patch.msgid.link/20260319093542.3756606-4-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
2026-03-25 10:57:16 +01:00
Benno Lossin 960c37cbcb rust: pin-init: properly document let binding workaround
The three let bindings (in the bodies of `cast_init`, `cast_pin_init`
and the `init!` macro) are used to avoid the following compiler error in
Rust 1.78.0, 1.79.0, 1.80.0, 1.80.1, and 1.81.0 (just showing the one
for `cast_init`, the others are similar):

    error[E0391]: cycle detected when computing type of opaque `cast_init::{opaque#0}`
        --> src/lib.rs:1160:66
         |
    1160 | pub const unsafe fn cast_init<T, U, E>(init: impl Init<T, E>) -> impl Init<U, E> {
         |                                                                  ^^^^^^^^^^^^^^^
         |
    note: ...which requires borrow-checking `cast_init`...
        --> src/lib.rs:1160:1
         |
    1160 | pub const unsafe fn cast_init<T, U, E>(init: impl Init<T, E>) -> impl Init<U, E> {
         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    note: ...which requires const checking `cast_init`...
        --> src/lib.rs:1160:1
         |
    1160 | pub const unsafe fn cast_init<T, U, E>(init: impl Init<T, E>) -> impl Init<U, E> {
         | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         = note: ...which requires computing whether `cast_init::{opaque#0}` is freeze...
         = note: ...which requires evaluating trait selection obligation `cast_init::{opaque#0}: core::marker::Freeze`...
         = note: ...which again requires computing type of opaque `cast_init::{opaque#0}`, completing the cycle
    note: cycle used when computing type of `cast_init::{opaque#0}`
        --> src/lib.rs:1160:66
         |
    1160 | pub const unsafe fn cast_init<T, U, E>(init: impl Init<T, E>) -> impl Init<U, E> {
         |                                                                  ^^^^^^^^^^^^^^^
         = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

Once we raise the nightly-MSRV above 1.81, we can remove this
workaround.

Link: https://github.com/Rust-for-Linux/pin-init/commit/bb3e96f3e9a4f5fca80a22af883c7e5aa90f0893
[ Moved this commit after the previous one to avoid a build failure due
  to unstable features. Changed the cfg to use `USE_RUSTC_FEAUTURES`.
  - Benno ]
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260319093542.3756606-3-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
2026-03-25 10:56:53 +01:00
Gary Guo 002a121b16 rust: pin-init: build: simplify use of nightly features
We use some features that are already stable in later versions of Rust,
but only available as unstable features in older Rust versions that the
kernel needs to support.

Instead of checking if a feature is already stable, simply enable them
and allow the warning if the feature is already stable. This avoids the
need of hardcoding whether a feature has been stabilized at a given
version.

`#[feature(...)]` is used when cfg `USE_RUSTC_FEATURES` is enabled. The
build script automatically does this when a nightly compiler is detected
or `RUSTC_BOOTSTRAP` is set.

Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://github.com/Rust-for-Linux/pin-init/commit/885c5d83d7eb778a796d4a17380a0898b0d0a571
[ Added kernel build system changes to always enable USE_RUSTC_FEATURES.
  Moved this commit earlier (swapped with the next one) to avoid a build
  error. - Benno ]
Link: https://patch.msgid.link/20260319093542.3756606-2-lossin@kernel.org
Signed-off-by: Benno Lossin <lossin@kernel.org>
2026-03-25 10:56:16 +01:00