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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.