Skip to contentSkip to conversation

rust: transmute: add `as_bytes(_mut)` methods for `AsBytes` trait

PATCH Superseded Alexandre Courbot 6 participants 10 messages Jul 28, 2025 Rust

v4 of 5 Superseded Latest is v5 →

lore
Share & tools
lore

Alexandre Courbot

author reviewer
#0 lore raw

v4 cover rust: transmute: add `as_bytes(_mut)` methods for `AsBytes` trait

This is the sister patch of [1], providing an as_bytes method for AsBytes, and an as_bytes_mut accessor for types also implementing FromBytes.

It is going to be used in Nova, but should also be universally useful - if anything, it felt a bit strange that AsBytes did not provide this so far.

[1] https://lore.kernel.org/rust-for-linux/[email protected]/

---
Changes in v4:
- Add the as_bytes_mut method for types also implementing FromBytes. (thanks Alice!)
- Link to v3: https://lore.kernel.org/r/[email protected]

Changes in v3:
- Use ptr::from_ref instead of as *const T.
- Link to v2: https://lore.kernel.org/r/[email protected]

Changes in v2:
- Use size_of_val to provide a default implementation for both Sized and non-Sized types, and remove AsBytesSized. (thanks Alice!)
- Link to v1: https://lore.kernel.org/r/[email protected]

---
Alexandre Courbot (2):
rust: transmute: add as_bytes method for AsBytes trait
rust: transmute: add as_bytes_mut method to AsBytes trait

 rust/kernel/transmute.rs | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

---
base-commit: 14ae91a81ec8fa0bc23170d4aa16dd2a20d54105
change-id: 20250725-as_bytes-6cbc11f2e8c3

Best regards,

Signature · 1 line
Alexandre Courbot <[email protected]>
author reviewer
#1 lore raw

PATCH v4 1/2 rust: transmute: add `as_bytes` method for `AsBytes` trait

Every type that implements AsBytes should be able to provide its byte representation. Introduce the as_bytes method that returns the implementer as a stream of bytes, and provide a default implementation that should be suitable for any type that satisfies AsBytes's safety requirements.

---
 rust/kernel/transmute.rs | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
rust/kernel/transmute.rs +10 -1
index 1c7d43771a37b90150de86699f114a2ffb84db91..d541c9960904d8c7f755351f22d06e4e8dbd546a 100644
@@ -47,7 +47,16 @@ macro_rules! impl_frombytes {
 ///
 /// Values of this type may not contain any uninitialized bytes. This type must not have interior
 /// mutability.
-pub unsafe trait AsBytes {}
+pub unsafe trait AsBytes {
+    /// Returns `self` as a slice of bytes.
+    fn as_bytes(&self) -> &[u8] {
+        let data = core::ptr::from_ref(self).cast::<u8>();
+        let len = size_of_val(self);
+
+        // SAFETY: `data` is non-null and valid for reads over `len * sizeof::<u8>()` bytes.
+        unsafe { core::slice::from_raw_parts(data, len) }
+    }
+}
 
 macro_rules! impl_asbytes {
     ($($({$($generics:tt)*})? $t:ty, )*) => {
Signature · 1 line
2.50.1
reviewer
#2 lore raw

Re: [PATCH v4 1/2] rust: transmute: add `as_bytes` method for `AsBytes` trait

rust/kernel/transmute.rs macro_rules! impl_frombytes { · line 53

Quoted 13 lines · Alexandre Courbot
rust/kernel/transmute.rs +4 -1
index 1c7d43771a37b90150de86699f114a2ffb84db91..d541c9960904d8c7f755351f22d06e4e8dbd546a 100644
@@ -47,7 +47,16 @@ macro_rules! impl_frombytes {
 ///
 /// Values of this type may not contain any uninitialized bytes. This type must not have interior
 /// mutability.
-pub unsafe trait AsBytes {}
+pub unsafe trait AsBytes {
+    /// Returns `self` as a slice of bytes.
+    fn as_bytes(&self) -> &[u8] {
+        let data = core::ptr::from_ref(self).cast::<u8>();

Let's add a CAST comment above this that says:

    // CAST: `Self` implements `AsBytes` thus all bytes of `self` are initialized.

rust/kernel/transmute.rs macro_rules! impl_frombytes { · line 56

Quoted 3 lines
rust/kernel/transmute.rs +3 -0
+        let len = size_of_val(self);
+
+        // SAFETY: `data` is non-null and valid for reads over `len * sizeof::<u8>()` bytes.

s/over/of/

---
Cheers,
Benno

Quoted 6 lines
rust/kernel/transmute.rs +3 -0
+        unsafe { core::slice::from_raw_parts(data, len) }
+    }
+}
 
 macro_rules! impl_asbytes {
     ($($({$($generics:tt)*})? $t:ty, )*) => {
author reviewer
#3 lore raw

PATCH v4 2/2 rust: transmute: add `as_bytes_mut` method to `AsBytes` trait

In reply to Alexandre Courbot

Types that implement both AsBytes and FromBytes can be safely modified as a slice of bytes. Add a as_bytes_mut method for that purpose.

---
 rust/kernel/transmute.rs | 13 +++++++++++++
 1 file changed, 13 insertions(+)
rust/kernel/transmute.rs +13 -0
index d541c9960904d8c7f755351f22d06e4e8dbd546a..000fda2a78f8e6e8378bbe93cddd8a5008db20cc 100644
@@ -56,6 +56,19 @@ fn as_bytes(&self) -> &[u8] {
         // SAFETY: `data` is non-null and valid for reads over `len * sizeof::<u8>()` bytes.
         unsafe { core::slice::from_raw_parts(data, len) }
     }
+
+    /// Returns `self` as a mutable slice of bytes.
+    fn as_bytes_mut(&mut self) -> &mut [u8]
+    where
+        Self: FromBytes,
+    {
+        let data = core::ptr::from_mut(self).cast::<u8>();
+        let len = size_of_val(self);
+
+        // SAFETY: `data` is non-null and valid for read and writes over `len * sizeof::<u8>()`
+        // bytes. Since `Self` implements `FromBytes` it can be represented by any value.
+        unsafe { core::slice::from_raw_parts_mut(data, len) }
+    }
 }
 
 macro_rules! impl_asbytes {
Signature · 1 line
2.50.1
reviewer
#5 lore raw

Re: [PATCH v4 2/2] rust: transmute: add `as_bytes_mut` method to `AsBytes` trait

In reply to Alexandre Courbot
Quoted 5 lines · Alexandre Courbot
rust/kernel/transmute.rs +0 -0
index d541c9960904d8c7f755351f22d06e4e8dbd546a..000fda2a78f8e6e8378bbe93cddd8a5008db20cc 100644

rust/kernel/transmute.rs fn as_bytes(&self) -> &[u8] { · line 65

Quoted 10 lines
rust/kernel/transmute.rs +7 -0
@@ -56,6 +56,19 @@ fn as_bytes(&self) -> &[u8] {
         // SAFETY: `data` is non-null and valid for reads over `len * sizeof::<u8>()` bytes.
         unsafe { core::slice::from_raw_parts(data, len) }
     }
+
+    /// Returns `self` as a mutable slice of bytes.
+    fn as_bytes_mut(&mut self) -> &mut [u8]
+    where
+        Self: FromBytes,
+    {
+        let data = core::ptr::from_mut(self).cast::<u8>();

Also add a CAST comment above this line:

    // CAST: `Self` implements both `AsBytes` and `FromBytes` thus making `Self` bi-directionally
    // transmutable to `[u8; size_of_val(self)]`.

On that note, FromBytes probably entails Sized, or does someone have a use-case in mind? (because then we could replace the size_of_val(self) above with size_of::<Self>() which I think makes it simpler to understand)

rust/kernel/transmute.rs fn as_bytes(&self) -> &[u8] { · line 68

Quoted 3 lines
rust/kernel/transmute.rs +3 -0
+        let len = size_of_val(self);
+
+        // SAFETY: `data` is non-null and valid for read and writes over `len * sizeof::<u8>()`

s/over/of/

rust/kernel/transmute.rs fn as_bytes(&self) -> &[u8] { · line 69

Quoted 1 line
rust/kernel/transmute.rs +1 -0
+        // bytes. Since `Self` implements `FromBytes` it can be represented by any value.

Don't need the second sentence due to the CAST comment above.

---
Cheers,
Benno

Quoted 5 lines
rust/kernel/transmute.rs +2 -0
+        unsafe { core::slice::from_raw_parts_mut(data, len) }
+    }
 }
 
 macro_rules! impl_asbytes {
#6 lore raw

Re: [PATCH v4 2/2] rust: transmute: add `as_bytes_mut` method to `AsBytes` trait

Quoted 19 lines · Benno Lossin
Quoted 5 lines · Alexandre Courbot
rust/kernel/transmute.rs +0 -0
index d541c9960904d8c7f755351f22d06e4e8dbd546a..000fda2a78f8e6e8378bbe93cddd8a5008db20cc 100644

rust/kernel/transmute.rs fn as_bytes(&self) -> &[u8] { · line 65

Quoted 10 lines
rust/kernel/transmute.rs +7 -0
@@ -56,6 +56,19 @@ fn as_bytes(&self) -> &[u8] {
         // SAFETY: `data` is non-null and valid for reads over `len * sizeof::<u8>()` bytes.
         unsafe { core::slice::from_raw_parts(data, len) }
     }
+
+    /// Returns `self` as a mutable slice of bytes.
+    fn as_bytes_mut(&mut self) -> &mut [u8]
+    where
+        Self: FromBytes,
+    {
+        let data = core::ptr::from_mut(self).cast::<u8>();

Also add a CAST comment above this line:

Quoted 5 lines
    // CAST: `Self` implements both `AsBytes` and `FromBytes` thus making `Self` bi-directionally
    // transmutable to `[u8; size_of_val(self)]`.

On that note, FromBytes probably entails Sized, or does someone have a use-case in mind? (because then we could replace the

Because if T is FromBytes then we want [T] is FromBytes too? Also it would be weird if [u8] itself doesn't implement FromBytes.

Regards,
Boqun

Quoted 3 lines

size_of_val(self) above with size_of::<Self>() which I think makes it simpler to understand)

[...]

reviewer
#7 lore raw

Re: [PATCH v4 2/2] rust: transmute: add `as_bytes_mut` method to `AsBytes` trait

Quoted 20 lines · Boqun Feng
Quoted 19 lines · Benno Lossin
Quoted 5 lines · Alexandre Courbot
rust/kernel/transmute.rs +0 -0
index d541c9960904d8c7f755351f22d06e4e8dbd546a..000fda2a78f8e6e8378bbe93cddd8a5008db20cc 100644

rust/kernel/transmute.rs fn as_bytes(&self) -> &[u8] { · line 65

Quoted 10 lines
rust/kernel/transmute.rs +7 -0
@@ -56,6 +56,19 @@ fn as_bytes(&self) -> &[u8] {
         // SAFETY: `data` is non-null and valid for reads over `len * sizeof::<u8>()` bytes.
         unsafe { core::slice::from_raw_parts(data, len) }
     }
+
+    /// Returns `self` as a mutable slice of bytes.
+    fn as_bytes_mut(&mut self) -> &mut [u8]
+    where
+        Self: FromBytes,
+    {
+        let data = core::ptr::from_mut(self).cast::<u8>();

Also add a CAST comment above this line:

Quoted 8 lines
Quoted 5 lines
    // CAST: `Self` implements both `AsBytes` and `FromBytes` thus making `Self` bi-directionally
    // transmutable to `[u8; size_of_val(self)]`.

On that note, FromBytes probably entails Sized, or does someone have a use-case in mind? (because then we could replace the

Because if T is FromBytes then we want [T] is FromBytes too? Also it would be weird if [u8] itself doesn't implement FromBytes.

Oh yeah that's true.

---
Cheers,
Benno

reviewer Reviewed-by on the v4 series
#8 lore raw
In reply to Alexandre Courbot
Quoted 26 lines · Alexandre Courbot

This is the sister patch of [1], providing an as_bytes method for AsBytes, and an as_bytes_mut accessor for types also implementing FromBytes.

It is going to be used in Nova, but should also be universally useful - if anything, it felt a bit strange that AsBytes did not provide this so far.

[1] https://lore.kernel.org/rust-for-linux/[email protected]/

---
Changes in v4:
- Add the as_bytes_mut method for types also implementing FromBytes. (thanks Alice!)
- Link to v3: https://lore.kernel.org/r/[email protected]

Changes in v3:
- Use ptr::from_ref instead of as *const T.
- Link to v2: https://lore.kernel.org/r/[email protected]

Changes in v2:
- Use size_of_val to provide a default implementation for both Sized and non-Sized types, and remove AsBytesSized. (thanks Alice!)
- Link to v1: https://lore.kernel.org/r/[email protected]

Quoted 4 lines

---
Alexandre Courbot (2):
rust: transmute: add as_bytes method for AsBytes trait
rust: transmute: add as_bytes_mut method to AsBytes trait

reviewer Reviewed-by on the v4 series
#9 lore raw
In reply to Alexandre Courbot
Quoted 31 lines · On Mon, 28 Jul 2025 21:47:50 +0900 Alexandre Courbot <[email protected]>…

This is the sister patch of [1], providing an as_bytes method for AsBytes, and an as_bytes_mut accessor for types also implementing FromBytes.

It is going to be used in Nova, but should also be universally useful - if anything, it felt a bit strange that AsBytes did not provide this so far.

[1] https://lore.kernel.org/rust-for-linux/[email protected]/

---
Changes in v4:
- Add the as_bytes_mut method for types also implementing FromBytes. (thanks Alice!)
- Link to v3: https://lore.kernel.org/r/[email protected]

Changes in v3:
- Use ptr::from_ref instead of as *const T.
- Link to v2: https://lore.kernel.org/r/[email protected]

Changes in v2:
- Use size_of_val to provide a default implementation for both Sized and non-Sized types, and remove AsBytesSized. (thanks Alice!)
- Link to v1: https://lore.kernel.org/r/[email protected]

---
Alexandre Courbot (2):
rust: transmute: add as_bytes method for AsBytes trait
rust: transmute: add as_bytes_mut method to AsBytes trait

Quoted 7 lines
 rust/kernel/transmute.rs | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

---
base-commit: 14ae91a81ec8fa0bc23170d4aa16dd2a20d54105
change-id: 20250725-as_bytes-6cbc11f2e8c3

Best regards,