[PATCH 1/2] rust: impl_flags: add conversion functions

Andreas Hindborg posted 2 patches 1 month, 2 weeks ago
[PATCH 1/2] rust: impl_flags: add conversion functions
Posted by Andreas Hindborg 1 month, 2 weeks ago
Add two conversion functions to the `impl_flags!` macro:

 - A `From<_>` implementation to convert from the flag value enum to
   underlying type.

 - A `TryFrom<_> implementation to convert from the underlying
   representation to flag container type.

Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
---
 rust/kernel/impl_flags.rs | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/rust/kernel/impl_flags.rs b/rust/kernel/impl_flags.rs
index 9160e8ce2e126..f34ecbe870d80 100644
--- a/rust/kernel/impl_flags.rs
+++ b/rust/kernel/impl_flags.rs
@@ -102,6 +102,26 @@ fn from(value: $flags) -> Self {
             }
         }
 
+        impl ::core::convert::From<$flag> for $ty {
+            #[inline]
+            fn from(value: $flag) -> Self {
+                // SAFETY: All `$flag` values are valid for use as `$ty`.
+                unsafe { core::mem::transmute::<$flag, $ty>(value) }
+            }
+        }
+
+        impl ::core::convert::TryFrom<$ty> for $flags {
+            type Error = ::kernel::error::Error;
+
+            fn try_from(value: $ty) -> Result<Self, Self::Error> {
+                match value & !$flags::all_bits() == 0 {
+                    // SAFETY: We checked above that `value` is a valid bit pattern for `$flags`.
+                    true => Ok(unsafe {::core::mem::transmute::<$ty, $flags>(value)}),
+                    false => Err(::kernel::error::code::EINVAL),
+                }
+            }
+        }
+
         impl ::core::ops::BitOr for $flags {
             type Output = Self;
             #[inline]

-- 
2.51.2
Re: [PATCH 1/2] rust: impl_flags: add conversion functions
Posted by Miguel Ojeda 1 month, 2 weeks ago
On Sun, Feb 15, 2026 at 9:23 PM Andreas Hindborg <a.hindborg@kernel.org> wrote:
>
> +        impl ::core::convert::From<$flag> for $ty {
> +            #[inline]
> +            fn from(value: $flag) -> Self {
> +                // SAFETY: All `$flag` values are valid for use as `$ty`.
> +                unsafe { core::mem::transmute::<$flag, $ty>(value) }
> +            }
> +        }

Why do we need the transmute instead of a cast? Did you notice a difference?

Same in the other one -- why not constructing the object normally?

Also, you can use `Self` for `$ty` and `$flags` to make it easier to read.

In addition, I would suggest an early return with a simple `if`.

Finally, it wouldn't hurt adding a one-liner example for each at the top.

Thanks!

Cheers,
Miguel