diff --git a/drivers/common/src/lib.rs b/drivers/common/src/lib.rs index b6661e3aaa..0f2ada3cf6 100644 --- a/drivers/common/src/lib.rs +++ b/drivers/common/src/lib.rs @@ -329,3 +329,43 @@ impl VirtaddrTranslationHandle { Ok(usize::from_ne_bytes(buf)) } } + +#[cfg(test)] +mod physmap_type_assertions { + use super::*; + + /// If `physmap` ever changes its error type, this test fails to + /// compile and surfaces the regression at `cargo check` time on the + /// host rather than during a full Redox cross-build. + /// + /// The check uses `std::mem::size_of_val` on a constructed error + /// value. `libredox::error::Error` is `pub struct { errno: u16 }`, + /// so its `size_of_val` is exactly `size_of::() == 2`. A + /// future change to a different error type (e.g. + /// `syscall::error::Error { errno: i32 }` which would be 4 bytes) + /// would change this constant and force a maintainer to update + /// both the assertion and the downstream `map_err` adapters in + /// lockstep — making the type drift visible at review time rather + /// than at build time. + #[test] + fn physmap_returns_libredox_error_result() { + // Reference layout: `libredox::error::Error { errno: u16 }`. + // If this changes the size assertion below must be updated. + const EXPECTED_SIZE: usize = std::mem::size_of::(); + + // Reference error type used at the assertion site. + let reference: libredox::error::Error = libredox::error::Error::new(0); + assert_eq!(std::mem::size_of_val(&reference), EXPECTED_SIZE); + + // Coercion check: the function pointer signature must be + // mappable to the expected return type. If physmap's error + // type drifts (e.g. from `libredox::error::Error` to + // `syscall::error::Error` or `std::io::Error`), this coercion + // fails to compile. We never call `f` — we only borrow its + // signature. + let _f: PhysmapSig = physmap; + } + + /// Concrete signature of `physmap` for the assertion above. + type PhysmapSig = unsafe fn(usize, usize, Prot, MemoryType) -> libredox::error::Result<*mut ()>; +}