Re: [PATCH 10/22] rust: add `ZeroableOption` and implement it instead of `Zeroable` for `Option<Box<T, A>>`
From: Fiona Behrens
Date: Wed Mar 05 2025 - 04:25:51 EST
Benno Lossin <benno.lossin@xxxxxxxxx> writes:
> When making pin-init its own crate, `Zeroable` will no longer be defined
> by the kernel crate and thus implementing it for `Option<Box<T, A>>` is
> no longer possible due to the orphan rule.
> For this reason introduce a new `ZeroableOption` trait that circumvents
> this problem.
>
> Signed-off-by: Benno Lossin <benno.lossin@xxxxxxxxx>
Reviewed-by: Fiona Behrens <me@xxxxxxxxxx>
> ---
> rust/kernel/alloc/kbox.rs | 4 ++--
> rust/pin-init/src/lib.rs | 11 +++++++++++
> 2 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
> index 9861433559dc..07150c038e3f 100644
> --- a/rust/kernel/alloc/kbox.rs
> +++ b/rust/kernel/alloc/kbox.rs
> @@ -15,7 +15,7 @@
> use core::ptr::NonNull;
> use core::result::Result;
>
> -use crate::init::{InPlaceWrite, Init, PinInit, Zeroable};
> +use crate::init::{InPlaceWrite, Init, PinInit, ZeroableOption};
> use crate::init_ext::InPlaceInit;
> use crate::types::ForeignOwnable;
>
> @@ -104,7 +104,7 @@
> //
> // In this case we are allowed to use `T: ?Sized`, since all zeros is the `None` variant and there
> // is no problem with a VTABLE pointer being null.
> -unsafe impl<T: ?Sized, A: Allocator> Zeroable for Option<Box<T, A>> {}
> +unsafe impl<T: ?Sized, A: Allocator> ZeroableOption for Box<T, A> {}
>
> // SAFETY: `Box` is `Send` if `T` is `Send` because the `Box` owns a `T`.
> unsafe impl<T, A> Send for Box<T, A>
> diff --git a/rust/pin-init/src/lib.rs b/rust/pin-init/src/lib.rs
> index 5fd8fa7c2ce9..fd2c4fdd0ca4 100644
> --- a/rust/pin-init/src/lib.rs
> +++ b/rust/pin-init/src/lib.rs
> @@ -1297,6 +1297,17 @@ pub unsafe trait PinnedDrop: __internal::HasPinData {
> /// ```
> pub unsafe trait Zeroable {}
>
> +/// Marker trait for types that allow `Option<Self>` to be set to all zeroes in order to write
> +/// `None` to that location.
> +///
> +/// # Safety
> +///
> +/// The implementer needs to ensure that `unsafe impl Zeroable for Option<Self> {}` is sound.
is sound does sound a bit vague, but also don't have ideas.
Thanks
Fiona
> +pub unsafe trait ZeroableOption {}
> +
> +// SAFETY: by the safety requirement of `ZeroableOption`, this is valid.
> +unsafe impl<T: ZeroableOption> Zeroable for Option<T> {}
> +
> /// Create a new zeroed T.
> ///
> /// The returned initializer will write `0x00` to every byte of the given `slot`.