mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 14:18:04 +08:00
Rework DynAnyNode design to work with the borrow stack (#796)
This commit is contained in:
committed by
Keavon Chambers
parent
cef58b16c2
commit
562217015d
@@ -25,12 +25,20 @@ pub fn downcast_ref<'a, V: StaticType>(i: &'a dyn DynAny<'a>) -> Option<&'a V> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn downcast<'a, V: StaticType>(i: Box<dyn DynAny<'a> + 'a>) -> Option<Box<V>> {
|
||||
if i.type_id() == std::any::TypeId::of::<<V as StaticType>::Static>() {
|
||||
let type_id = DynAny::type_id(i.as_ref());
|
||||
if type_id == std::any::TypeId::of::<<V as StaticType>::Static>() {
|
||||
// SAFETY: caller guarantees that T is the correct type
|
||||
let ptr = Box::into_raw(i) as *mut dyn DynAny<'a> as *mut V;
|
||||
Some(unsafe { Box::from_raw(ptr) })
|
||||
} else {
|
||||
// TODO: add log error
|
||||
if type_id == std::any::TypeId::of::<&dyn DynAny<'static>>() {
|
||||
panic!("downcast error: type_id == std::any::TypeId::of::<dyn DynAny<'a>>()");
|
||||
}
|
||||
println!("expected: {:?}", std::any::TypeId::of::<<V as StaticType>::Static>());
|
||||
println!("actual one: {:?}", type_id);
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -94,13 +102,29 @@ impl<'a> StaticType for &'a str {
|
||||
impl StaticType for () {
|
||||
type Static = ();
|
||||
}
|
||||
impl<'a, T: 'a + StaticType> StaticType for &'a T {
|
||||
impl<'a, T: 'a + StaticType + ?Sized> StaticType for &'a T {
|
||||
type Static = &'static <T as StaticType>::Static;
|
||||
}
|
||||
impl<T: StaticTypeSized, const N: usize> StaticType for [T; N] {
|
||||
type Static = [<T as StaticTypeSized>::Static; N];
|
||||
}
|
||||
|
||||
impl<'a> StaticType for dyn DynAny<'a> + '_ {
|
||||
type Static = dyn DynAny<'static>;
|
||||
}
|
||||
pub trait IntoDynAny<'n>: Sized + StaticType + 'n {
|
||||
fn into_dyn(self) -> Box<dyn DynAny<'n> + 'n> {
|
||||
Box::new(self)
|
||||
}
|
||||
}
|
||||
impl<'n, T: StaticType + 'n> IntoDynAny<'n> for T {}
|
||||
|
||||
impl From<()> for Box<dyn DynAny<'static>> {
|
||||
fn from(_: ()) -> Box<dyn DynAny<'static>> {
|
||||
Box::new(())
|
||||
}
|
||||
}
|
||||
|
||||
use core::{
|
||||
cell::{Cell, RefCell, UnsafeCell},
|
||||
iter::Empty,
|
||||
@@ -117,12 +141,21 @@ use std::{
|
||||
|
||||
impl_type!(Option<T>,Result<T, E>,Cell<T>,UnsafeCell<T>,RefCell<T>,MaybeUninit<T>,
|
||||
Vec<T>, String, BTreeMap<K,V>,BTreeSet<V>, LinkedList<T>, VecDeque<T>,
|
||||
BinaryHeap<T>, Box<T>, ManuallyDrop<T>, PhantomData<T>, PhantomPinned,Empty<T>,
|
||||
BinaryHeap<T>, ManuallyDrop<T>, PhantomData<T>, PhantomPinned,Empty<T>,
|
||||
Wrapping<T>, Duration, Once, Mutex<T>, RwLock<T>, bool, f32, f64, char,
|
||||
u8, AtomicU8, u16,AtomicU16, u32,AtomicU32, u64,AtomicU64, usize,AtomicUsize,
|
||||
i8,AtomicI8, i16,AtomicI16, i32,AtomicI32, i64,AtomicI64, isize,AtomicIsize,
|
||||
i128, u128, AtomicBool, AtomicPtr<T>
|
||||
);
|
||||
|
||||
impl<T: crate::StaticType + ?Sized> crate::StaticType for Box<T> {
|
||||
type Static = Box<<T as crate::StaticType>::Static>;
|
||||
}
|
||||
fn test() {
|
||||
let foo = (Box::new(&1 as &dyn DynAny<'static>), Box::new(&2 as &dyn DynAny<'static>));
|
||||
//let bar = &foo as &dyn DynAny<'static>;
|
||||
}
|
||||
|
||||
macro_rules! impl_tuple {
|
||||
(@rec $t:ident) => { };
|
||||
(@rec $_:ident $($t:ident)+) => {
|
||||
@@ -148,3 +181,9 @@ fn simple_downcast() {
|
||||
let x = Box::new(3_u32) as Box<dyn DynAny>;
|
||||
assert_eq!(*downcast::<u32>(x).unwrap(), 3_u32);
|
||||
}
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn simple_downcast_panic() {
|
||||
let x = Box::new(3_i32) as Box<dyn DynAny>;
|
||||
assert_eq!(*downcast::<u32>(x).expect("attempted to perform invalid downcast"), 3_u32);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user