Constructor checking
Constructor checking
Posted Oct 24, 2024 19:01 UTC (Thu) by ringerc (subscriber, #3071)In reply to: Constructor checking by epa
Parent article: Toward safe transmutation in Rust
In this case the type would want to be able to mark itself as able to be transmuted to, but only when the type itself is doing the transmuting. Essentially a private access marker trait. I don't know enough Rust to know if this is possible.
Posted Oct 28, 2024 7:43 UTC (Mon)
by NYKevin (subscriber, #129325)
[Link]
You can sort of do that now:
But this is just a thin wrapper around transmute. It's sound, in this case, but if MyType is more complicated, then you have all the problems that the article describes. The compiler is not going to do very much for you here (the only check that the compiler performs in the above example code is to make sure that a pointer-to-u8 is the same size as a pointer-to-MyType, which is rather obvious anyway).
(If this looks like a lot of boilerplate code, bear in mind that Rust has macros, so you don't have to write all of this out repeatedly if you're doing it a lot.)
Constructor checking
In this case the type would want to be able to mark itself as able to be transmuted to, but only when the type itself is doing the transmuting.
// Simple one-field struct as an example, can be replaced with a more complicated struct.
#[repr(C)] // But it does need to be repr(C) or repr(transparent)
struct MyType(u64);
use std::convert::TryFrom;
impl<'a> TryFrom<&'a [u8]> for &'a MyType {
type Error = &'static str; // XXX: In a real codebase, use a proper Error type and not a string.
fn try_from(x: &'a [u8]) -> Result<Self, &'static str> {
if x.len() != std::mem::size_of::<MyType>() {
return Err("Wrong size!");
}
let ptr: *const MyType = unsafe { std::mem::transmute(x.as_ptr()) };
if ptr.is_aligned() {
Ok(unsafe { &*ptr })
} else {
Err("Not aligned!")
}
}
}
// Implementation for &'a mut [u8] omitted because it's nearly identical.
// Now safe code can call try_from() and try_into() for this conversion.