fix UB =)
This commit is contained in:
parent
9b6fe632bb
commit
830adfbc10
18
src/lib.rs
18
src/lib.rs
|
|
@ -25,8 +25,16 @@ pub struct Dyn<'a, Trait: ?Sized + 'a> {
|
|||
impl<'a, Trait: ?Sized + 'a> Dyn<'a, Trait> {
|
||||
pub type Target = Trait;
|
||||
|
||||
fn as_ptr(&self) -> *const Self::Target {
|
||||
ptr::from_raw_parts::<Trait>(&self.data, self.meta)
|
||||
/// SAFETY:
|
||||
/// The `meta` field in `this` must be valid for reading.
|
||||
///
|
||||
/// The returned pointer inherits validity from the input pointer.
|
||||
unsafe fn ptr(this: *mut Self) -> *mut Self::Target {
|
||||
let pmeta = &raw const (*this).meta;
|
||||
// SAFETY: `meta` is valid for reading, per the function safety requirement.
|
||||
let meta = unsafe { *pmeta };
|
||||
let pdata = &raw mut (*this).data;
|
||||
ptr::from_raw_parts_mut::<Trait>(pdata, meta)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -34,13 +42,15 @@ impl<'a, Trait: ?Sized + 'a> ops::Deref for Dyn<'a, Trait> {
|
|||
type Target = Trait;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { self.as_ptr().as_ref_unchecked() }
|
||||
// SAFETY: `self` is valid for reading.
|
||||
unsafe { Self::ptr(self as *const Self as *mut Self).as_ref_unchecked() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Trait: ?Sized + 'a> ops::DerefMut for Dyn<'a, Trait> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
unsafe { self.as_ptr().cast_mut().as_mut_unchecked() }
|
||||
// SAFETY: `self` is valid for writing.
|
||||
unsafe { Self::ptr(self as *mut Self).as_mut_unchecked() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user