rust: io: add static cast() method for views

Add a compile-time checked variant of `try_cast()` using the minimum size
and alignment information.

Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260805-typed_register-v2-1-c3ca142220a0@garyguo.net
[ecourtney: fix the doc example type and doc grammar per v2 review]
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Link: https://patch.msgid.link/20260827-pramin-split-v3-5-24b24d7afc52@nvidia.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
This commit is contained in:
Gary Guo 2026-08-27 17:51:46 +09:00 committed by Alexandre Courbot
parent b05ff82081
commit 9aa6069d62

View File

@ -447,6 +447,45 @@ fn is_empty<T>(self) -> bool
self.len() == 0
}
/// Convert into a different typed I/O view.
///
/// The target type must be known (statically) to be of the same or smaller size to current
/// type, and the current view must be properly aligned for the target type.
///
/// # Examples
///
/// ```no_run
/// use kernel::io::{
/// io_project,
/// Mmio,
/// Io,
/// Region,
/// };
/// #[derive(FromBytes, IntoBytes)]
/// #[repr(C)]
/// struct MyStruct { field: u32, }
///
/// # fn test(mmio: &Mmio<'_, Region<0x1000>>) {
/// // let mmio: Mmio<'_, Region<0x1000>>;
/// let whole: Mmio<'_, MyStruct> = mmio.cast();
/// # }
/// ```
#[inline]
fn cast<U>(self) -> <Self::Backend as IoBackend>::View<'a, U>
where
Self::Target: FromBytes + IntoBytes,
U: FromBytes + IntoBytes,
{
let view = self.as_view();
let ptr = Self::Backend::as_ptr(view);
const_assert!(size_of::<U>() <= Self::Target::MIN_SIZE);
const_assert!(align_of::<U>() <= Self::Target::MIN_ALIGN.as_usize());
// SAFETY: We have checked bounds and alignment, so this is a valid projection.
unsafe { Self::Backend::project_view(view, ptr.cast()) }
}
/// Try to convert into a different typed I/O view.
///
/// A runtime check is performed to ensure that the target type is of same or smaller size to