From d91cd1bc3a33be4b7ae819c4ea675716b3036fd6 Mon Sep 17 00:00:00 2001 From: Aumetra Weisman Date: Tue, 12 Nov 2024 15:24:27 +0100 Subject: [PATCH] More robust non-static type equality --- packages/cw-schema/src/lib.rs | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/packages/cw-schema/src/lib.rs b/packages/cw-schema/src/lib.rs index 8aaa809b9..b0e80c2c9 100644 --- a/packages/cw-schema/src/lib.rs +++ b/packages/cw-schema/src/lib.rs @@ -6,7 +6,7 @@ extern crate alloc; extern crate std; use alloc::{borrow::Cow, collections::BTreeMap, vec::Vec}; -use core::hash::BuildHasherDefault; +use core::{any::TypeId, hash::BuildHasherDefault, marker::PhantomData}; use indexmap::IndexMap; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; @@ -142,27 +142,32 @@ pub enum Schema { } #[derive(Hash, PartialEq, Eq)] -pub struct Identifier(usize); +pub struct Identifier(TypeId); impl Identifier { pub fn of() -> Self where T: ?Sized, { - // Don't do this at home. I'm a professional. + // Taken from : https://github.com/sagebind/castaway/blob/a7baeab32d75d0f105d1415210a2867d213f8818/src/utils.rs#L36 // - // This is a hack based on the assumption that each type has will produce a unique monomorphized function. - // Therefore each function has a distinct function pointer. - // - // The compiler _might_ break this assumption in the future. - #[inline] - fn type_id_of() -> usize { - type_id_of:: as usize + // Seems more robust than the previous implementation. + trait NonStaticAny { + fn get_type_id(&self) -> TypeId where Self: 'static; + } + + impl NonStaticAny for PhantomData { + fn get_type_id(&self) -> TypeId where Self: 'static { + TypeId::of::() + } } - debug_assert_eq!(type_id_of::(), type_id_of::()); + let phantom = PhantomData::; + let ty_id = NonStaticAny::get_type_id(unsafe { + core::mem::transmute::<&dyn NonStaticAny, &(dyn NonStaticAny + 'static)>(&phantom) + }); - Self(type_id_of::()) + Identifier(ty_id) } }