* [PATCH v4] rust: make `build_assert` module the home of related macros
@ 2026-06-09 14:26 Gary Guo
2026-06-09 17:19 ` Miguel Ojeda
0 siblings, 1 reply; 2+ messages in thread
From: Gary Guo @ 2026-06-09 14:26 UTC (permalink / raw)
To: Danilo Krummrich, Alexandre Courbot, Alice Ryhl, David Airlie,
Simona Vetter, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Trevor Gross, Daniel Almeida, FUJITA Tomonori, Yury Norov,
Will Deacon, Peter Zijlstra, Mark Rutland, Ingo Molnar,
Waiman Long, Tamir Duberstein
Cc: nova-gpu, dri-devel, linux-kernel, rust-for-linux, driver-core,
netdev
From: Gary Guo <gary@garyguo.net>
Given the macro scoping rules, all macros are rendered twice, in the
module and in the top-level of kernel crate.
Add `#[doc(no_inline)]` to the prelude so it just shows up as re-export.
Add `#[doc(hidden)]` to the macro definition and `#[doc(inline)]` to the
re-export inside `build_assert` module so the top-level items are hidden.
Acked-by: Danilo Krummrich <dakr@kernel.org>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Acked-by: Alexandre Courbot <acourbot@nvidia.com>
Acked-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
Acked-by: Boqun Feng <boqun@kernel.org>
Signed-off-by: Gary Guo <gary@garyguo.net>
---
This is the remaining unapplied patch from
https://lore.kernel.org/rust-for-linux/20260319121653.2975748-1-gary@kernel.org/.
Changes:
- Rebased so it applies cleanly. (both on linux-next and rust-next)
- Picked up tags
- Updated commit message to reflect that my other patch "rust: doc: disable
doc inlining for all prelude items" already reduce number of rendering
times from 3 to 2.
---
drivers/gpu/nova-core/bitfield.rs | 4 ++--
drivers/gpu/nova-core/num.rs | 2 +-
rust/kernel/build_assert.rs | 19 ++++++++++++-------
rust/kernel/io/register.rs | 19 ++++++++++++-------
rust/kernel/io/resource.rs | 2 +-
rust/kernel/ioctl.rs | 2 +-
rust/kernel/net/phy/reg.rs | 8 +++++---
rust/kernel/num/bounded.rs | 2 +-
rust/kernel/prelude.rs | 12 ++++++++----
rust/kernel/sync/atomic/internal.rs | 9 ++++++---
rust/kernel/sync/atomic/predefine.rs | 2 +-
rust/kernel/sync/locked_by.rs | 2 +-
rust/kernel/sync/refcount.rs | 8 +++++---
rust/kernel/xarray.rs | 10 ++++++++--
14 files changed, 64 insertions(+), 37 deletions(-)
diff --git a/drivers/gpu/nova-core/bitfield.rs b/drivers/gpu/nova-core/bitfield.rs
index 02efdcf78d89..660c3911402d 100644
--- a/drivers/gpu/nova-core/bitfield.rs
+++ b/drivers/gpu/nova-core/bitfield.rs
@@ -170,7 +170,7 @@ impl $name {
(@check_field_bounds $hi:tt:$lo:tt $field:ident as bool) => {
#[allow(clippy::eq_op)]
const _: () = {
- ::kernel::build_assert!(
+ ::kernel::build_assert::build_assert!(
$hi == $lo,
concat!("boolean field `", stringify!($field), "` covers more than one bit")
);
@@ -181,7 +181,7 @@ impl $name {
(@check_field_bounds $hi:tt:$lo:tt $field:ident as $type:tt) => {
#[allow(clippy::eq_op)]
const _: () = {
- ::kernel::build_assert!(
+ ::kernel::build_assert::build_assert!(
$hi >= $lo,
concat!("field `", stringify!($field), "`'s MSB is smaller than its LSB")
);
diff --git a/drivers/gpu/nova-core/num.rs b/drivers/gpu/nova-core/num.rs
index 6c824b8d7b97..6eb174d136ab 100644
--- a/drivers/gpu/nova-core/num.rs
+++ b/drivers/gpu/nova-core/num.rs
@@ -49,7 +49,7 @@ macro_rules! impl_safe_as {
#[allow(unused)]
#[inline(always)]
pub(crate) const fn [<$from _as_ $into>](value: $from) -> $into {
- kernel::static_assert!(size_of::<$into>() >= size_of::<$from>());
+ ::kernel::build_assert::static_assert!(size_of::<$into>() >= size_of::<$from>());
value as $into
}
diff --git a/rust/kernel/build_assert.rs b/rust/kernel/build_assert.rs
index 2ea2154ec30c..c3acb9b68a65 100644
--- a/rust/kernel/build_assert.rs
+++ b/rust/kernel/build_assert.rs
@@ -61,15 +61,16 @@
//! undefined symbols and linker errors, it is not developer friendly to debug, so it is recommended
//! to avoid it and prefer other two assertions where possible.
+#[doc(inline)]
pub use crate::{
- build_assert,
+ build_assert_macro as build_assert,
build_error,
const_assert,
static_assert, //
};
#[doc(hidden)]
-pub use build_error::build_error;
+pub use build_error::build_error as build_error_fn;
/// Static assert (i.e. compile-time assert).
///
@@ -105,6 +106,7 @@
/// static_assert!(f(40) == 42, "f(x) must add 2 to the given input.");
/// ```
#[macro_export]
+#[doc(hidden)]
macro_rules! static_assert {
($condition:expr $(,$arg:literal)?) => {
const _: () = ::core::assert!($condition $(,$arg)?);
@@ -133,6 +135,7 @@ macro_rules! static_assert {
/// }
/// ```
#[macro_export]
+#[doc(hidden)]
macro_rules! const_assert {
($condition:expr $(,$arg:literal)?) => {
const { ::core::assert!($condition $(,$arg)?) };
@@ -157,12 +160,13 @@ macro_rules! const_assert {
/// // foo(usize::MAX); // Fails to compile.
/// ```
#[macro_export]
+#[doc(hidden)]
macro_rules! build_error {
() => {{
- $crate::build_assert::build_error("")
+ $crate::build_assert::build_error_fn("")
}};
($msg:expr) => {{
- $crate::build_assert::build_error($msg)
+ $crate::build_assert::build_error_fn($msg)
}};
}
@@ -200,15 +204,16 @@ macro_rules! build_error {
/// const _: () = const_bar(2);
/// ```
#[macro_export]
-macro_rules! build_assert {
+#[doc(hidden)]
+macro_rules! build_assert_macro {
($cond:expr $(,)?) => {{
if !$cond {
- $crate::build_assert::build_error(concat!("assertion failed: ", stringify!($cond)));
+ $crate::build_assert::build_error_fn(concat!("assertion failed: ", stringify!($cond)));
}
}};
($cond:expr, $msg:expr) => {{
if !$cond {
- $crate::build_assert::build_error($msg);
+ $crate::build_assert::build_error_fn($msg);
}
}};
}
diff --git a/rust/kernel/io/register.rs b/rust/kernel/io/register.rs
index 388647f28292..f924c7c7c1db 100644
--- a/rust/kernel/io/register.rs
+++ b/rust/kernel/io/register.rs
@@ -108,9 +108,10 @@
use core::marker::PhantomData;
-use crate::io::IoLoc;
-
-use kernel::build_assert;
+use crate::{
+ build_assert::build_assert,
+ io::IoLoc, //
+};
/// Trait implemented by all registers.
pub trait Register: Sized {
@@ -872,7 +873,7 @@ macro_rules! register {
@reg $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty)
[ $size:expr, stride = $stride:expr ] @ $offset:literal { $($fields:tt)* }
) => {
- ::kernel::static_assert!(::core::mem::size_of::<$storage>() <= $stride);
+ $crate::build_assert::static_assert!(::core::mem::size_of::<$storage>() <= $stride);
$crate::register!(@bitfield $(#[$attr])* $vis struct $name($storage) { $($fields)* });
$crate::register!(@io_base $name($storage) @ $offset);
@@ -895,7 +896,9 @@ macro_rules! register {
@reg $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) => $alias:ident [ $idx:expr ]
{ $($fields:tt)* }
) => {
- ::kernel::static_assert!($idx < <$alias as $crate::io::register::RegisterArray>::SIZE);
+ $crate::build_assert::static_assert!(
+ $idx < <$alias as $crate::io::register::RegisterArray>::SIZE
+ );
$crate::register!(@bitfield $(#[$attr])* $vis struct $name($storage) { $($fields)* });
$crate::register!(
@@ -912,7 +915,7 @@ macro_rules! register {
[ $size:expr, stride = $stride:expr ]
@ $base:ident + $offset:literal { $($fields:tt)* }
) => {
- ::kernel::static_assert!(::core::mem::size_of::<$storage>() <= $stride);
+ $crate::build_assert::static_assert!(::core::mem::size_of::<$storage>() <= $stride);
$crate::register!(@bitfield $(#[$attr])* $vis struct $name($storage) { $($fields)* });
$crate::register!(@io_base $name($storage) @ $offset);
@@ -938,7 +941,9 @@ macro_rules! register {
@reg $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty)
=> $base:ident + $alias:ident [ $idx:expr ] { $($fields:tt)* }
) => {
- ::kernel::static_assert!($idx < <$alias as $crate::io::register::RegisterArray>::SIZE);
+ $crate::build_assert::static_assert!(
+ $idx < <$alias as $crate::io::register::RegisterArray>::SIZE
+ );
$crate::register!(@bitfield $(#[$attr])* $vis struct $name($storage) { $($fields)* });
$crate::register!(
diff --git a/rust/kernel/io/resource.rs b/rust/kernel/io/resource.rs
index b7ac9faf141d..17b0c174cfc5 100644
--- a/rust/kernel/io/resource.rs
+++ b/rust/kernel/io/resource.rs
@@ -229,7 +229,7 @@ impl Flags {
// Always inline to optimize out error path of `build_assert`.
#[inline(always)]
const fn new(value: u32) -> Self {
- crate::build_assert!(value as u64 <= c_ulong::MAX as u64);
+ build_assert!(value as u64 <= c_ulong::MAX as u64);
Flags(value as c_ulong)
}
}
diff --git a/rust/kernel/ioctl.rs b/rust/kernel/ioctl.rs
index 2fc7662339e5..5bb5b48cf949 100644
--- a/rust/kernel/ioctl.rs
+++ b/rust/kernel/ioctl.rs
@@ -6,7 +6,7 @@
#![expect(non_snake_case)]
-use crate::build_assert;
+use crate::build_assert::build_assert;
/// Build an ioctl number, analogous to the C macro of the same name.
#[inline(always)]
diff --git a/rust/kernel/net/phy/reg.rs b/rust/kernel/net/phy/reg.rs
index a7db0064cb7d..80e22c264ea8 100644
--- a/rust/kernel/net/phy/reg.rs
+++ b/rust/kernel/net/phy/reg.rs
@@ -9,9 +9,11 @@
//! defined in IEEE 802.3.
use super::Device;
-use crate::build_assert;
-use crate::error::*;
-use crate::uapi;
+use crate::{
+ build_assert::build_assert,
+ error::*,
+ uapi, //
+};
mod private {
/// Marker that a trait cannot be implemented outside of this crate
diff --git a/rust/kernel/num/bounded.rs b/rust/kernel/num/bounded.rs
index f9f90d6ec482..dafe77782d79 100644
--- a/rust/kernel/num/bounded.rs
+++ b/rust/kernel/num/bounded.rs
@@ -364,7 +364,7 @@ pub fn try_new(value: T) -> Option<Self> {
// Always inline to optimize out error path of `build_assert`.
#[inline(always)]
pub fn from_expr(expr: T) -> Self {
- crate::build_assert!(
+ crate::build_assert::build_assert!(
fits_within(expr, N),
"Requested value larger than maximal representable value."
);
diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs
index ca260cc3937a..f6e852638ade 100644
--- a/rust/kernel/prelude.rs
+++ b/rust/kernel/prelude.rs
@@ -79,9 +79,6 @@
VVec,
Vec, //
},
- build_assert,
- build_error,
- const_assert,
current,
dev_alert,
dev_crit,
@@ -105,7 +102,6 @@
pr_info,
pr_notice,
pr_warn,
- static_assert,
str::CStrExt as _,
try_init,
try_pin_init,
@@ -113,6 +109,14 @@
ThisModule, //
};
+#[doc(no_inline)]
+pub use crate::build_assert::{
+ build_assert,
+ build_error,
+ const_assert,
+ static_assert, //
+};
+
// `super::std_vendor` is hidden, which makes the macro inline for some reason.
#[doc(no_inline)]
pub use super::dbg;
diff --git a/rust/kernel/sync/atomic/internal.rs b/rust/kernel/sync/atomic/internal.rs
index ad810c2172ec..9c8a7a203abd 100644
--- a/rust/kernel/sync/atomic/internal.rs
+++ b/rust/kernel/sync/atomic/internal.rs
@@ -4,8 +4,11 @@
//!
//! Provides 1:1 mapping to the C atomic operations.
-use crate::bindings;
-use crate::macros::paste;
+use crate::{
+ bindings,
+ build_assert::static_assert,
+ macros::paste, //
+};
use core::cell::UnsafeCell;
use ffi::c_void;
@@ -46,7 +49,7 @@ pub trait AtomicImpl: Sized + Copy + private::Sealed {
// In the future when a CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=n architecture plans to support Rust, the
// load/store helpers that guarantee atomicity against RmW operations (usually via a lock) need to
// be added.
-crate::static_assert!(
+static_assert!(
cfg!(CONFIG_ARCH_SUPPORTS_ATOMIC_RMW),
"The current implementation of atomic i8/i16/ptr relies on the architecure being \
ARCH_SUPPORTS_ATOMIC_RMW"
diff --git a/rust/kernel/sync/atomic/predefine.rs b/rust/kernel/sync/atomic/predefine.rs
index 7468153429e1..adc5fa126487 100644
--- a/rust/kernel/sync/atomic/predefine.rs
+++ b/rust/kernel/sync/atomic/predefine.rs
@@ -2,7 +2,7 @@
//! Pre-defined atomic types
-use crate::static_assert;
+use crate::prelude::*;
use core::mem::{align_of, size_of};
use ffi::c_void;
diff --git a/rust/kernel/sync/locked_by.rs b/rust/kernel/sync/locked_by.rs
index 61f100a45b35..fb4a1430b3b4 100644
--- a/rust/kernel/sync/locked_by.rs
+++ b/rust/kernel/sync/locked_by.rs
@@ -3,7 +3,7 @@
//! A wrapper for data protected by a lock that does not wrap it.
use super::{lock::Backend, lock::Lock};
-use crate::build_assert;
+use crate::build_assert::build_assert;
use core::{cell::UnsafeCell, mem::size_of, ptr};
/// Allows access to some data to be serialised by a lock that does not wrap it.
diff --git a/rust/kernel/sync/refcount.rs b/rust/kernel/sync/refcount.rs
index 6c7ae8b05a0b..23a5d201f343 100644
--- a/rust/kernel/sync/refcount.rs
+++ b/rust/kernel/sync/refcount.rs
@@ -4,9 +4,11 @@
//!
//! C header: [`include/linux/refcount.h`](srctree/include/linux/refcount.h)
-use crate::build_assert;
-use crate::sync::atomic::Atomic;
-use crate::types::Opaque;
+use crate::{
+ build_assert::build_assert,
+ sync::atomic::Atomic,
+ types::Opaque, //
+};
/// Atomic reference counter.
///
diff --git a/rust/kernel/xarray.rs b/rust/kernel/xarray.rs
index 46e5f43223fe..987c9c0c2198 100644
--- a/rust/kernel/xarray.rs
+++ b/rust/kernel/xarray.rs
@@ -5,10 +5,16 @@
//! C header: [`include/linux/xarray.h`](srctree/include/linux/xarray.h)
use crate::{
- alloc, bindings, build_assert,
+ alloc,
+ bindings,
+ build_assert::build_assert,
error::{Error, Result},
ffi::c_void,
- types::{ForeignOwnable, NotThreadSafe, Opaque},
+ types::{
+ ForeignOwnable,
+ NotThreadSafe,
+ Opaque, //
+ }, //
};
use core::{iter, marker::PhantomData, pin::Pin, ptr::NonNull};
use pin_init::{pin_data, pin_init, pinned_drop, PinInit};
base-commit: 98cc68794c003bc76fc9da2e8a075e947eee5921
--
2.54.0
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH v4] rust: make `build_assert` module the home of related macros
2026-06-09 14:26 [PATCH v4] rust: make `build_assert` module the home of related macros Gary Guo
@ 2026-06-09 17:19 ` Miguel Ojeda
0 siblings, 0 replies; 2+ messages in thread
From: Miguel Ojeda @ 2026-06-09 17:19 UTC (permalink / raw)
To: Gary Guo
Cc: Danilo Krummrich, Alexandre Courbot, Alice Ryhl, David Airlie,
Simona Vetter, Miguel Ojeda, Boqun Feng, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Trevor Gross, Daniel Almeida,
FUJITA Tomonori, Yury Norov, Will Deacon, Peter Zijlstra,
Mark Rutland, Ingo Molnar, Waiman Long, Tamir Duberstein,
nova-gpu, dri-devel, linux-kernel, rust-for-linux, driver-core,
netdev
On Tue, Jun 9, 2026 at 4:27 PM Gary Guo <gary@kernel.org> wrote:
>
> This is the remaining unapplied patch from
> https://lore.kernel.org/rust-for-linux/20260319121653.2975748-1-gary@kernel.org/.
Thanks for rebasing! I had it as "Waiting for apply" in the
spreadsheet, but this saved me a bit of work.
Quick question below about the prelude...
> +#[doc(no_inline)]
> +pub use crate::build_assert::{
> + build_assert,
> + build_error,
> + const_assert,
> + static_assert, //
> +};
Did you split this for some reason? I moved the file to a single group
per crate when I moved the file to the new formatting style, so I was
wondering if we could keep it non-split. I mean, it may be nicer for
macros since it allows us to group them, but I hope we don't end up
with many `use`s again if we go down that road again...
Or perhaps you did it for the attribute, i.e. it may behave
differently, but I doubt that is the case? i.e. if `no_inline` somehow
behaves differently this way.
> rust/kernel/sync/atomic/predefine.rs
In this one you used the prelude, but in the others not -- which is
fine, we should be using the prelude more (though perhaps it is a
separate change), but I wonder if there was a reason.
Thanks!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-06-09 17:19 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-09 14:26 [PATCH v4] rust: make `build_assert` module the home of related macros Gary Guo
2026-06-09 17:19 ` Miguel Ojeda
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox