|
3 | 3 | use alloc::boxed::Box; |
4 | 4 | use core::{ |
5 | 5 | any::{Any, TypeId}, |
| 6 | + mem::size_of, |
6 | 7 | ptr::addr_of, |
7 | 8 | }; |
8 | 9 |
|
@@ -43,21 +44,41 @@ macro_rules! impl_asany { |
43 | 44 | /// |
44 | 45 | /// # Note |
45 | 46 | /// Probably not safe for future compilers, fine for now. |
| 47 | +/// The size changed in later rust versions, see <https://github.com/rust-lang/compiler-team/issues/608> |
| 48 | +#[inline] |
46 | 49 | #[must_use] |
47 | | -pub fn pack_type_id(id: u64) -> TypeId { |
48 | | - assert_eq_size!(TypeId, u64); |
49 | | - unsafe { *(addr_of!(id) as *const TypeId) } |
| 50 | +pub const fn pack_type_id(id: u128) -> TypeId { |
| 51 | + match size_of::<TypeId>() { |
| 52 | + 8 => { |
| 53 | + let id_64 = id as u64; |
| 54 | + unsafe { *(addr_of!(id_64) as *const TypeId) } |
| 55 | + } |
| 56 | + 16 => unsafe { *(addr_of!(id) as *const TypeId) }, |
| 57 | + _ => { |
| 58 | + // TypeId size of this size is not yet supported" |
| 59 | + panic!("Unsupported size for TypeId"); |
| 60 | + } |
| 61 | + } |
50 | 62 | } |
51 | 63 |
|
52 | 64 | /// Unpack a `type_id` to an `u64` |
53 | 65 | /// Opposite of [`pack_type_id(id)`]. |
54 | 66 | /// |
55 | 67 | /// # Note |
56 | 68 | /// Probably not safe for future compilers, fine for now. |
| 69 | +/// The size changed in later rust versions, see <https://github.com/rust-lang/compiler-team/issues/608> |
| 70 | +#[inline] |
57 | 71 | #[must_use] |
58 | | -pub fn unpack_type_id(id: TypeId) -> u64 { |
59 | | - assert_eq_size!(TypeId, u64); |
60 | | - unsafe { *(addr_of!(id) as *const u64) } |
| 72 | +pub const fn unpack_type_id(id: TypeId) -> u128 { |
| 73 | + #[allow(clippy::cast_ptr_alignment)] // we never actually cast to u128 if the type is u64. |
| 74 | + match size_of::<TypeId>() { |
| 75 | + 8 => unsafe { *(addr_of!(id) as *const u64) as u128 }, |
| 76 | + 16 => unsafe { *(addr_of!(id) as *const u128) }, |
| 77 | + _ => { |
| 78 | + // TypeId size of this size is not yet supported" |
| 79 | + panic!("Unsupported size for TypeId"); |
| 80 | + } |
| 81 | + } |
61 | 82 | } |
62 | 83 |
|
63 | 84 | /// Create `AnyMap` and `NamedAnyMap` for a given trait |
@@ -432,3 +453,22 @@ macro_rules! create_anymap_for_trait { |
432 | 453 | } |
433 | 454 | } |
434 | 455 | } |
| 456 | + |
| 457 | +#[cfg(test)] |
| 458 | +mod test { |
| 459 | + use core::any::TypeId; |
| 460 | + |
| 461 | + use super::{pack_type_id, unpack_type_id}; |
| 462 | + |
| 463 | + #[test] |
| 464 | + fn test_type_id() { |
| 465 | + let type_id_u64 = unpack_type_id(TypeId::of::<u64>()); |
| 466 | + let type_id_u128 = unpack_type_id(TypeId::of::<u128>()); |
| 467 | + |
| 468 | + assert_eq!(pack_type_id(type_id_u64), TypeId::of::<u64>()); |
| 469 | + assert_eq!(pack_type_id(type_id_u128), TypeId::of::<u128>()); |
| 470 | + |
| 471 | + assert_ne!(pack_type_id(type_id_u64), TypeId::of::<u128>()); |
| 472 | + assert_ne!(pack_type_id(type_id_u128), TypeId::of::<u64>()); |
| 473 | + } |
| 474 | +} |
0 commit comments