Re: [PATCH v7 03/10] rust: num: add nz! macro for compile time NonZero values
"Gary Guo" <[email protected]>
| Newsgroups | org.kernel.vger.rust-for-linux,dev.linux.lists.nova-gpu,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On Mon Aug 17, 2026 at 8:04 AM BST, Eliot Courtney wrote: > Currently, using NonZero constants is quite verbose. It's unfortunate > because it disincentivizes using it in interface boundaries. Introduce a > macro to make it nicer to use. > > Link: https://lore.kernel.org/[email protected] > Signed-off-by: Eliot Courtney <[email protected]> > --- > rust/kernel/num.rs | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) > > diff --git a/rust/kernel/num.rs b/rust/kernel/num.rs > index 8532b511384c..055d23ca7fd1 100644 > --- a/rust/kernel/num.rs > +++ b/rust/kernel/num.rs > @@ -7,6 +7,29 @@ > pub mod bounded; > pub use bounded::*; > > +/// Infallibly creates a [`NonZero`] value from a constant expression. > +/// > +/// [`NonZero`]: core::num::NonZero > +/// > +/// # Examples > +/// > +/// ``` > +/// use core::num::NonZero; > +/// use kernel::nz; > +/// > +/// let v: NonZero<usize> = nz!(8); > +/// assert_eq!(v.get(), 8); > +/// > +/// const N: NonZero<u32> = nz!(0x10); > +/// assert_eq!(N.get(), 0x10); > +/// ``` > +#[macro_export] > +macro_rules! nz { > + ($v:expr) => { > + const { ::core::num::NonZero::new($v).unwrap() } > + }; > +} I wonder if if we can have a generic macro for creating types from literals, given that this is needed for bounded too. Something like trait FromLiteral { fn from_literal<const N: i64>() -> Self; } impl FromLiteral for NonZero<u32> { #[inline] fn from_literal<const N: i64>() -> Self { const_assert!(N > 0 && N < u32::MAX as i64); const { NonZero::new(N as u32).unwrap() } } } macro_rules! lit { ($x:expr) => { FromLiteral::from_literal::<{$x}>() } } let nz: NonZero<u32> = lit!(1); let bounded: Bounded<..> = lit!(1); I think the only downside is that this expression isn't const expr anymore. We can change this to be const trait FromLiteral { fn from_literal(v: i64) -> Self; } when const trait impl is stable upstream and we have MSRV bumped high enough to have an impl of it. Best, Gary