| Age | Commit message (Collapse) | Author |
|
Organize parsing and generation into two separate phases, with a single
`StructInfo` in the middle. This allows analysis and processing to happen
with a single struct and avoid having to pass different information into
the token stream generation functions.
A drawback of this approach is that as we consume the `Fields`, we cannot
expand the original struct using `quote!(#struct_)` anymore, and the field
needs to be re-constructed in `generate_struct_def` function. However, this
is only a temporary drawback, as the upcoming pin-init self-referential
feature will require modification of the generated struct anyway.
Acked-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20261006-dev-selfref-dep-v1-8-da716f740d6d@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
"pin" is a very overloaded word in pin-init. For the generated projection
structs, the lifetime refer to that of the whole struct, so rename the
lifetime used in expansion from `'__pin` to `'__this` instead.
The `__pin_phantom_data` field is renamed to `__this` for the same reason
and for clarity purpose, capture a `PhantomData` of the mutable reference
to the struct.
Acked-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20261006-dev-selfref-dep-v1-7-da716f740d6d@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
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>
|
|
()` block
Most users would not need to mention the generated projection struct. With
the upcoming self-referential support, there needs to be additional
projection structs. Instead of give them publicly visible names, simply
make the name not publicly accessible.
A heavy user of pin projection outside kernel is for async programming.
I've checked tokio codebase there is a single use case and that's for
enums.
Acked-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20261006-dev-selfref-dep-v1-5-da716f740d6d@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
More attributes are to be added which has the requirement that they should
only be specified once. Add a utility code to extract attributes for a
specific path and report error when appeared multiple times.
Convert `#[pin]` parsing to use the added utility.
Acked-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20261006-dev-selfref-dep-v1-4-da716f740d6d@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
There're many cases where we want to merge multiple generics together.
Currently this is done by cloning generics and modifying it, making the
code less readable.
Add a utility code that allow printing multiple generics together, ensuring
correct ordering between lifetime and other parameters.
Acked-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20261006-dev-selfref-dep-v1-3-da716f740d6d@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
Set the span location of the guards to point to the identifier. The
generated diagnostic is still not ideal, as ideally it points the place
where the identifier is used rather than the identifier name in
initializer, but is still an improvement to status quo.
Before the change:
error[E0505]: cannot move out of value because it is borrowed
--> tests/ui/compile-fail/init/accessor_lifetime.rs:8:13
|
8 | let _ = init!(Foo {
| _____________^
9 | | x: 0,
10 | | _: {
11 | | let _: &'static usize = x;
| | -------------- type annotation requires that borrow lasts for `'static`
12 | | },
13 | | });
| | ^
| | |
| |______move out of value occurs here
| borrow of value occurs here
After the change:
error[E0505]: cannot move out of value because it is borrowed
--> tests/ui/compile-fail/init/accessor_lifetime.rs:9:9
|
9 | x: 0,
| ^
| |
| move out of value occurs here
| borrow of value occurs here
10 | _: {
11 | let _: &'static usize = x;
| -------------- type annotation requires that borrow lasts for `'static`
Acked-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20261006-dev-selfref-dep-v1-2-da716f740d6d@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
Currently, the forget order is the same as initialization order, this is
the wrong way around compared to their drop order when going out-of-scope.
The wrong order will cause borrow checker errors if there are lifetime
dependencies between the guards. This does not matter for now because there
cannot be any lifetime dependency; it would matter for self-referential
borrows.
Reverse the order to be consistent with their out-of-scope drop order.
Acked-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20261006-dev-selfref-dep-v1-1-da716f740d6d@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
Currently we use the full span of the field initializer as the span of the
generated init call. This produces overlapping spans for type mismatch
errors, which is hard to read.
Use the span of `<-` or `:` for the method name, which wll cause type
mismatch errors or trait bound not implemented error to be appear from the
`<-` or `:` token, which declutter the output a bit and make it easier to
read.
Before the change:
error[E0277]: `impl pin_init::PinInit<Bar>` cannot be used to movably initialize `Bar` with error `_`
--> tests/ui/compile-fail/init/invalid_init.rs:19:16
|
19 | bar <- Bar::new(),
| -------^^^^^^^^^^
| | |
| | the trait `Init<Bar, _>` is not implemented for `impl pin_init::PinInit<Bar>`
| required by a bound introduced by this call
|
= note: if your type implements `PinInit` but not `Init`, you might be forgetting a `#[pin]` annotation on fields
After the change:
error[E0277]: `impl pin_init::PinInit<Bar>` cannot be used to movably initialize `Bar` with error `_`
--> tests/ui/compile-fail/init/invalid_init.rs:19:16
|
19 | bar <- Bar::new(),
| -- ^^^^^^^^^^ the trait `Init<Bar, _>` is not implemented for `impl pin_init::PinInit<Bar>`
| |
| required by a bound introduced by this call
|
= note: if your type implements `PinInit` but not `Init`, you might be forgetting a `#[pin]` annotation on fields
Suggested-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20260928-dev-pin-init-sync-v1-3-e591c8e9cf0e@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
Use span of the field name for generated alignment and field duplication
checks. This avoids pointing diagnostics to the full macro invocation, but
just the part of it going wrong.
Before the change:
error[E0062]: field `0` specified more than once
--> tests/ui/compile-fail/init/tuple_duplicate_field.rs:7:37
|
7 | let _ = pin_init!(Tuple { 0: 1, 0: 2, 1: 3 });
| ------------------------^------------
| | |
| | used more than once
| first use of `0`
After the change:
error[E0062]: field `0` specified more than once
--> tests/ui/compile-fail/init/tuple_duplicate_field.rs:7:37
|
7 | let _ = pin_init!(Tuple { 0: 1, 0: 2, 1: 3 });
| - ^ used more than once
| |
| first use of `0`
Link: https://patch.msgid.link/20260928-dev-pin-init-sync-v1-2-e591c8e9cf0e@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
Use `let mut` for created bindings of initialized field, so `Pin<&mut T>`
bindings may be reborrowed in subsequent initializers or code blocks.
Without `let mut`, attempt to reborrow can produce error (and also a
confusing fix):
error[E0596]: cannot borrow `gpu` as mutable, as it is not declared as mutable
--> drivers/gpu/nova-core/driver.rs:129:17
|
129 | gpu.as_mut().run_selftests(pdev);
| ^^^ cannot borrow as mutable
|
help: consider changing this to be mutable |
119 | mut gpu <- Gpu::new(
| +++
error: aborting due to 1 previous error
Reported-by: Danilo Krummrich <dakr@kernel.org>
Closes: https://lore.kernel.org/nova-gpu/DLQXWXRP3P1J.28SLFOJJQ2EDK@kernel.org/
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Tested-by: Danilo Krummrich <dakr@kernel.org>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
Link: https://patch.msgid.link/20260928-dev-pin-init-sync-v1-1-e591c8e9cf0e@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
Currently, if proc macro panicked, the diagnostics clean up is not
executed, and further invocation will cause the "DiagCtxt cannot be nested"
error. While we should aim to have no panics inside proc macros, producing
a sensible diagnostics message even when macro panicked is very useful for
developing.
Thus, catch proc macro panics and convert them to errors, and emit them
together with all diagnostics accumulated so far.
Ideally we would like panic location w/ line numbers being available as
well; however this is not currently implementable without overriding the
global panic hook.
Reviewed-by: Benno Lossin <lossin@kernel.org>
Link: https://patch.msgid.link/20260923140618.1978181-3-gary@kernel.org
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>
|
|
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 {
| ^^^^^^^^^^
Link: https://patch.msgid.link/20260923-dev-pin-data-diag-v1-3-e4d7193569e5@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
Remove the unsafe markers of `__init_data` and `__pin_data`. These methods
are for inference help and does not need to be unsafe.
The `HasInitData` cannot be implemented outside pin-init, so the `unsafe
trait` marker is not necessary.
Link: https://patch.msgid.link/20260923-dev-pin-data-diag-v1-1-e4d7193569e5@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
for `Unpin`
`#[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.
Link: https://patch.msgid.link/20260922211320.1390159-1-gary@kernel.org
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
Use the span of `Index` for generated identifiers, so diagnostics can point
to the span of the index.
Link: https://patch.msgid.link/20260916184131.435059-1-gary@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
When initializing a field, pin-init first projects the full slot to a slot
of the field, then initialize it by invoking a method. Currently the span
location is not explicitly set, so the error message points to the full
macro invocation.
Improve it by provide a span, so Rust will point to the specific fields
causing the error when type check fails.
Old error message:
error[E0308]: mismatched types
--> tests/ui/compile-fail/init/field_value_wrong_type.rs:8:28
|
8 | let _ = init!(Foo { a: () });
| ---------------^^---
| | |
| | expected `usize`, found `()`
| arguments to this method are incorrect
New error message:
error[E0308]: mismatched types
--> tests/ui/compile-fail/init/field_value_wrong_type.rs:8:28
|
8 | let _ = init!(Foo { a: () });
| ---^^
| | |
| | expected `usize`, found `()`
| arguments to this method are incorrect
Link: https://patch.msgid.link/20260916-dev-hygiene-v1-3-dfb6ae2588ba@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
Use `quote_spanned!(Span::mixed_site() => ...)` directly instead of
creating `slot` identifier and interpolate it later. Do the same for
`__data`, too.
This is needed so that we can customize the location of the span without
having the `slot` identifier getting in the way. For example:
quote_spanned!(Span::mixed_site().located_at(loc) => ...)
with `slot` mentioned directly will have the diagnostic pointing to the
desired location, while `#slot` won't.
Link: https://patch.msgid.link/20260916-dev-hygiene-v1-2-dfb6ae2588ba@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
Syn/quote's default is the call site hygiene. If user provides a field
named `slot`, it will conflict with pin-init generated `slot` identifier.
Change it to use mixed site hygiene instead.
Fixes: 4883830e9784 ("rust: pin-init: rewrite the initializer macros using `syn`")
Link: https://patch.msgid.link/20260916-dev-hygiene-v1-1-dfb6ae2588ba@garyguo.net
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>
|
|
Extend the initializer syntax so that a field can be named by an index,
addressing tuple struct fields the same way a struct expression does:
pin_init!(Foo { 0: value, 1 <- initializer })
Tuple fields are not exposed by a `let` binding to the fields after them,
since they have no name to bind; `_0` would shadow a user variable.
Signed-off-by: Mohamad Alsadhan <mo@sdhn.cc>
[ Fixed incorrect index calculation and cleaned up the code - Gary ]
Link: https://patch.msgid.link/20260904-tuple-struct-v1-3-72c50bd037fd@garyguo.net
Signed-off-by: Gary Guo <gary@garyguo.net>
|
|
`#[pin_data]` rejects tuple structs because it assumes every field has a
name, which it uses for the projection field, the `__Unpin` field and the
pin-data accessor.
Identify fields by `syn::Member` instead, so that tuple fields are referred
to by their index in generated field accesses. The names that generated
items still need are derived from the index as `_0`, `_1`, etc.
The projection of a tuple struct is a tuple struct itself, so projected
fields are accessed with the same `.0`, `.1` syntax as on the input
type rather than through synthesised names.
Signed-off-by: Mohamad Alsadhan <mo@sdhn.cc>
[ Moved utility code to util.rs as extension trait - Gary ]
Link: https://patch.msgid.link/20260904-tuple-struct-v1-2-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>
|
|
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>
|
|
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>
|
|
`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>
|
|
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>
|
|
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>
|
|
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>
|
|
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: 42415d163e5d ("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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
`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>
|
|
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>
|
|
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>
|
|
`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>
|
|
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>
|
|
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>
|
|
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>
|
|
The pin-init crate has been licensed under `Apache-2.0 OR MIT` since the
beginning. I introduced in commit 071cedc84e90 ("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>
|
|
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>
|
|
`#[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>
|
|
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>
|
|
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: 42415d163e5d ("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>
|