| Age | Commit message (Collapse) | Author |
|
function
The `pin_data` function is getting big. Split the `#[cfg]` handling which
does not interact with other part of expansion to its own `expand_with_cfg`
function.
Acked-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20261006-dev-selfref-dep-v1-6-da716f740d6d@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
Currently, there is a split between `syn::Error` and pin-init's custom
`DiagCtxt`. Parsing has no access to `DiagCtxt` and therefore cannot report
diagnostics without failing the parse. Bridge the gap by making the
`DiagCtxt` available inside parsers using `thread_local!`.
`parse_macro_input!` returns error as token stream directly, so it is no
longer suitable when the parsing is moved inside `DiagCtxt` closure. Add a
`From<syn::Error> for ErrorGuaranteed` implementation so `?` can be used to
add a `syn::Error` into the current diagnostic context and obtain a
`ErrorGuaranteed`.
Clean up the handler of using `<-` inside tuple expression as a
demonstration of the usefulness of having `DiagCtxt` access inside `Parse`.
Reviewed-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20260923140618.1978181-2-gary@kernel.org
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
Currently `DiagCtxt` is used to allow error recovery in the pin-init
macros, by generating both a `compile_error!()` macro item and continue
expansion, and then merge token streams together. This works very well for
items, however for expressions, this will produce invalid expression and
result in a confusing error message.
error: macro expansion ignores `::` and any tokens following
--> tests/ui/compile-fail/zeroable/invalid_spread.rs:15:9
|
13 | let _ = init!(Foo {
| _____________-
14 | | a: 0,
15 | | ..MyZeroable::init_zeroed()
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
16 | | });
| |______- caused by the macro expansion here
|
= note: the usage of `init!` is likely invalid in expression context
Fix this by wrap the concatenated diagnostics in a block, with the
generated expression in its tail position. This results in the desired
error message.
error: expected nothing or `..Zeroable::init_zeroed()`.
--> tests/ui/compile-fail/zeroable/invalid_spread.rs:15:9
|
15 | ..MyZeroable::init_zeroed()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Reviewed-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20260923140618.1978181-1-gary@kernel.org
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
A tuple struct whose fields are all set to a value reads better written
like a call to its constructor than with the indices spelled out:
pin_init!(Foo(value, value))
Parse the two forms into separate types and rewrite the constructor
arguments into the indexed fields they are shorthand for, so that only the
parser has to know about the second form.
The arguments have no names, so they cannot use `<-`. Parse it anyway and
reject it afterwards, which reports the position of every offending `<-`
rather than stopping at the first one.
`cfg` needs different treatment for tuple constructor syntax. As non-derive
proc macros are invoked before cfg is resolved, the macro cannot know
whether a field survives, and dropping a tuple field renumbers every field
after it. That cannot be expressed by attaching a `cfg` attribute to the
initializer of a single field. Thus, resolve tuple field cfgs up front
instead, by generating two cfg-gated invocations of the macro with one
field resolved in each. This is the approach of commit 5bbf2b2deb94 ("rust:
pin-init: internal: rework how `#[pin_data]` handles cfg"), and it is
linear time because only one of the two branches is ever expanded. Struct
expression syntax do not renumber, so using tuple structs with struct
syntax can keep using the existing attribute-based handling.
Suggested-by: Gary Guo <gary@garyguo.net>
Link: https://github.com/Rust-for-Linux/pin-init/pull/165
Signed-off-by: Mohamad Alsadhan <mo@sdhn.cc>
[ Pre-expand cfgs for tuple init syntax. Use generics instead of separate
types for normalization - Gary ]
Co-developed-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260904-tuple-struct-v1-4-72c50bd037fd@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
Create a new `util.rs` to host utility code that are generic and can be
shared by multiple macros.
Link: https://patch.msgid.link/20260904-tuple-struct-v1-1-72c50bd037fd@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
Following the kernel minimum version bump in commit f32fb9c58a5b ("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>
|
|
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>
|
|
Rewrite the initializer macros `[pin_]init!` using `syn`. No functional
changes intended aside from improved error messages on syntactic and
semantical errors. For example if one forgets to use `<-` with an
initializer (and instead uses `:`):
impl Bar {
fn new() -> impl PinInit<Self> { ... }
}
impl Foo {
fn new() -> impl PinInit<Self> {
pin_init!(Self { bar: Bar::new() })
}
}
Then the declarative macro would report:
error[E0308]: mismatched types
--> tests/ui/compile-fail/init/colon_instead_of_arrow.rs:21:9
|
14 | fn new() -> impl PinInit<Self> {
| ------------------ the found opaque type
...
21 | pin_init!(Self { bar: Bar::new() })
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| expected `Bar`, found opaque type
| arguments to this function are incorrect
|
= note: expected struct `Bar`
found opaque type `impl pin_init::PinInit<Bar>`
note: function defined here
--> $RUST/core/src/ptr/mod.rs
|
| pub const unsafe fn write<T>(dst: *mut T, src: T) {
| ^^^^^
= note: this error originates in the macro `$crate::__init_internal` which comes from the expansion of the macro `pin_init` (in Nightly builds, run with -Z macro-backtrace for more info)
And the new error is:
error[E0308]: mismatched types
--> tests/ui/compile-fail/init/colon_instead_of_arrow.rs:21:31
|
14 | fn new() -> impl PinInit<Self> {
| ------------------ the found opaque type
...
21 | pin_init!(Self { bar: Bar::new() })
| --- ^^^^^^^^^^ expected `Bar`, found opaque type
| |
| arguments to this function are incorrect
|
= note: expected struct `Bar`
found opaque type `impl pin_init::PinInit<Bar>`
note: function defined here
--> $RUST/core/src/ptr/mod.rs
|
| pub const unsafe fn write<T>(dst: *mut T, src: T) {
| ^^^^^
Importantly, this error gives much more accurate span locations,
pointing to the offending field, rather than the entire macro
invocation.
Tested-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Benno Lossin <lossin@kernel.org>
|
|
Rewrite the attribute macro `#[pin_data]` using `syn`. No functional
changes intended aside from improved error messages on syntactic and
semantical errors. For example if one forgets a comma at the end of a
field:
#[pin_data]
struct Foo {
a: Box<Foo>
b: Box<Foo>
}
The declarative macro reports the following errors:
error: expected `,`, or `}`, found `b`
--> tests/ui/compile-fail/pin_data/missing_comma.rs:5:16
|
5 | a: Box<Foo>
| ^ help: try adding a comma: `,`
error: recursion limit reached while expanding `$crate::__pin_data!`
--> tests/ui/compile-fail/pin_data/missing_comma.rs:3:1
|
3 | #[pin_data]
| ^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`$CRATE`)
= note: this error originates in the macro `$crate::__pin_data` which comes from the expansion of the attribute macro `pin_data` (in Nightly builds, run with -Z macro-backtrace for more info)
The new `syn` version reports:
error: expected `,`, or `}`, found `b`
--> tests/ui/compile-fail/pin_data/missing_comma.rs:5:16
|
5 | a: Box<Foo>
| ^ help: try adding a comma: `,`
error: expected `,`
--> tests/ui/compile-fail/pin_data/missing_comma.rs:6:5
|
6 | b: Box<Foo>
| ^
Tested-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Benno Lossin <lossin@kernel.org>
|
|
Rewrite the attribute macro for implementing `PinnedDrop` using `syn`.
Otherwise no functional changes intended aside from improved error
messages on syntactic and semantical errors. For example:
When missing the `drop` function in the implementation, the old error
was:
error: no rules expected `)`
--> tests/ui/compile-fail/pinned_drop/no_fn.rs:6:1
|
6 | #[pinned_drop]
| ^^^^^^^^^^^^^^ no rules expected this token in macro call
|
note: while trying to match keyword `fn`
--> src/macros.rs
|
| fn drop($($sig:tt)*) {
| ^^
= note: this error originates in the attribute macro `pinned_drop` (in Nightly builds, run with -Z macro-backtrace for more info)
And the new one is:
error[E0046]: not all trait items implemented, missing: `drop`
--> tests/ui/compile-fail/pinned_drop/no_fn.rs:7:1
|
7 | impl PinnedDrop for Foo {}
| ^^^^^^^^^^^^^^^^^^^^^^^ missing `drop` in implementation
|
= help: implement the missing item: `fn drop(self: Pin<&mut Self>, _: OnlyCallFromDrop) { todo!() }`
Tested-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Benno Lossin <lossin@kernel.org>
|
|
`syn`
Rewrite the two derive macros for `Zeroable` using `syn`. One positive
side effect of this change is that tuple structs are now supported by
them. Additionally, syntax errors and the error emitted when trying to
use one of the derive macros on an `enum` are improved. Otherwise no
functional changes intended.
For example:
#[derive(Zeroable)]
enum Num {
A(u32),
B(i32),
}
Produced this error before this commit:
error: no rules expected keyword `enum`
--> tests/ui/compile-fail/zeroable/enum.rs:5:1
|
5 | enum Num {
| ^^^^ no rules expected this token in macro call
|
note: while trying to match keyword `struct`
--> src/macros.rs
|
| $vis:vis struct $name:ident
| ^^^^^^
Now the error is:
error: cannot derive `Zeroable` for an enum
--> tests/ui/compile-fail/zeroable/enum.rs:5:1
|
5 | enum Num {
| ^^^^
error: cannot derive `Zeroable` for an enum
Tested-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Benno Lossin <lossin@kernel.org>
|
|
The API is similar to diagnostics handling in rustc and uses a
`ErrorGuaranteed` value to signify that an error has been emitted. It
supports both fatal errors (which abort the macro expansion immediately
by returning `Err(ErrorGuaranteed)`) and non-fatal ones at generation
time. These errors are appended to the token stream after generation has
finished normally. This allows giving good errors while still expanding
most of the code as expected to avoid the user encountering additional
errors (for example missing definitions).
Suggested-by: Gary Guo <gary@garyguo.net>
Tested-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
[ remove duplicate word in commit message - Benno ]
Signed-off-by: Benno Lossin <lossin@kernel.org>
|
|
workarounds
`syn` makes parsing Rust from proc-macros a lot simpler. `pin-init` has
not used `syn` up until now, because the we did not support it. That
changed in commit 54e3eae85562 ("Merge patch series "`syn` support""),
so we can finally utilize the added ergonomics of parsing proc-macro
input with `syn`.
Previously we only had the `proc-macro` library available, whereas the
user-space version also used `proc-macro2` and `quote`. Now both are
available, so remove the workarounds.
Due to these changes, clippy emits warnings about unnecessary
`.to_string()` as `proc-macro2` provides an additional `PartialEq` impl
on `Ident`, so the warnings are fixed.
[ Adjusted wording from upstream version and added build system changes
for the kernel - Benno ]
Co-developed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Tamir Duberstein <tamird@gmail.com>
Tested-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Benno Lossin <lossin@kernel.org>
|
|
This derive macro implements `Zeroable` for structs & unions precisely
if all fields also implement `Zeroable` and does nothing otherwise. The
plain `Zeroable` derive macro instead errors when it cannot derive
`Zeroable` safely. The `MaybeZeroable` derive macro is useful in cases
where manual checking is infeasible such as with the bindings crate.
Move the zeroable generics parsing into a standalone function in order
to avoid code duplication between the two derive macros.
Link: https://github.com/Rust-for-Linux/pin-init/pull/42/commits/1165cdad1a391b923efaf30cf76bc61e38da022e
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
|
|
The `quote` module only is available in the kernel and thus running
`cargo fmt` or `rustfmt internal/src/lib.rs` in the user-space
repository [1] results in:
error: couldn't read `~/pin-init/internal/src/../../../macros/quote.rs`: No such file or directory (os error 2)
--> ~/pin-init/internal/src/lib.rs:25:1
|
25 | mod quote;
| ^^^^^^^^^^
Error writing files: failed to resolve mod `quote`: ~/pin-init/internal/src/../../../macros/quote.rs does not exist
Thus mark it with `rustfmt::skip` when compiling without kernel support.
Link: https://github.com/Rust-for-Linux/pin-init [1]
Link: https://github.com/Rust-for-Linux/pin-init/pull/33/commits/a6caf1945e51da38761aab4dffa56e63e2baa218
Link: https://lore.kernel.org/all/20250414195928.129040-2-benno.lossin@proton.me
Reviewed-by: Christian Schrefl <chrisi.schrefl@gmail.com>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
|
|
Remove the last differences between the kernel version and the
user-space version.
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Tested-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Fiona Behrens <me@kloenk.dev>
Link: https://lore.kernel.org/r/20250308110339.2997091-20-benno.lossin@proton.me
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
|
|
Synchronize the internal macros crate with the user-space version that
uses the quote crate [1] instead of a custom `quote!` macro. The imports
in the different version are achieved using `cfg` on the kernel config
value. This cfg is always set in the kernel and never set in the
user-space version.
Since the quote crate requires the proc_macro2 crate, imports also need
to be adjusted and `.into()` calls have to be inserted.
Link: https://crates.io/crates/quote [1]
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Tested-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Fiona Behrens <me@Kloenk.dev>
Link: https://lore.kernel.org/r/20250308110339.2997091-19-benno.lossin@proton.me
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
|
|
Rename relative paths inside of the crate to still refer to the same
items, also rename paths inside of the kernel crate and adjust the build
system to build the crate.
[ Remove the `expect` (and thus the `lint_reasons` feature) since
the tree now uses `quote!` from `rust/macros/export.rs`. Remove the
`TokenStream` import removal, since it is now used as well.
In addition, temporarily (i.e. just for this commit) use an `--extern
force:alloc` to prevent an unknown `new_uninit` error in the `rustdoc`
target. For context, please see a similar case in:
https://lore.kernel.org/lkml/20240422090644.525520-1-ojeda@kernel.org/
And adjusted the message above. - Miguel ]
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Fiona Behrens <me@kloenk.dev>
Tested-by: Andreas Hindborg <a.hindborg@kernel.org>
Link: https://lore.kernel.org/r/20250308110339.2997091-16-benno.lossin@proton.me
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
|
|
Add infrastructure for moving the initialization API to its own crate.
Covers all make targets such as `rust-analyzer` and `rustdoc`. The tests
of pin-init are not added to `rusttest`, as they are already tested in
the user-space repository [1].
Link: https://github.com/Rust-for-Linux/pin-init [1]
Co-developed-by: Benno Lossin <benno.lossin@proton.me>
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Tested-by: Andreas Hindborg <a.hindborg@kernel.org>
Link: https://lore.kernel.org/r/20250308110339.2997091-15-benno.lossin@proton.me
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
|
|
Move the documentation of proc-macros from pin-init-internal into
pin-init. This is because documentation can only reference types from
dependencies and pin-init-internal cannot have pin-init as a dependency,
as that would be cyclic.
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Fiona Behrens <me@kloenk.dev>
Tested-by: Andreas Hindborg <a.hindborg@kernel.org>
Link: https://lore.kernel.org/r/20250308110339.2997091-5-benno.lossin@proton.me
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
|
|
In preparation of splitting off the pin-init crate from the kernel
crate, move all pin-init API code (including proc-macros) into
`rust/pin-init`.
Moved modules have their import path adjusted via the `#[path = "..."]`
attribute. This allows the files to still be imported in the kernel
crate even though the files are in different directories.
Code that is moved out of files (but the file itself stays where it is)
is imported via the `include!` macro. This also allows the code to be
moved while still being part of the kernel crate.
Note that this commit moves the generics parsing code out of the GPL-2.0
file `rust/macros/helpers.rs` into the Apache-2.0 OR MIT file
`rust/pin_init/internal/src/helpers.rs`. I am the sole author of that
code and it already is available with that license at [1].
The same is true for the entry-points of the proc-macros `pin_data`,
`pinned_drop` and `derive_zeroable` in `rust/macros/lib.rs` that are
moved to `rust/pin_data/internal/src/lib.rs`. Although there are some
smaller patches that fix the doctests.
Link: https://github.com/Rust-for-Linux/pinned-init [1]
Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Fiona Behrens <me@kloenk.dev>
Tested-by: Andreas Hindborg <a.hindborg@kernel.org>
Link: https://lore.kernel.org/r/20250308110339.2997091-3-benno.lossin@proton.me
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
|