[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <DBDP54SLN4EZ.2EQ004NXWCX2L@kernel.org>
Date: Wed, 16 Jul 2025 20:38:22 +0200
From: "Danilo Krummrich" <dakr@...nel.org>
To: "Daniel Almeida" <daniel.almeida@...labora.com>
Cc: "Miguel Ojeda" <ojeda@...nel.org>, "Alex Gaynor"
<alex.gaynor@...il.com>, "Boqun Feng" <boqun.feng@...il.com>, "Gary Guo"
<gary@...yguo.net>, Björn Roy Baron
<bjorn3_gh@...tonmail.com>, "Benno Lossin" <lossin@...nel.org>, "Andreas
Hindborg" <a.hindborg@...nel.org>, "Alice Ryhl" <aliceryhl@...gle.com>,
"Trevor Gross" <tmgross@...ch.edu>, <linux-kernel@...r.kernel.org>,
<rust-for-linux@...r.kernel.org>, "Alexandre Courbot" <acourbot@...dia.com>
Subject: Re: [PATCH v9] rust: kernel: add support for bits/genmask macros
On Tue Jul 15, 2025 at 1:29 AM CEST, Daniel Almeida wrote:
> +macro_rules! impl_genmask_fn {
> + (
> + $ty:ty,
> + $(#[$genmask_checked_ex:meta])*,
> + $(#[$genmask_ex:meta])*
> + ) => {
> + paste! {
> + /// Creates a contiguous bitmask for the given range by validating
> + /// the range at runtime.
> + ///
> + /// Returns [`None`] if the range is invalid, i.e.: if the start is
> + /// greater than the end or if the range is outside of the
> + /// representable range for the type.
> + $(#[$genmask_checked_ex])*
> + #[inline]
> + pub fn [<genmask_checked_ $ty>](range: RangeInclusive<u32>) -> Option<$ty> {
> + let start = *range.start();
> + let end = *range.end();
> +
> + if start > end {
> + return None;
> + }
> +
> + let high = [<checked_bit_ $ty>](end)?;
> + let low = [<checked_bit_ $ty>](start)?;
> + Some((high | (high - 1)) & !(low - 1))
> + }
> +
> + /// Creates a compile-time contiguous bitmask for the given range by
> + /// performing a compile-time assertion that the range is valid.
> + ///
> + /// This version is the default and should be used if the range is known
> + /// at compile time.
> + $(#[$genmask_ex])*
> + #[inline]
> + pub const fn [<genmask_ $ty>](range: RangeInclusive<u32>) -> $ty {
> + let start = *range.start();
> + let end = *range.end();
> +
> + build_assert!(start <= end);
> +
> + let high = [<bit_ $ty>](end);
> + let low = [<bit_ $ty>](start);
> + (high | (high - 1)) & !(low - 1)
> + }
> + }
> + };
> +}
Just for reference, I asked some questions regarding this code in [1].
Additional to "Why does genmask_u64(0..=100) compile?" I would expect the
corresponding genmask_checked_u64() call to return None.
[1] https://lore.kernel.org/lkml/DBDP0BJW9VAZ.5KRU4V4288R8@kernel.org/
Powered by blists - more mailing lists