rust/kernel/list/impl_list_item_mod.rs

Source file repositories/reference/linux-study-clean/rust/kernel/list/impl_list_item_mod.rs

File Facts

System
Linux kernel
Corpus path
rust/kernel/list/impl_list_item_mod.rs
Extension
.rs
Size
15884 bytes
Lines
362
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

// SPDX-License-Identifier: GPL-2.0

// Copyright (C) 2024 Google LLC.

//! Helpers for implementing list traits safely.

/// Declares that this type has a [`ListLinks<ID>`] field.
///
/// This trait is only used to help implement [`ListItem`] safely. If [`ListItem`] is implemented
/// manually, then this trait is not needed. Use the [`impl_has_list_links!`] macro to implement
/// this trait.
///
/// # Safety
///
/// The methods on this trait must have exactly the behavior that the definitions given below have.
///
/// [`ListLinks<ID>`]: crate::list::ListLinks
/// [`ListItem`]: crate::list::ListItem
pub unsafe trait HasListLinks<const ID: u64 = 0> {
    /// Returns a pointer to the [`ListLinks<ID>`] field.
    ///
    /// # Safety
    ///
    /// The provided pointer must point at a valid struct of type `Self`.
    ///
    /// [`ListLinks<ID>`]: crate::list::ListLinks
    unsafe fn raw_get_list_links(ptr: *mut Self) -> *mut crate::list::ListLinks<ID>;
}

/// Implements the [`HasListLinks`] trait for the given type.
#[macro_export]
#[doc(hidden)]
macro_rules! impl_has_list_links {
    ($(impl$({$($generics:tt)*})?
       HasListLinks$(<$id:tt>)?
       for $self:ty
       { self$(.$field:ident)* }
    )*) => {$(
        // SAFETY: The implementation of `raw_get_list_links` only compiles if the field has the
        // right type.
        unsafe impl$(<$($generics)*>)? $crate::list::HasListLinks$(<$id>)? for $self {
            #[inline]
            unsafe fn raw_get_list_links(ptr: *mut Self) -> *mut $crate::list::ListLinks$(<$id>)? {
                // Statically ensure that `$(.field)*` doesn't follow any pointers.
                //
                // Cannot be `const` because `$self` may contain generics and E0401 says constants
                // "can't use {`Self`,generic parameters} from outer item".
                if false { let _: usize = ::core::mem::offset_of!(Self, $($field).*); }

                // SAFETY: The caller promises that the pointer is not dangling. We know that this
                // expression doesn't follow any pointers, as the `offset_of!` invocation above
                // would otherwise not compile.
                unsafe { ::core::ptr::addr_of_mut!((*ptr)$(.$field)*) }
            }
        }
    )*};
}
pub use impl_has_list_links;

/// Declares that the [`ListLinks<ID>`] field in this struct is inside a
/// [`ListLinksSelfPtr<T, ID>`].
///
/// # Safety
///
/// The [`ListLinks<ID>`] field of this struct at [`HasListLinks<ID>::raw_get_list_links`] must be
/// inside a [`ListLinksSelfPtr<T, ID>`].
///
/// [`ListLinks<ID>`]: crate::list::ListLinks
/// [`ListLinksSelfPtr<T, ID>`]: crate::list::ListLinksSelfPtr
pub unsafe trait HasSelfPtr<T: ?Sized, const ID: u64 = 0>
where
    Self: HasListLinks<ID>,
{
}

/// Implements the [`HasListLinks`] and [`HasSelfPtr`] traits for the given type.
#[macro_export]
#[doc(hidden)]
macro_rules! impl_has_list_links_self_ptr {
    ($(impl$({$($generics:tt)*})?
       HasSelfPtr<$item_type:ty $(, $id:tt)?>
       for $self:ty
       { self$(.$field:ident)* }
    )*) => {$(
        // SAFETY: The implementation of `raw_get_list_links` only compiles if the field has the
        // right type.
        unsafe impl$(<$($generics)*>)? $crate::list::HasSelfPtr<$item_type $(, $id)?> for $self {}

        // SAFETY: TODO.
        unsafe impl$(<$($generics)*>)? $crate::list::HasListLinks$(<$id>)? for $self {

Annotation

Implementation Notes