diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-02-10 11:53:01 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-02-10 11:53:01 -0800 |
| commit | a9aabb3b839aba094ed80861054993785c61462c (patch) | |
| tree | 4fde2eb2606fe9fc6aa8b598bafb63a3a71c36e4 /rust/pin-init/internal/src/lib.rs | |
| parent | f144367d012929326f15a399394a9a8be4f98acb (diff) | |
| parent | b8d687c7eeb52d0353ac27c4f71594a2e6aa365f (diff) | |
Merge tag 'rust-6.20-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux
Pull rust updates from Miguel Ojeda:
"Toolchain and infrastructure:
- Add '__rust_helper' annotation to the C helpers
This is needed to inline these helpers into Rust code
- Remove imports available via the prelude, treewide
This was possible thanks to a new lint in Klint that Gary has
implemented -- more Klint-related changes, including initial
upstream support, are coming
- Deduplicate pin-init flags
'kernel' crate:
- Add support for calling a function exactly once with the new
'do_once_lite!' macro (and 'OnceLite' type)
Based on this, add 'pr_*_once!' macros to print only once
- Add 'impl_flags!' macro for defining common bitflags operations:
impl_flags!(
/// Represents multiple permissions.
#[derive(Debug, Clone, Default, Copy, PartialEq, Eq)]
pub struct Permissions(u32);
/// Represents a single permission.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Permission {
/// Read permission.
Read = 1 << 0,
/// Write permission.
Write = 1 << 1,
/// Execute permission.
Execute = 1 << 2,
}
);
let mut f: Permissions = Permission::Read | Permission::Write;
assert!(f.contains(Permission::Read));
assert!(!f.contains(Permission::Execute));
f |= Permission::Execute;
assert!(f.contains(Permission::Execute));
let f2: Permissions = Permission::Write | Permission::Execute;
assert!((f ^ f2).contains(Permission::Read));
assert!(!(f ^ f2).contains(Permission::Write));
- 'bug' module: support 'CONFIG_DEBUG_BUGVERBOSE_DETAILED' in the
'warn_on!' macro in order to show the evaluated condition alongside
the file path:
------------[ cut here ]------------
WARNING: [val == 1] linux/samples/rust/rust_minimal.rs:27 at ...
Modules linked in: rust_minimal(+)
- Add safety module with 'unsafe_precondition_assert!' macro,
currently a wrapper for 'debug_assert!', intended to mark the
validation of safety preconditions where possible:
/// # Safety
///
/// The caller must ensure that `index` is less than `N`.
unsafe fn set_unchecked(&mut self, index: usize, value: T) {
unsafe_precondition_assert!(
index < N,
"set_unchecked() requires index ({index}) < N ({N})"
);
...
}
- Add instructions to 'build_assert!' documentation requesting to
always inline functions when used with function arguments
- 'ptr' module: replace 'build_assert!' with a 'const' one
- 'rbtree' module: reduce unsafe blocks on pointer derefs
- 'transmute' module: implement 'FromBytes' and 'AsBytes' for
inhabited ZSTs, and use it in Nova
- More treewide replacements of 'c_str!' with C string literals
'macros' crate:
- Rewrite most procedural macros ('module!', 'concat_idents!',
'#[export]', '#[vtable]', '#[kunit_tests]') to use the 'syn'
parsing library which we introduced last cycle, with better
diagnostics
This also allows to support '#[cfg]' properly in the '#[vtable]'
macro, to support arbitrary types in 'module!' macro (not just an
identifier) and to remove several custom parsing helpers we had
- Use 'quote!' from the recently vendored 'quote' library and remove
our custom one
The vendored one also allows us to avoid quoting '"' and '{}'
inside the template anymore and editors can now highlight it. In
addition, it improves robustness as it eliminates the need for
string quoting and escaping
- Use 'pin_init::zeroed()' to simplify KUnit code
'pin-init' crate:
- Rewrite all procedural macros ('[pin_]init!', '#[pin_data]',
'#[pinned_drop]', 'derive([Maybe]Zeroable)') to use the 'syn'
parsing library which we introduced last cycle, with better
diagnostics
- Implement 'InPlaceWrite' for '&'static mut MaybeUninit<T>'. This
enables users to use external allocation mechanisms such as
'static_cell'
- Support tuple structs in 'derive([Maybe]Zeroable)'
- Support attributes on fields in '[pin_]init!' (such as
'#[cfg(...)]')
- Add a '#[default_error(<type>)]' attribute to '[pin_]init!' to
override the default error (when no '? Error' is specified)
- Support packed structs in '[pin_]init!' with
'#[disable_initialized_field_access]'
- Remove 'try_[pin_]init!' in favor of merging their feature with
'[pin_]init!'. Update the kernel's own 'try_[pin_]init!' macros to
use the 'default_error' attribute
- Correct 'T: Sized' bounds to 'T: ?Sized' in the generated
'PinnedDrop' check by '#[pin_data]'
Documentation:
- Conclude the Rust experiment
MAINTAINERS:
- Add "RUST [RUST-ANALYZER]" entry for the rust-analyzer support.
Tamir and Jesung will take care of it. They have both been active
around it for a while. The new tree will flow through the Rust one
- Add Gary as maintainer for "RUST [PIN-INIT]"
- Update Boqun and Tamir emails to their kernel.org accounts
And a few other cleanups and improvements"
* tag 'rust-6.20-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: (59 commits)
rust: safety: introduce `unsafe_precondition_assert!` macro
rust: add `impl_flags!` macro for defining common bitflag operations
rust: print: Add pr_*_once macros
rust: bug: Support DEBUG_BUGVERBOSE_DETAILED option
rust: print: Add support for calling a function exactly once
rust: kbuild: deduplicate pin-init flags
gpu: nova-core: remove imports available via prelude
rust: clk: replace `kernel::c_str!` with C-Strings
MAINTAINERS: Update my email address to @kernel.org
rust: macros: support `#[cfg]` properly in `#[vtable]` macro.
rust: kunit: use `pin_init::zeroed` instead of custom null value
rust: macros: rearrange `#[doc(hidden)]` in `module!` macro
rust: macros: allow arbitrary types to be used in `module!` macro
rust: macros: convert `#[kunit_tests]` macro to use `syn`
rust: macros: convert `concat_idents!` to use `syn`
rust: macros: convert `#[export]` to use `syn`
rust: macros: use `quote!` for `module!` macro
rust: macros: use `syn` to parse `module!` macro
rust: macros: convert `#[vtable]` macro to use `syn`
rust: macros: use `quote!` from vendored crate
...
Diffstat (limited to 'rust/pin-init/internal/src/lib.rs')
| -rw-r--r-- | rust/pin-init/internal/src/lib.rs | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/rust/pin-init/internal/src/lib.rs b/rust/pin-init/internal/src/lib.rs index 297b0129a5bf..08372c8f65f0 100644 --- a/rust/pin-init/internal/src/lib.rs +++ b/rust/pin-init/internal/src/lib.rs @@ -7,48 +7,54 @@ //! `pin-init` proc macros. #![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))] -// Allow `.into()` to convert -// - `proc_macro2::TokenStream` into `proc_macro::TokenStream` in the user-space version. -// - `proc_macro::TokenStream` into `proc_macro::TokenStream` in the kernel version. -// Clippy warns on this conversion, but it's required by the user-space version. -// -// Remove once we have `proc_macro2` in the kernel. -#![allow(clippy::useless_conversion)] // Documentation is done in the pin-init crate instead. #![allow(missing_docs)] use proc_macro::TokenStream; +use syn::parse_macro_input; -#[cfg(kernel)] -#[path = "../../../macros/quote.rs"] -#[macro_use] -#[cfg_attr(not(kernel), rustfmt::skip)] -mod quote; -#[cfg(not(kernel))] -#[macro_use] -extern crate quote; +use crate::diagnostics::DiagCtxt; -mod helpers; +mod diagnostics; +mod init; mod pin_data; mod pinned_drop; mod zeroable; #[proc_macro_attribute] -pub fn pin_data(inner: TokenStream, item: TokenStream) -> TokenStream { - pin_data::pin_data(inner.into(), item.into()).into() +pub fn pin_data(args: TokenStream, input: TokenStream) -> TokenStream { + let args = parse_macro_input!(args); + let input = parse_macro_input!(input); + DiagCtxt::with(|dcx| pin_data::pin_data(args, input, dcx)).into() } #[proc_macro_attribute] pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream { - pinned_drop::pinned_drop(args.into(), input.into()).into() + let args = parse_macro_input!(args); + let input = parse_macro_input!(input); + DiagCtxt::with(|dcx| pinned_drop::pinned_drop(args, input, dcx)).into() } #[proc_macro_derive(Zeroable)] pub fn derive_zeroable(input: TokenStream) -> TokenStream { - zeroable::derive(input.into()).into() + let input = parse_macro_input!(input); + DiagCtxt::with(|dcx| zeroable::derive(input, dcx)).into() } #[proc_macro_derive(MaybeZeroable)] pub fn maybe_derive_zeroable(input: TokenStream) -> TokenStream { - zeroable::maybe_derive(input.into()).into() + let input = parse_macro_input!(input); + DiagCtxt::with(|dcx| zeroable::maybe_derive(input, dcx)).into() +} +#[proc_macro] +pub fn init(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input); + DiagCtxt::with(|dcx| init::expand(input, Some("::core::convert::Infallible"), false, dcx)) + .into() +} + +#[proc_macro] +pub fn pin_init(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input); + DiagCtxt::with(|dcx| init::expand(input, Some("::core::convert::Infallible"), true, dcx)).into() } |
