mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Refactor Capable::vtable
to return Option<NonNull<()>>
(#4252)
This commit is contained in:
parent
4929262610
commit
1694327b70
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user