Skip to content

Commit

Permalink
rust: types: avoid repetition in {As,From}Bytes impls
Browse files Browse the repository at this point in the history
In order to provide `// SAFETY` comments for every `unsafe impl`, we would
need to repeat them, which is not very useful and would be harder to read.

We could perhaps allow the lint (ideally within a small module), but we
can take the chance to avoid the repetition of the `impl`s themselves
too by using a small local macro, like in other places where we have
had to do this sort of thing.

Thus add the straightforward `impl_{from,as}bytes!` macros and use them
to implement `FromBytes`.

This, in turn, will allow us in the next patch to place a `// SAFETY`
comment that defers to the actual invocation of the macro.

Signed-off-by: Miguel Ojeda <[email protected]>
  • Loading branch information
ojeda committed Sep 3, 2024
1 parent 2f346e6 commit 8126b58
Showing 1 changed file with 35 additions and 33 deletions.
68 changes: 35 additions & 33 deletions rust/kernel/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,21 +481,22 @@ pub enum Either<L, R> {
/// All bit-patterns must be valid for this type. This type must not have interior mutability.
pub unsafe trait FromBytes {}

// SAFETY: All bit patterns are acceptable values of the types below.
unsafe impl FromBytes for u8 {}
unsafe impl FromBytes for u16 {}
unsafe impl FromBytes for u32 {}
unsafe impl FromBytes for u64 {}
unsafe impl FromBytes for usize {}
unsafe impl FromBytes for i8 {}
unsafe impl FromBytes for i16 {}
unsafe impl FromBytes for i32 {}
unsafe impl FromBytes for i64 {}
unsafe impl FromBytes for isize {}
// SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit
// patterns are also acceptable for arrays of that type.
unsafe impl<T: FromBytes> FromBytes for [T] {}
unsafe impl<T: FromBytes, const N: usize> FromBytes for [T; N] {}
macro_rules! impl_frombytes {
($($({$($generics:tt)*})? $t:ty, )*) => {
$(unsafe impl$($($generics)*)? FromBytes for $t {})*
};
}

impl_frombytes! {
// SAFETY: All bit patterns are acceptable values of the types below.
u8, u16, u32, u64, usize,
i8, i16, i32, i64, isize,

// SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit
// patterns are also acceptable for arrays of that type.
{<T: FromBytes>} [T],
{<T: FromBytes, const N: usize>} [T; N],
}

/// Types that can be viewed as an immutable slice of initialized bytes.
///
Expand All @@ -514,21 +515,22 @@ unsafe impl<T: FromBytes, const N: usize> FromBytes for [T; N] {}
/// mutability.
pub unsafe trait AsBytes {}

// SAFETY: Instances of the following types have no uninitialized portions.
unsafe impl AsBytes for u8 {}
unsafe impl AsBytes for u16 {}
unsafe impl AsBytes for u32 {}
unsafe impl AsBytes for u64 {}
unsafe impl AsBytes for usize {}
unsafe impl AsBytes for i8 {}
unsafe impl AsBytes for i16 {}
unsafe impl AsBytes for i32 {}
unsafe impl AsBytes for i64 {}
unsafe impl AsBytes for isize {}
unsafe impl AsBytes for bool {}
unsafe impl AsBytes for char {}
unsafe impl AsBytes for str {}
// SAFETY: If individual values in an array have no uninitialized portions, then the array itself
// does not have any uninitialized portions either.
unsafe impl<T: AsBytes> AsBytes for [T] {}
unsafe impl<T: AsBytes, const N: usize> AsBytes for [T; N] {}
macro_rules! impl_asbytes {
($($({$($generics:tt)*})? $t:ty, )*) => {
$(unsafe impl$($($generics)*)? AsBytes for $t {})*
};
}

impl_asbytes! {
// SAFETY: Instances of the following types have no uninitialized portions.
u8, u16, u32, u64, usize,
i8, i16, i32, i64, isize,
bool,
char,
str,

// SAFETY: If individual values in an array have no uninitialized portions, then the array
// itself does not have any uninitialized portions either.
{<T: AsBytes>} [T],
{<T: AsBytes, const N: usize>} [T; N],
}

0 comments on commit 8126b58

Please sign in to comment.