* [PATCH v3 2/4] rust: add `const_assert!` macro
[not found] <20260319121653.2975748-1-gary@kernel.org>
@ 2026-03-19 12:16 ` Gary Guo
2026-03-19 14:12 ` Alice Ryhl
2026-03-21 13:05 ` Alexandre Courbot
0 siblings, 2 replies; 5+ messages in thread
From: Gary Guo @ 2026-03-19 12:16 UTC (permalink / raw)
To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Alexandre Courbot, Yury Norov,
Nathan Chancellor, Nicolas Schier
Cc: Yury Norov, rust-for-linux, linux-kernel, linux-kbuild
From: Gary Guo <gary@garyguo.net>
The macro is a more powerful version of `static_assert!` for use inside
function contexts. This is powered by inline consts, so enable the feature
for old compiler versions that does not have it stably.
While it is possible already to write `const { assert!(...) }`, this
provides a short hand that is more uniform with other assertions. It also
formats nicer with rustfmt where it will not be formatted into multiple
lines.
Two users that would route via the Rust tree are converted.
Reviewed-by: Yury Norov <ynorov@nvidia.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
---
rust/kernel/build_assert.rs | 24 ++++++++++++++++++++++++
rust/kernel/num/bounded.rs | 24 +++++++++---------------
rust/kernel/prelude.rs | 7 ++++++-
rust/kernel/ptr.rs | 12 ++++++------
scripts/Makefile.build | 5 +++--
5 files changed, 48 insertions(+), 24 deletions(-)
diff --git a/rust/kernel/build_assert.rs b/rust/kernel/build_assert.rs
index d464494d430a..50b0fc0a80fc 100644
--- a/rust/kernel/build_assert.rs
+++ b/rust/kernel/build_assert.rs
@@ -41,6 +41,30 @@ macro_rules! static_assert {
};
}
+/// Assertion during constant evaluation.
+///
+/// This is a more powerful version of [`static_assert!`] that can refer to generics inside
+/// functions or implementation blocks. However, it also has a limitation where it can only appear
+/// in places where statements can appear; for example, you cannot use it as an item in the module.
+///
+/// # Examples
+///
+/// ```
+/// fn foo<const N: usize>() {
+/// const_assert!(N > 1);
+/// }
+///
+/// fn bar<T>() {
+/// const_assert!(size_of::<T>() > 0, "T cannot be ZST");
+/// }
+/// ```
+#[macro_export]
+macro_rules! const_assert {
+ ($condition:expr $(,$arg:literal)?) => {
+ const { ::core::assert!($condition $(,$arg)?) };
+ };
+}
+
/// Fails the build if the code path calling `build_error!` can possibly be executed.
///
/// If the macro is executed in const context, `build_error!` will panic.
diff --git a/rust/kernel/num/bounded.rs b/rust/kernel/num/bounded.rs
index bbab6bbcb315..f9f90d6ec482 100644
--- a/rust/kernel/num/bounded.rs
+++ b/rust/kernel/num/bounded.rs
@@ -255,9 +255,7 @@ impl<const N: u32> Bounded<$type, N> {
/// ```
pub const fn new<const VALUE: $type>() -> Self {
// Statically assert that `VALUE` fits within the set number of bits.
- const {
- assert!(fits_within!(VALUE, $type, N));
- }
+ const_assert!(fits_within!(VALUE, $type, N));
// SAFETY: `fits_within` confirmed that `VALUE` can be represented within
// `N` bits.
@@ -287,12 +285,10 @@ impl<T, const N: u32> Bounded<T, N>
/// The caller must ensure that `value` can be represented within `N` bits.
const unsafe fn __new(value: T) -> Self {
// Enforce the type invariants.
- const {
- // `N` cannot be zero.
- assert!(N != 0);
- // The backing type is at least as large as `N` bits.
- assert!(N <= T::BITS);
- }
+ // `N` cannot be zero.
+ const_assert!(N != 0);
+ // The backing type is at least as large as `N` bits.
+ const_assert!(N <= T::BITS);
// INVARIANT: The caller ensures `value` fits within `N` bits.
Self(value)
@@ -409,12 +405,10 @@ pub const fn get(self) -> T {
/// assert_eq!(larger_v, v);
/// ```
pub const fn extend<const M: u32>(self) -> Bounded<T, M> {
- const {
- assert!(
- M >= N,
- "Requested number of bits is less than the current representation."
- );
- }
+ const_assert!(
+ M >= N,
+ "Requested number of bits is less than the current representation."
+ );
// SAFETY: The value did fit within `N` bits, so it will all the more fit within
// the larger `M` bits.
diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs
index c7e91b80d301..6a54597fa0a2 100644
--- a/rust/kernel/prelude.rs
+++ b/rust/kernel/prelude.rs
@@ -29,7 +29,12 @@
pub use pin_init::{init, pin_data, pin_init, pinned_drop, InPlaceWrite, Init, PinInit, Zeroable};
-pub use super::{build_assert, build_error, static_assert};
+pub use super::{
+ build_assert,
+ build_error,
+ const_assert,
+ static_assert, //
+};
// `super::std_vendor` is hidden, which makes the macro inline for some reason.
#[doc(no_inline)]
diff --git a/rust/kernel/ptr.rs b/rust/kernel/ptr.rs
index bdc2d79ff669..d05e5888e80c 100644
--- a/rust/kernel/ptr.rs
+++ b/rust/kernel/ptr.rs
@@ -11,6 +11,8 @@
};
use core::num::NonZero;
+use crate::const_assert;
+
/// Type representing an alignment, which is always a power of two.
///
/// It is used to validate that a given value is a valid alignment, and to perform masking and
@@ -44,12 +46,10 @@ impl Alignment {
/// ```
#[inline(always)]
pub const fn new<const ALIGN: usize>() -> Self {
- const {
- assert!(
- ALIGN.is_power_of_two(),
- "Provided alignment is not a power of two."
- );
- }
+ const_assert!(
+ ALIGN.is_power_of_two(),
+ "Provided alignment is not a power of two."
+ );
// INVARIANT: `align` is a power of two.
// SAFETY: `align` is a power of two, and thus non-zero.
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 010d08472fb2..195a8b7016f3 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -310,7 +310,8 @@ $(obj)/%.lst: $(obj)/%.c FORCE
# The features in this list are the ones allowed for non-`rust/` code.
#
-# - Stable since Rust 1.79.0: `feature(slice_ptr_len)`.
+# - Stable since Rust 1.79.0: `feature(inline_const)`,
+# `feature(slice_ptr_len)`,
# - Stable since Rust 1.81.0: `feature(lint_reasons)`.
# - Stable since Rust 1.82.0: `feature(asm_const)`,
# `feature(offset_of_nested)`, `feature(raw_ref_op)`.
@@ -322,7 +323,7 @@ $(obj)/%.lst: $(obj)/%.c FORCE
#
# Please see https://github.com/Rust-for-Linux/linux/issues/2 for details on
# the unstable features in use.
-rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,generic_arg_infer,lint_reasons,offset_of_nested,raw_ref_op,slice_ptr_len,strict_provenance,used_with_arg
+rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,generic_arg_infer,inline_const,lint_reasons,offset_of_nested,raw_ref_op,slice_ptr_len,strict_provenance,used_with_arg
# `--out-dir` is required to avoid temporaries being created by `rustc` in the
# current working directory, which may be not accessible in the out-of-tree
--
2.51.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v3 2/4] rust: add `const_assert!` macro
2026-03-19 12:16 ` [PATCH v3 2/4] rust: add `const_assert!` macro Gary Guo
@ 2026-03-19 14:12 ` Alice Ryhl
2026-03-19 14:26 ` Gary Guo
2026-03-21 13:05 ` Alexandre Courbot
1 sibling, 1 reply; 5+ messages in thread
From: Alice Ryhl @ 2026-03-19 14:12 UTC (permalink / raw)
To: Gary Guo
Cc: Miguel Ojeda, Boqun Feng, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Trevor Gross, Danilo Krummrich,
Alexandre Courbot, Yury Norov, Nathan Chancellor, Nicolas Schier,
Yury Norov, rust-for-linux, linux-kernel, linux-kbuild
On Thu, Mar 19, 2026 at 12:16:46PM +0000, Gary Guo wrote:
> From: Gary Guo <gary@garyguo.net>
>
> The macro is a more powerful version of `static_assert!` for use inside
> function contexts. This is powered by inline consts, so enable the feature
> for old compiler versions that does not have it stably.
>
> While it is possible already to write `const { assert!(...) }`, this
> provides a short hand that is more uniform with other assertions. It also
> formats nicer with rustfmt where it will not be formatted into multiple
> lines.
>
> Two users that would route via the Rust tree are converted.
>
> Reviewed-by: Yury Norov <ynorov@nvidia.com>
> Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
It may be worth to mention in docs that const_assert! may only be
checked if the function it appears in has a caller. Whereas
static_assert! is always checked no matter what.
Alice
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 2/4] rust: add `const_assert!` macro
2026-03-19 14:12 ` Alice Ryhl
@ 2026-03-19 14:26 ` Gary Guo
2026-03-19 14:34 ` Alice Ryhl
0 siblings, 1 reply; 5+ messages in thread
From: Gary Guo @ 2026-03-19 14:26 UTC (permalink / raw)
To: Alice Ryhl, Gary Guo
Cc: Miguel Ojeda, Boqun Feng, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Trevor Gross, Danilo Krummrich,
Alexandre Courbot, Yury Norov, Nathan Chancellor, Nicolas Schier,
Yury Norov, rust-for-linux, linux-kernel, linux-kbuild
On Thu Mar 19, 2026 at 2:12 PM GMT, Alice Ryhl wrote:
> On Thu, Mar 19, 2026 at 12:16:46PM +0000, Gary Guo wrote:
>> From: Gary Guo <gary@garyguo.net>
>>
>> The macro is a more powerful version of `static_assert!` for use inside
>> function contexts. This is powered by inline consts, so enable the feature
>> for old compiler versions that does not have it stably.
>>
>> While it is possible already to write `const { assert!(...) }`, this
>> provides a short hand that is more uniform with other assertions. It also
>> formats nicer with rustfmt where it will not be formatted into multiple
>> lines.
>>
>> Two users that would route via the Rust tree are converted.
>>
>> Reviewed-by: Yury Norov <ynorov@nvidia.com>
>> Signed-off-by: Gary Guo <gary@garyguo.net>
>
> Reviewed-by: Alice Ryhl <aliceryhl@google.com>
>
> It may be worth to mention in docs that const_assert! may only be
> checked if the function it appears in has a caller. Whereas
> static_assert! is always checked no matter what.
>
> Alice
I explained this in patch 3 on why `static_assert!` is preferred over
`const_assert!`. Given that we recommend `const_assert!` only when it refers to
generics, the check is inherently tied to a specific instance anyway, so I don't
think it needs to be mentioned in the item doc.
Best,
Gary
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 2/4] rust: add `const_assert!` macro
2026-03-19 14:26 ` Gary Guo
@ 2026-03-19 14:34 ` Alice Ryhl
0 siblings, 0 replies; 5+ messages in thread
From: Alice Ryhl @ 2026-03-19 14:34 UTC (permalink / raw)
To: Gary Guo
Cc: Miguel Ojeda, Boqun Feng, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Trevor Gross, Danilo Krummrich,
Alexandre Courbot, Yury Norov, Nathan Chancellor, Nicolas Schier,
Yury Norov, rust-for-linux, linux-kernel, linux-kbuild
On Thu, Mar 19, 2026 at 02:26:06PM +0000, Gary Guo wrote:
> On Thu Mar 19, 2026 at 2:12 PM GMT, Alice Ryhl wrote:
> > On Thu, Mar 19, 2026 at 12:16:46PM +0000, Gary Guo wrote:
> >> From: Gary Guo <gary@garyguo.net>
> >>
> >> The macro is a more powerful version of `static_assert!` for use inside
> >> function contexts. This is powered by inline consts, so enable the feature
> >> for old compiler versions that does not have it stably.
> >>
> >> While it is possible already to write `const { assert!(...) }`, this
> >> provides a short hand that is more uniform with other assertions. It also
> >> formats nicer with rustfmt where it will not be formatted into multiple
> >> lines.
> >>
> >> Two users that would route via the Rust tree are converted.
> >>
> >> Reviewed-by: Yury Norov <ynorov@nvidia.com>
> >> Signed-off-by: Gary Guo <gary@garyguo.net>
> >
> > Reviewed-by: Alice Ryhl <aliceryhl@google.com>
> >
> > It may be worth to mention in docs that const_assert! may only be
> > checked if the function it appears in has a caller. Whereas
> > static_assert! is always checked no matter what.
> >
> > Alice
>
> I explained this in patch 3 on why `static_assert!` is preferred over
> `const_assert!`. Given that we recommend `const_assert!` only when it refers to
> generics, the check is inherently tied to a specific instance anyway, so I don't
> think it needs to be mentioned in the item doc.
Ok.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 2/4] rust: add `const_assert!` macro
2026-03-19 12:16 ` [PATCH v3 2/4] rust: add `const_assert!` macro Gary Guo
2026-03-19 14:12 ` Alice Ryhl
@ 2026-03-21 13:05 ` Alexandre Courbot
1 sibling, 0 replies; 5+ messages in thread
From: Alexandre Courbot @ 2026-03-21 13:05 UTC (permalink / raw)
To: Gary Guo
Cc: Gary Guo, Miguel Ojeda, Boqun Feng, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Yury Norov, Nathan Chancellor, Nicolas Schier,
Yury Norov, rust-for-linux, linux-kernel, linux-kbuild
On Thu Mar 19, 2026 at 9:16 PM JST, Gary Guo wrote:
> From: Gary Guo <gary@garyguo.net>
>
> The macro is a more powerful version of `static_assert!` for use inside
> function contexts. This is powered by inline consts, so enable the feature
> for old compiler versions that does not have it stably.
>
> While it is possible already to write `const { assert!(...) }`, this
> provides a short hand that is more uniform with other assertions. It also
> formats nicer with rustfmt where it will not be formatted into multiple
> lines.
>
> Two users that would route via the Rust tree are converted.
>
> Reviewed-by: Yury Norov <ynorov@nvidia.com>
> Signed-off-by: Gary Guo <gary@garyguo.net>
> ---
> rust/kernel/build_assert.rs | 24 ++++++++++++++++++++++++
> rust/kernel/num/bounded.rs | 24 +++++++++---------------
> rust/kernel/prelude.rs | 7 ++++++-
> rust/kernel/ptr.rs | 12 ++++++------
> scripts/Makefile.build | 5 +++--
I'd split the update of users to the new version into dedicated patches,
but other than that,
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-03-21 13:05 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260319121653.2975748-1-gary@kernel.org>
2026-03-19 12:16 ` [PATCH v3 2/4] rust: add `const_assert!` macro Gary Guo
2026-03-19 14:12 ` Alice Ryhl
2026-03-19 14:26 ` Gary Guo
2026-03-19 14:34 ` Alice Ryhl
2026-03-21 13:05 ` Alexandre Courbot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox