rust/zerocopy/src/util/macro_util.rs

Source file repositories/reference/linux-study-clean/rust/zerocopy/src/util/macro_util.rs

File Facts

System
Linux kernel
Corpus path
rust/zerocopy/src/util/macro_util.rs
Extension
.rs
Size
55845 bytes
Lines
1311
Domain
Rust Kernel Layer
Bucket
Rust API Membrane
Inferred role
Rust Kernel Layer: implementation source
Status
source implementation candidate

Why This File Exists

Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.

Dependency Surface

Detected Declarations

Annotated Snippet

struct OffsetOfTrailingIsAlignment {
            _byte: u8,
            _trailing: $ty,
        }

        trailing_field_offset!(OffsetOfTrailingIsAlignment, _trailing)
    }};
}

mod size_to_tag {
    pub trait SizeToTag<const SIZE: usize> {
        type Tag;
    }

    impl SizeToTag<1> for () {
        type Tag = u8;
    }
    impl SizeToTag<2> for () {
        type Tag = u16;
    }
    impl SizeToTag<4> for () {
        type Tag = u32;
    }
    impl SizeToTag<8> for () {
        type Tag = u64;
    }
    impl SizeToTag<16> for () {
        type Tag = u128;
    }
}

/// An alias for the unsigned integer of the given size in bytes.
#[doc(hidden)]
pub type SizeToTag<const SIZE: usize> = <() as size_to_tag::SizeToTag<SIZE>>::Tag;

// We put `Sized` in its own module so it can have the same name as the standard
// library `Sized` without shadowing it in the parent module.
#[cfg(not(no_zerocopy_diagnostic_on_unimplemented_1_78_0))]
mod __size_of {
    #[diagnostic::on_unimplemented(
        message = "`{Self}` is unsized",
        label = "`IntoBytes` needs all field types to be `Sized` in order to determine whether there is padding",
        note = "consider using `#[repr(packed)]` to remove padding",
        note = "`IntoBytes` does not require the fields of `#[repr(packed)]` types to be `Sized`"
    )]
    pub trait Sized: core::marker::Sized {}
    impl<T: core::marker::Sized> Sized for T {}

    #[inline(always)]
    #[must_use]
    #[allow(clippy::needless_maybe_sized)]
    pub const fn size_of<T: Sized + ?core::marker::Sized>() -> usize {
        core::mem::size_of::<T>()
    }
}

#[cfg(no_zerocopy_diagnostic_on_unimplemented_1_78_0)]
pub use core::mem::size_of;

#[cfg(not(no_zerocopy_diagnostic_on_unimplemented_1_78_0))]
pub use __size_of::size_of;

/// How many padding bytes does the struct type `$t` have?
///
/// `$ts` is the list of the type of every field in `$t`. `$t` must be a struct
/// type, or else `struct_padding!`'s result may be meaningless.
///
/// Note that `struct_padding!`'s results are independent of `repcr` since they
/// only consider the size of the type and the sizes of the fields. Whatever the
/// repr, the size of the type already takes into account any padding that the
/// compiler has decided to add. Structs with well-defined representations (such
/// as `repr(C)`) can use this macro to check for padding. Note that while this
/// may yield some consistent value for some `repr(Rust)` structs, it is not
/// guaranteed across platforms or compilations.
#[doc(hidden)] // `#[macro_export]` bypasses this module's `#[doc(hidden)]`.
#[macro_export]
macro_rules! struct_padding {
    ($t:ty, $_align:expr, $_packed:expr, [$($ts:ty),*]) => {{
        // The `align` and `packed` directives can be ignored here. Regardless
        // of if and how they are set, comparing the size of `$t` to the sum of
        // its field sizes is a reliable indicator of the presence of padding.
        $crate::util::macro_util::size_of::<$t>() - (0 $(+ $crate::util::macro_util::size_of::<$ts>())*)
    }};
}

/// Does the `repr(C)` struct type `$t` have padding?
///
/// `$ts` is the list of the type of every field in `$t`. `$t` must be a
/// `repr(C)` struct type, or else `struct_has_padding!`'s result may be
/// meaningless.

Annotation

Implementation Notes