fix UB =)

This commit is contained in:
numzero 2026-09-23 20:36:04 +03:00
parent 9b6fe632bb
commit 830adfbc10

View File

@ -25,8 +25,16 @@ pub struct Dyn<'a, Trait: ?Sized + 'a> {
impl<'a, Trait: ?Sized + 'a> Dyn<'a, Trait> { impl<'a, Trait: ?Sized + 'a> Dyn<'a, Trait> {
pub type Target = Trait; pub type Target = Trait;
fn as_ptr(&self) -> *const Self::Target { /// SAFETY:
ptr::from_raw_parts::<Trait>(&self.data, self.meta) /// 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; type Target = Trait;
fn deref(&self) -> &Self::Target { 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> { impl<'a, Trait: ?Sized + 'a> ops::DerefMut for Dyn<'a, Trait> {
fn deref_mut(&mut self) -> &mut Self::Target { 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() }
} }
} }