diff options
| author | +merlan #flirora <uruwi@protonmail.com> | 2024-05-25 15:17:07 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-25 19:17:07 +0000 |
| commit | 1694327b707621454606d7c3ffd0ed7f603d87e9 (patch) | |
| tree | a3f501bd26ca59c3f24a4d60c95557000f341300 | |
| parent | 4929262610016280b455f3a79f4b150724a5acbe (diff) | |
Refactor `Capable::vtable` to return `Option<NonNull<()>>` (#4252)
| -rw-r--r-- | crates/typst-macros/src/elem.rs | 2 | ||||
| -rw-r--r-- | crates/typst-utils/src/fat.rs | 7 | ||||
| -rw-r--r-- | crates/typst/src/foundations/content.rs | 4 | ||||
| -rw-r--r-- | crates/typst/src/foundations/element.rs | 7 |
4 files changed, 12 insertions, 8 deletions
diff --git a/crates/typst-macros/src/elem.rs b/crates/typst-macros/src/elem.rs index ffc4d8c2..35dc8b75 100644 --- a/crates/typst-macros/src/elem.rs +++ b/crates/typst-macros/src/elem.rs @@ -845,7 +845,7 @@ fn create_capable_impl(element: &Elem) -> TokenStream { quote! { unsafe impl #foundations::Capable for #ident { - fn vtable(capability: ::std::any::TypeId) -> ::std::option::Option<*const ()> { + fn vtable(capability: ::std::any::TypeId) -> ::std::option::Option<::std::ptr::NonNull<()>> { let dangling = ::std::ptr::NonNull::<#foundations::Packed<#ident>>::dangling().as_ptr(); #(#checks)* None diff --git a/crates/typst-utils/src/fat.rs b/crates/typst-utils/src/fat.rs index d3c9bb20..b31a2bb1 100644 --- a/crates/typst-utils/src/fat.rs +++ b/crates/typst-utils/src/fat.rs @@ -7,6 +7,7 @@ use std::alloc::Layout; use std::mem; +use std::ptr::NonNull; /// Create a fat pointer from a data address and a vtable address. /// @@ -39,9 +40,11 @@ pub unsafe fn from_raw_parts_mut<T: ?Sized>(data: *mut (), vtable: *const ()) -> /// # Safety /// Must only be called when `T` is a `dyn Trait`. #[track_caller] -pub unsafe fn vtable<T: ?Sized>(ptr: *const T) -> *const () { +pub unsafe fn vtable<T: ?Sized>(ptr: *const T) -> NonNull<()> { debug_assert_eq!(Layout::new::<*const T>(), Layout::new::<FatPointer>()); - mem::transmute_copy::<*const T, FatPointer>(&ptr).vtable + NonNull::new_unchecked( + mem::transmute_copy::<*const T, FatPointer>(&ptr).vtable as *mut (), + ) } /// The memory representation of a trait object pointer. diff --git a/crates/typst/src/foundations/content.rs b/crates/typst/src/foundations/content.rs index 741deb36..d072640b 100644 --- a/crates/typst/src/foundations/content.rs +++ b/crates/typst/src/foundations/content.rs @@ -299,7 +299,7 @@ impl Content { // use a `*const Content` pointer. let vtable = self.elem().vtable()(TypeId::of::<C>())?; let data = self as *const Content as *const (); - Some(unsafe { &*fat::from_raw_parts(data, vtable) }) + Some(unsafe { &*fat::from_raw_parts(data, vtable.as_ptr()) }) } /// Cast to a mutable trait object if the contained element has the given @@ -319,7 +319,7 @@ impl Content { // mutable access is required. let vtable = self.elem().vtable()(TypeId::of::<C>())?; let data = self as *mut Content as *mut (); - Some(unsafe { &mut *fat::from_raw_parts_mut(data, vtable) }) + Some(unsafe { &mut *fat::from_raw_parts_mut(data, vtable.as_ptr()) }) } /// Whether the content is an empty sequence. diff --git a/crates/typst/src/foundations/element.rs b/crates/typst/src/foundations/element.rs index e58fc89e..6ffeadb9 100644 --- a/crates/typst/src/foundations/element.rs +++ b/crates/typst/src/foundations/element.rs @@ -2,6 +2,7 @@ use std::any::TypeId; use std::cmp::Ordering; use std::fmt::{self, Debug}; use std::hash::Hash; +use std::ptr::NonNull; use ecow::EcoString; use once_cell::sync::Lazy; @@ -81,7 +82,7 @@ impl Element { } /// The VTable for capabilities dispatch. - pub fn vtable(self) -> fn(of: TypeId) -> Option<*const ()> { + pub fn vtable(self) -> fn(of: TypeId) -> Option<NonNull<()>> { self.0.vtable } @@ -208,7 +209,7 @@ pub trait NativeElement: /// `TypeId::of::<dyn C>()`. pub unsafe trait Capable { /// Get the pointer to the vtable for the given capability / trait. - fn vtable(capability: TypeId) -> Option<*const ()>; + fn vtable(capability: TypeId) -> Option<NonNull<()>>; } /// Defines how fields of an element are accessed. @@ -275,7 +276,7 @@ pub struct NativeElementData { pub set: fn(&mut Engine, &mut Args) -> SourceResult<Styles>, /// Gets the vtable for one of this element's capabilities /// (see [`Capable`]). - pub vtable: fn(capability: TypeId) -> Option<*const ()>, + pub vtable: fn(capability: TypeId) -> Option<NonNull<()>>, /// Gets the numeric index of this field by its name. pub field_id: fn(name: &str) -> Option<u8>, /// Gets the name of a field by its numeric index. |
