Fix AnyMap for TypeIds with 128 bit (#1311)
* Fix AnyMap for TypeIds with 128 bit * make const * added test, removed static_assertions
This commit is contained in:
parent
fa63493cee
commit
62b1bde7a9
@ -67,7 +67,6 @@ serde = { version = "1.0", default-features = false, features = ["alloc", "deriv
|
|||||||
erased-serde = { version = "0.3.21", default-features = false, features = ["alloc"] } # erased serde
|
erased-serde = { version = "0.3.21", default-features = false, features = ["alloc"] } # erased serde
|
||||||
postcard = { version = "1.0", features = ["alloc"] } # no_std compatible serde serialization fromat
|
postcard = { version = "1.0", features = ["alloc"] } # no_std compatible serde serialization fromat
|
||||||
bincode = {version = "1.3", optional = true }
|
bincode = {version = "1.3", optional = true }
|
||||||
static_assertions = "1.1.0"
|
|
||||||
c2rust-bitfields = { version = "0.17", features = ["no_std"] }
|
c2rust-bitfields = { version = "0.17", features = ["no_std"] }
|
||||||
num_enum = { version = "0.5.7", default-features = false }
|
num_enum = { version = "0.5.7", default-features = false }
|
||||||
typed-builder = "0.14" # Implement the builder pattern at compiletime
|
typed-builder = "0.14" # Implement the builder pattern at compiletime
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use core::{
|
use core::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
|
mem::size_of,
|
||||||
ptr::addr_of,
|
ptr::addr_of,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -43,10 +44,21 @@ macro_rules! impl_asany {
|
|||||||
///
|
///
|
||||||
/// # Note
|
/// # Note
|
||||||
/// Probably not safe for future compilers, fine for now.
|
/// Probably not safe for future compilers, fine for now.
|
||||||
|
/// The size changed in later rust versions, see <https://github.com/rust-lang/compiler-team/issues/608>
|
||||||
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn pack_type_id(id: u64) -> TypeId {
|
pub const fn pack_type_id(id: u128) -> TypeId {
|
||||||
assert_eq_size!(TypeId, u64);
|
match size_of::<TypeId>() {
|
||||||
unsafe { *(addr_of!(id) as *const TypeId) }
|
8 => {
|
||||||
|
let id_64 = id as u64;
|
||||||
|
unsafe { *(addr_of!(id_64) as *const TypeId) }
|
||||||
|
}
|
||||||
|
16 => unsafe { *(addr_of!(id) as *const TypeId) },
|
||||||
|
_ => {
|
||||||
|
// TypeId size of this size is not yet supported"
|
||||||
|
panic!("Unsupported size for TypeId");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unpack a `type_id` to an `u64`
|
/// Unpack a `type_id` to an `u64`
|
||||||
@ -54,10 +66,19 @@ pub fn pack_type_id(id: u64) -> TypeId {
|
|||||||
///
|
///
|
||||||
/// # Note
|
/// # Note
|
||||||
/// Probably not safe for future compilers, fine for now.
|
/// Probably not safe for future compilers, fine for now.
|
||||||
|
/// The size changed in later rust versions, see <https://github.com/rust-lang/compiler-team/issues/608>
|
||||||
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn unpack_type_id(id: TypeId) -> u64 {
|
pub const fn unpack_type_id(id: TypeId) -> u128 {
|
||||||
assert_eq_size!(TypeId, u64);
|
#[allow(clippy::cast_ptr_alignment)] // we never actually cast to u128 if the type is u64.
|
||||||
unsafe { *(addr_of!(id) as *const u64) }
|
match size_of::<TypeId>() {
|
||||||
|
8 => unsafe { *(addr_of!(id) as *const u64) as u128 },
|
||||||
|
16 => unsafe { *(addr_of!(id) as *const u128) },
|
||||||
|
_ => {
|
||||||
|
// TypeId size of this size is not yet supported"
|
||||||
|
panic!("Unsupported size for TypeId");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create `AnyMap` and `NamedAnyMap` for a given trait
|
/// Create `AnyMap` and `NamedAnyMap` for a given trait
|
||||||
@ -432,3 +453,22 @@ macro_rules! create_anymap_for_trait {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use core::any::TypeId;
|
||||||
|
|
||||||
|
use super::{pack_type_id, unpack_type_id};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_type_id() {
|
||||||
|
let type_id_u64 = unpack_type_id(TypeId::of::<u64>());
|
||||||
|
let type_id_u128 = unpack_type_id(TypeId::of::<u128>());
|
||||||
|
|
||||||
|
assert_eq!(pack_type_id(type_id_u64), TypeId::of::<u64>());
|
||||||
|
assert_eq!(pack_type_id(type_id_u128), TypeId::of::<u128>());
|
||||||
|
|
||||||
|
assert_ne!(pack_type_id(type_id_u64), TypeId::of::<u128>());
|
||||||
|
assert_ne!(pack_type_id(type_id_u128), TypeId::of::<u64>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -100,7 +100,7 @@ macro_rules! create_serde_registry_for_trait {
|
|||||||
where
|
where
|
||||||
V: serde::de::SeqAccess<'de>,
|
V: serde::de::SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
let id: u64 = visitor.next_element()?.unwrap();
|
let id: u128 = visitor.next_element()?.unwrap();
|
||||||
let cb = unsafe {
|
let cb = unsafe {
|
||||||
*REGISTRY
|
*REGISTRY
|
||||||
.deserializers
|
.deserializers
|
||||||
@ -117,7 +117,7 @@ macro_rules! create_serde_registry_for_trait {
|
|||||||
|
|
||||||
#[allow(unused_qualifications)]
|
#[allow(unused_qualifications)]
|
||||||
struct Registry {
|
struct Registry {
|
||||||
deserializers: Option<HashMap<u64, DeserializeCallback<dyn $trait_name>>>,
|
deserializers: Option<HashMap<u128, DeserializeCallback<dyn $trait_name>>>,
|
||||||
finalized: bool,
|
finalized: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ macro_rules! create_serde_registry_for_trait {
|
|||||||
/// in the registry
|
/// in the registry
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct SerdeAnyMap {
|
pub struct SerdeAnyMap {
|
||||||
map: HashMap<u64, Box<dyn $trait_name>>,
|
map: HashMap<u128, Box<dyn $trait_name>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cloning by serializing and deserializing. It ain't fast, but it's honest work.
|
// Cloning by serializing and deserializing. It ain't fast, but it's honest work.
|
||||||
@ -301,7 +301,7 @@ macro_rules! create_serde_registry_for_trait {
|
|||||||
#[allow(unused_qualifications)]
|
#[allow(unused_qualifications)]
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct NamedSerdeAnyMap {
|
pub struct NamedSerdeAnyMap {
|
||||||
map: HashMap<u64, HashMap<u64, Box<dyn $trait_name>>>,
|
map: HashMap<u128, HashMap<u64, Box<dyn $trait_name>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cloning by serializing and deserializing. It ain't fast, but it's honest work.
|
// Cloning by serializing and deserializing. It ain't fast, but it's honest work.
|
||||||
@ -467,8 +467,8 @@ macro_rules! create_serde_registry_for_trait {
|
|||||||
pub fn all_typeids(
|
pub fn all_typeids(
|
||||||
&self,
|
&self,
|
||||||
) -> core::iter::Map<
|
) -> core::iter::Map<
|
||||||
Keys<'_, u64, HashMap<u64, Box<dyn $trait_name>>>,
|
Keys<'_, u128, HashMap<u64, Box<dyn $trait_name>>>,
|
||||||
fn(&u64) -> TypeId,
|
fn(&u128) -> TypeId,
|
||||||
> {
|
> {
|
||||||
self.map.keys().map(|x| pack_type_id(*x))
|
self.map.keys().map(|x| pack_type_id(*x))
|
||||||
}
|
}
|
||||||
|
@ -79,8 +79,6 @@ extern crate std;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub extern crate alloc;
|
pub extern crate alloc;
|
||||||
#[macro_use]
|
|
||||||
extern crate static_assertions;
|
|
||||||
#[cfg(feature = "ctor")]
|
#[cfg(feature = "ctor")]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use ctor::ctor;
|
pub use ctor::ctor;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user