Re: [PATCH 1/2] rust: num: casts: replace const type narrowing methods with a macro

"Eliot Courtney" <[email protected]>
Newsgroups org.kernel.vger.rust-for-linux,dev.linux.lists.nova-gpu,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On Tue Aug 25, 2026 at 11:44 AM JST, Alexandre Courbot wrote:
> The casts module features a series of const converters (e.g.
> `u32_into_u16`) that narrow the type of a const expression provided that
> its value can be proven to fit into the destination type at
> compile-time.
>
> These functions are numerous (9 of them), generated by a macro and thus
> not easily discoverable, and cumbersome to use as they require a
> turbofish and const expression between `{` and `}` braces.
>
> Replace them all by a single `const_as!` macro that expands to a const
> block verifying the lossless nature of the conversion at compile-time.
> This turns e.g.:
>
>     const DMA_LEN: u32 = casts::usize_into_u32::<{ MEM_BLOCK_ALIGNMENT }>();
>
> into
>
>     const DMA_LEN: u32 = casts::const_as!(MEM_BLOCK_ALIGNMENT => u32);
>
> This makes things easier to read and understand, while shifting the
> burden of checking the conversion's validity from reviewers (via a CAST
> comment) to the compiler.
>
> Signed-off-by: Alexandre Courbot <[email protected]>
> ---
>  rust/kernel/num/casts.rs | 129 +++++++++++++++++++++++++++++------------------
>  1 file changed, 79 insertions(+), 50 deletions(-)
>
> diff --git a/rust/kernel/num/casts.rs b/rust/kernel/num/casts.rs
> index 7e6c7dec747d..a4a18a6f2ba8 100644
> --- a/rust/kernel/num/casts.rs
> +++ b/rust/kernel/num/casts.rs
> @@ -20,10 +20,8 @@
>  //! - Two extension traits, [`FromSafeCast`] and [`IntoSafeCast`], providing conversion methods
>  //!   similar to [`From`] and [`Into`] for conversions that are safe to perform in the kernel, but
>  //!   not supported by the standard library.
> -//! - Another series of const functions (e.g. [`u64_into_u8`]) supporting the conversion of a const
> -//!   value from a larger type into a smaller one, provided the value fits into the destination
> -//!   type. This is useful if a constant is defined as a larger type, but needs to be used as a
> -//!   smaller one.
> +//! - A [`const_as!`] macro, losslessly casting a constant expression between any two integer
> +//!   types, with conversions that would alter the value reported as build errors.
>  //! - An [`arch`] sub-module, defining more conversion functions that are only guaranteed to be
>  //!   lossless for a given pointer size. These can only be used in code that is specific to a
>  //!   given pointer size.

Can we add guidance somewhere in this file on when to use const_as! vs
when to use the u8_as_usize etc ones, when both could work? e.g. use
const_as! if you can, otherwise use the function version, or, use the
function version if it's sufficient (types alone are enough to prove)
otherwise use the macro.

[...]
> +#[macro_export]
> +#[doc(hidden)]
> +macro_rules! const_as {
> +    ($v:expr => $into:ty) => {
> +        const {
> +            #[allow(unused_comparisons, unused_assignments, clippy::as_underscore)]
> +            {
> +                let v = $v;
> +                let r = v as $into;
> +                // Pin `back` to `v`'s type so `as _` casts back to the source type.
> +                let mut back = v;
> +                back = r as _;
>  
> -                N as $into
> +                ::core::assert!(
> +                    back == v && (v < 0) == (r < 0),
> +                    "value does not fit into the target type"
> +                );

What about giving some text on what doesn't fit where? e.g.
::core::concat!("`", ::core::stringify!($v), "` does not fit into `", ::core::stringify!($into), "`")
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.