1use core::{
2 fmt::Debug,
3 marker::PhantomData,
4 num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroU8, NonZeroU16, NonZeroU32},
5 ptr::NonNull,
6};
7
8pub unsafe trait AsPackedValue: Sized {
20 const MIN_BIT_WIDTH: usize;
22 fn encode(zelf: Self) -> TruncatedU64<Self>;
25
26 unsafe fn decode(raw: TruncatedU64<Self>) -> Self;
30
31 fn is_rt_safe() -> bool;
33}
34
35#[repr(transparent)]
37pub struct TruncatedU64<T> {
38 v: u64,
39 _phantom: PhantomData<T>,
40}
41
42impl<T> Clone for TruncatedU64<T> {
43 fn clone(&self) -> Self {
44 *self
45 }
46}
47
48impl<T> Copy for TruncatedU64<T> {}
49
50impl<T> Debug for TruncatedU64<T> {
51 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
52 f.debug_struct("TruncatedU64")
53 .field("value", &self.v)
54 .finish()
55 }
56}
57
58impl<T> PartialEq for TruncatedU64<T> {
59 fn eq(&self, other: &Self) -> bool {
60 self.v.eq(&other.v)
61 }
62}
63
64impl<T> Eq for TruncatedU64<T> {}
65
66impl<T> TruncatedU64<T> {
67 pub fn read(&self) -> u64 {
69 self.v
70 }
71}
72
73impl<T: AsPackedValue> TruncatedU64<T> {
74 pub fn new(mut value: u64) -> Self {
77 if T::MIN_BIT_WIDTH < 64 {
79 value = unpack!((value): T::MIN_BIT_WIDTH).1;
80 }
81 Self {
82 v: value,
83 _phantom: PhantomData,
84 }
85 }
86}
87
88macro_rules! atomic_encode_primitive {
89 ($type:ty) => {
90 unsafe impl $crate::core::AsPackedValue for $type {
93 const MIN_BIT_WIDTH: usize = size_of::<$type>() * 8;
94
95 fn encode(zelf: Self) -> $crate::core::TruncatedU64<Self> {
96 $crate::core::TruncatedU64::new(zelf as u64)
97 }
98
99 unsafe fn decode(raw: $crate::core::TruncatedU64<Self>) -> Self {
100 (raw.read()) as Self
101 }
102
103 fn is_rt_safe() -> bool {
104 true
105 }
106 }
107 };
108}
109
110macro_rules! atomic_encode_non_zero_primitive {
111 ($type:ty, $raw:ty) => {
112 unsafe impl $crate::core::AsPackedValue for $type {
115 const MIN_BIT_WIDTH: usize = size_of::<$type>() * 8;
116
117 fn encode(zelf: Self) -> $crate::core::TruncatedU64<Self> {
118 $crate::core::TruncatedU64::new(zelf.get() as u64)
119 }
120
121 unsafe fn decode(raw: $crate::core::TruncatedU64<Self>) -> Self {
122 Self::new(raw.read() as $raw)
123 .expect("trying to construct a NonZero from a zero value")
124 }
125
126 fn is_rt_safe() -> bool {
127 true
128 }
129 }
130 };
131}
132
133atomic_encode_primitive!(u32);
134atomic_encode_primitive!(u16);
135atomic_encode_primitive!(u8);
136atomic_encode_primitive!(i32);
137atomic_encode_primitive!(i16);
138atomic_encode_primitive!(i8);
139
140atomic_encode_non_zero_primitive!(NonZeroU32, u32);
141atomic_encode_non_zero_primitive!(NonZeroU16, u16);
142atomic_encode_non_zero_primitive!(NonZeroU8, u8);
143atomic_encode_non_zero_primitive!(NonZeroI32, i32);
144atomic_encode_non_zero_primitive!(NonZeroI16, i16);
145atomic_encode_non_zero_primitive!(NonZeroI8, i8);
146
147unsafe impl AsPackedValue for () {
150 const MIN_BIT_WIDTH: usize = 0;
151
152 fn encode(_zelf: Self) -> TruncatedU64<Self> {
153 TruncatedU64::new(0)
154 }
155
156 unsafe fn decode(_raw: TruncatedU64<Self>) -> Self {}
159
160 fn is_rt_safe() -> bool {
161 true
162 }
163}
164
165#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
170mod bit64 {
171 use super::*;
172
173 fn assert_ptr_safety() {
174 let dummy = 42;
175 let raw = &dummy as *const i32;
176 let addr = raw as u64;
177 let top_16 = addr >> 48;
178 let bit_47 = (addr >> 47) & 1;
179
180 assert!(
181 (bit_47 == 0 && top_16 == 0) || (bit_47 == 1 && top_16 == 0xFFFF),
182 "Pointer {raw:p} exceeds 48-bit address space! AsPackedValue is unsafe here. Consider using a PooledQueue, a Tagged128 Slot or a custom ptrlike value encodeable in <= 48bits.",
183 );
184 }
185
186 unsafe impl<T> AsPackedValue for *const T
191 where
192 T: Sized,
193 {
194 const MIN_BIT_WIDTH: usize = 48;
195
196 fn encode(zelf: Self) -> TruncatedU64<Self> {
197 TruncatedU64::new(zelf as u64)
198 }
199
200 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
201 crate::utils::sign_extend(raw.read()) as *const T
202 }
203
204 fn is_rt_safe() -> bool {
205 assert_ptr_safety();
206 true
207 }
208 }
209
210 unsafe impl<T> AsPackedValue for *mut T
215 where
216 T: Sized,
217 {
218 const MIN_BIT_WIDTH: usize = 48;
219
220 fn encode(zelf: Self) -> TruncatedU64<Self> {
221 TruncatedU64::new(zelf as u64)
222 }
223
224 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
225 crate::utils::sign_extend(raw.read()) as *mut T
226 }
227
228 fn is_rt_safe() -> bool {
229 assert_ptr_safety();
230 true
231 }
232 }
233
234 unsafe impl<T> AsPackedValue for NonNull<T>
239 where
240 T: Sized,
241 {
242 const MIN_BIT_WIDTH: usize = 48;
243
244 fn encode(zelf: Self) -> TruncatedU64<Self> {
245 TruncatedU64::new(zelf.as_ptr() as u64)
246 }
247
248 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
249 Self::new(crate::utils::sign_extend(raw.read()) as *mut T)
250 .expect("tried to recosntruct a NonNull from 0")
251 }
252
253 fn is_rt_safe() -> bool {
254 assert_ptr_safety();
255 true
256 }
257 }
258
259 unsafe impl<T> AsPackedValue for &'static T {
264 const MIN_BIT_WIDTH: usize = 48;
265
266 fn encode(zelf: Self) -> TruncatedU64<Self> {
267 TruncatedU64::new(zelf as *const T as u64)
268 }
269
270 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
271 unsafe { &*(crate::utils::sign_extend(raw.read()) as *const T) }
274 }
275
276 fn is_rt_safe() -> bool {
277 assert_ptr_safety();
278 true
279 }
280 }
281
282 unsafe impl<T> AsPackedValue for &'static mut T {
287 const MIN_BIT_WIDTH: usize = 48;
288
289 fn encode(zelf: Self) -> TruncatedU64<Self> {
290 TruncatedU64::new(zelf as *mut T as u64)
291 }
292
293 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
294 unsafe { &mut *(crate::utils::sign_extend(raw.read()) as *mut T) }
297 }
298
299 fn is_rt_safe() -> bool {
300 assert_ptr_safety();
301 true
302 }
303 }
304
305 #[cfg(any(feature = "alloc", test))]
306 mod alloc_ {
307 use alloc::{
308 boxed::Box,
309 rc::{self, Rc},
310 sync::{self, Arc},
311 };
312
313 use super::*;
314
315 unsafe impl<T> AsPackedValue for Box<T> {
320 const MIN_BIT_WIDTH: usize = 48;
321
322 fn encode(zelf: Self) -> TruncatedU64<Self> {
323 let raw = Box::into_raw(zelf);
324 TruncatedU64::new(raw as u64)
325 }
326
327 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
328 unsafe { Box::from_raw(crate::utils::sign_extend(raw.read()) as *mut T) }
331 }
332
333 fn is_rt_safe() -> bool {
334 assert_ptr_safety();
335 true
336 }
337 }
338
339 unsafe impl<T> AsPackedValue for Rc<T> {
344 const MIN_BIT_WIDTH: usize = 48;
345
346 fn encode(zelf: Self) -> TruncatedU64<Self> {
347 let raw = Rc::into_raw(zelf);
348 TruncatedU64::new(raw as u64)
349 }
350
351 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
352 unsafe { Rc::from_raw(crate::utils::sign_extend(raw.read()) as *mut T) }
355 }
356
357 fn is_rt_safe() -> bool {
358 assert_ptr_safety();
359 true
360 }
361 }
362
363 unsafe impl<T> AsPackedValue for Arc<T> {
368 const MIN_BIT_WIDTH: usize = 48;
369
370 fn encode(zelf: Self) -> TruncatedU64<Self> {
371 let raw = Arc::into_raw(zelf);
372 TruncatedU64::new(raw as u64)
373 }
374
375 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
376 unsafe { Arc::from_raw(crate::utils::sign_extend(raw.read()) as *mut T) }
379 }
380
381 fn is_rt_safe() -> bool {
382 assert_ptr_safety();
383 true
384 }
385 }
386
387 unsafe impl<T> AsPackedValue for rc::Weak<T> {
392 const MIN_BIT_WIDTH: usize = 48;
393
394 fn encode(zelf: Self) -> TruncatedU64<Self> {
395 let raw = rc::Weak::into_raw(zelf);
396 TruncatedU64::new(raw as u64)
397 }
398
399 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
400 unsafe { rc::Weak::from_raw(crate::utils::sign_extend(raw.read()) as *mut T) }
403 }
404
405 fn is_rt_safe() -> bool {
406 assert_ptr_safety();
407 true
408 }
409 }
410
411 unsafe impl<T> AsPackedValue for sync::Weak<T> {
416 const MIN_BIT_WIDTH: usize = 48;
417
418 fn encode(zelf: Self) -> TruncatedU64<Self> {
419 let raw = sync::Weak::into_raw(zelf);
420 TruncatedU64::new(raw as u64)
421 }
422
423 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
424 unsafe { sync::Weak::from_raw(crate::utils::sign_extend(raw.read()) as *mut T) }
427 }
428
429 fn is_rt_safe() -> bool {
430 assert_ptr_safety();
431 true
432 }
433 }
434 }
435}
436
437#[cfg(all(
439 not(target_arch = "x86_64"),
440 not(target_arch = "aarch64"),
441 target_pointer_width = "64"
442))]
443mod full_bit64 {
444 use super::*;
445
446 unsafe impl<T> AsPackedValue for *const T
449 where
450 T: Sized,
451 {
452 const MIN_BIT_WIDTH: usize = 64;
453
454 fn encode(zelf: Self) -> TruncatedU64<Self> {
455 TruncatedU64::new(zelf as u64)
456 }
457
458 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
459 raw.read() as *const T
460 }
461
462 fn is_rt_safe() -> bool {
463 true
465 }
466 }
467
468 unsafe impl<T> AsPackedValue for *mut T
471 where
472 T: Sized,
473 {
474 const MIN_BIT_WIDTH: usize = 64;
475
476 fn encode(zelf: Self) -> TruncatedU64<Self> {
477 TruncatedU64::new(zelf as u64)
478 }
479
480 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
481 raw.read() as *mut T
482 }
483
484 fn is_rt_safe() -> bool {
485 true
487 }
488 }
489
490 unsafe impl<T> AsPackedValue for NonNull<T>
494 where
495 T: Sized,
496 {
497 const MIN_BIT_WIDTH: usize = 64;
498
499 fn encode(zelf: Self) -> TruncatedU64<Self> {
500 TruncatedU64::new(zelf.as_ptr() as u64)
501 }
502
503 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
504 Self::new(raw.read() as *mut T).expect("tried to recosntruct a NonNull from 0")
505 }
506
507 fn is_rt_safe() -> bool {
508 true
510 }
511 }
512
513 unsafe impl<T> AsPackedValue for &'static T {
516 const MIN_BIT_WIDTH: usize = 64;
517
518 fn encode(zelf: Self) -> TruncatedU64<Self> {
519 TruncatedU64::new(zelf as *const T as u64)
520 }
521
522 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
523 unsafe { &*(raw.read() as *const T) }
526 }
527
528 fn is_rt_safe() -> bool {
529 true
531 }
532 }
533
534 unsafe impl<T> AsPackedValue for &'static mut T {
537 const MIN_BIT_WIDTH: usize = 64;
538
539 fn encode(zelf: Self) -> TruncatedU64<Self> {
540 TruncatedU64::new(zelf as *mut T as u64)
541 }
542
543 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
544 unsafe { &mut *(raw.read() as *mut T) }
547 }
548
549 fn is_rt_safe() -> bool {
550 true
552 }
553 }
554
555 #[cfg(any(feature = "alloc", test))]
556 mod alloc_ {
557 use alloc::{
558 boxed::Box,
559 rc::{self, Rc},
560 sync::{self, Arc},
561 };
562
563 use super::*;
564
565 unsafe impl<T> AsPackedValue for Box<T> {
568 const MIN_BIT_WIDTH: usize = 64;
569
570 fn encode(zelf: Self) -> TruncatedU64<Self> {
571 TruncatedU64::new(Box::into_raw(zelf) as u64)
572 }
573
574 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
575 unsafe { Box::from_raw(raw.read() as *mut T) }
578 }
579
580 fn is_rt_safe() -> bool {
581 true
583 }
584 }
585
586 unsafe impl<T> AsPackedValue for Rc<T> {
589 const MIN_BIT_WIDTH: usize = 64;
590
591 fn encode(zelf: Self) -> TruncatedU64<Self> {
592 let raw = Rc::into_raw(zelf);
593 TruncatedU64::new(raw as u64)
594 }
595
596 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
597 unsafe { Rc::from_raw(raw.read() as *mut T) }
600 }
601
602 fn is_rt_safe() -> bool {
603 true
605 }
606 }
607
608 unsafe impl<T> AsPackedValue for Arc<T> {
611 const MIN_BIT_WIDTH: usize = 64;
612
613 fn encode(zelf: Self) -> TruncatedU64<Self> {
614 let raw = Arc::into_raw(zelf);
615 TruncatedU64::new(raw as u64)
616 }
617
618 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
619 unsafe { Arc::from_raw(raw.read() as *mut T) }
622 }
623
624 fn is_rt_safe() -> bool {
625 true
627 }
628 }
629
630 unsafe impl<T> AsPackedValue for rc::Weak<T> {
633 const MIN_BIT_WIDTH: usize = 64;
634
635 fn encode(zelf: Self) -> TruncatedU64<Self> {
636 let raw = rc::Weak::into_raw(zelf);
637 TruncatedU64::new(raw as u64)
638 }
639
640 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
641 unsafe { rc::Weak::from_raw(raw.read() as *mut T) }
644 }
645
646 fn is_rt_safe() -> bool {
647 true
649 }
650 }
651
652 unsafe impl<T> AsPackedValue for sync::Weak<T> {
655 const MIN_BIT_WIDTH: usize = 64;
656
657 fn encode(zelf: Self) -> TruncatedU64<Self> {
658 let raw = sync::Weak::into_raw(zelf);
659 TruncatedU64::new(raw as u64)
660 }
661
662 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
663 unsafe { sync::Weak::from_raw(raw.read() as *mut T) }
666 }
667
668 fn is_rt_safe() -> bool {
669 true
671 }
672 }
673 }
674}
675
676#[cfg(not(target_pointer_width = "64"))]
678mod bit32 {
679 use core::num::NonZeroUsize;
680
681 use super::*;
682
683 unsafe impl<T> AsPackedValue for *const T
686 where
687 T: Sized,
688 {
689 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
690
691 fn encode(zelf: Self) -> TruncatedU64<Self> {
692 TruncatedU64::new(zelf as u64)
693 }
694
695 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
696 raw.read() as *const T
697 }
698
699 fn is_rt_safe() -> bool {
700 true
702 }
703 }
704
705 unsafe impl<T> AsPackedValue for *mut T
708 where
709 T: Sized,
710 {
711 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
712
713 fn encode(zelf: Self) -> TruncatedU64<Self> {
714 TruncatedU64::new(zelf as u64)
715 }
716
717 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
718 raw.read() as *mut T
719 }
720
721 fn is_rt_safe() -> bool {
722 true
724 }
725 }
726
727 unsafe impl<T> AsPackedValue for NonNull<T>
730 where
731 T: Sized,
732 {
733 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
734
735 fn encode(zelf: Self) -> TruncatedU64<Self> {
736 TruncatedU64::new(zelf.as_ptr() as u64)
737 }
738
739 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
740 Self::new(raw.read() as *mut T)
741 .expect("Constructing a NonNull form a null ptr wich was not obtained from encode")
742 }
743
744 fn is_rt_safe() -> bool {
745 true
747 }
748 }
749
750 unsafe impl<T> AsPackedValue for &'static T {
753 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
754
755 fn encode(zelf: Self) -> TruncatedU64<Self> {
756 TruncatedU64::new(zelf as *const T as u64)
757 }
758
759 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
760 unsafe { &*(raw.read() as *const T) }
763 }
764
765 fn is_rt_safe() -> bool {
766 true
768 }
769 }
770
771 unsafe impl<T> AsPackedValue for &'static mut T {
774 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
775
776 fn encode(zelf: Self) -> TruncatedU64<Self> {
777 TruncatedU64::new(zelf as *mut T as u64)
778 }
779
780 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
781 unsafe { &mut *(raw.read() as *mut T) }
784 }
785
786 fn is_rt_safe() -> bool {
787 true
789 }
790 }
791
792 #[cfg(feature = "alloc")]
793 mod alloc_ {
794 use alloc::{
795 boxed::Box,
796 rc::{self, Rc},
797 sync::{self, Arc},
798 };
799
800 use super::*;
801
802 unsafe impl<T> AsPackedValue for Box<T> {
805 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
806
807 fn encode(zelf: Self) -> TruncatedU64<Self> {
808 TruncatedU64::new(Box::into_raw(zelf) as u64)
809 }
810
811 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
812 unsafe { Box::from_raw(raw.read() as *mut T) }
815 }
816
817 fn is_rt_safe() -> bool {
818 true
820 }
821 }
822
823 unsafe impl<T> AsPackedValue for Rc<T> {
826 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
827
828 fn encode(zelf: Self) -> TruncatedU64<Self> {
829 let raw = Rc::into_raw(zelf);
830 TruncatedU64::new(raw as u64)
831 }
832
833 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
834 unsafe { Rc::from_raw(raw.read() as *mut T) }
837 }
838
839 fn is_rt_safe() -> bool {
840 true
842 }
843 }
844
845 unsafe impl<T> AsPackedValue for Arc<T> {
848 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
849
850 fn encode(zelf: Self) -> TruncatedU64<Self> {
851 let raw = Arc::into_raw(zelf);
852 TruncatedU64::new(raw as u64)
853 }
854
855 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
856 unsafe { Arc::from_raw(raw.read() as *mut T) }
859 }
860
861 fn is_rt_safe() -> bool {
862 true
864 }
865 }
866
867 unsafe impl<T> AsPackedValue for rc::Weak<T> {
870 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
871
872 fn encode(zelf: Self) -> TruncatedU64<Self> {
873 let raw = rc::Weak::into_raw(zelf);
874 TruncatedU64::new(raw as u64)
875 }
876
877 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
878 unsafe { rc::Weak::from_raw(raw.read() as *mut T) }
881 }
882
883 fn is_rt_safe() -> bool {
884 true
886 }
887 }
888
889 unsafe impl<T> AsPackedValue for sync::Weak<T> {
892 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
893
894 fn encode(zelf: Self) -> TruncatedU64<Self> {
895 let raw = sync::Weak::into_raw(zelf);
896 TruncatedU64::new(raw as u64)
897 }
898
899 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
900 unsafe { sync::Weak::from_raw(raw.read() as *mut T) }
903 }
904
905 fn is_rt_safe() -> bool {
906 true
908 }
909 }
910 }
911
912 atomic_encode_primitive!(usize);
913 atomic_encode_non_zero_primitive!(NonZeroUsize, usize);
914}
915
916#[cfg(test)]
917mod tests {
918 use super::*;
919
920 #[test]
921 fn truncated_trait_impls() {
922 struct NotClone;
923
924 let packed = TruncatedU64::<NotClone> {
925 v: 0,
926 _phantom: PhantomData,
927 };
928
929 #[allow(clippy::clone_on_copy)]
930 let cloned = packed.clone();
931
932 assert_eq!(packed, cloned);
933 assert_eq!(format!("{packed:?}"), format!("{cloned:?}"));
934 }
935
936 macro_rules! generate_test {
937 ($name:ident: $constructor:expr, $type:ty, $deref:expr, $drop:expr) => {
938 #[test]
939 fn $name() {
940 #[allow(dead_code)]
941 static VALUE: i32 = 42;
942 const WIDTH: usize = <$type as AsPackedValue>::MIN_BIT_WIDTH;
943
944 assert!(<$type>::is_rt_safe());
945
946 let ptr1: $type = $constructor;
947 let expected = $deref(&ptr1);
948
949 let mut encoded = AsPackedValue::encode(ptr1);
950
951 if WIDTH < 64 {
952 let packed_encoded = pack!((!0, encoded.read()): WIDTH);
953 encoded = TruncatedU64::new(packed_encoded);
954 }
955
956 let decoded: $type = unsafe { AsPackedValue::decode(encoded) };
959
960 assert_eq!($deref(&decoded), expected);
961
962 #[allow(dropping_copy_types, dropping_references)]
963 $drop(decoded);
964 }
965 };
966 ($name:ident: $constructor:expr, $type:ty) => {
967 generate_test!($name: $constructor, $type, |x: &$type| x.clone(), drop);
968 };
969 }
970
971 generate_test!(raw: &VALUE as *const i32, *const i32);
972 generate_test!(raw_mut: &VALUE as *const i32 as *mut i32, *mut i32);
973 generate_test!(r#ref: &VALUE, &'static i32);
974 generate_test!(ref_mut: Box::leak(Box::new(VALUE)), & 'static mut i32, |x: &&'static mut i32| *x as *const i32,
976 |x: &'static mut i32|
977 unsafe {Box::from_raw(x as *mut i32)}
980 );
981 generate_test!(nonnull: NonNull::new(&VALUE as *const i32 as *mut i32).unwrap(), NonNull<i32>);
982 generate_test!(primitive_u32: 42, u32);
983 generate_test!(primitive_nonzero_u32: NonZeroU32::new(42).unwrap(), NonZeroU32);
984 generate_test!(unit: (), ());
985
986 #[cfg(feature = "alloc")]
987 mod alloc_ {
988 use alloc::{
989 boxed::Box,
990 rc::{self, Rc},
991 sync::{self, Arc},
992 };
993
994 use super::*;
995
996 generate_test!(r#box: Box::new(VALUE), Box<i32>);
997 generate_test!(r#arc: Arc::new(VALUE), Arc<i32>);
998 generate_test!(r#rc: Rc::new(VALUE), Rc<i32>);
999 generate_test!(weak_rc: Rc::downgrade(&Rc::new(VALUE)), rc::Weak<i32>, |x: &rc::Weak<i32>| x.as_ptr(), drop);
1000 generate_test!(weak_arc: Arc::downgrade(&Arc::new(VALUE)), sync::Weak<i32>, |x: &sync::Weak<i32>| x.as_ptr(), drop);
1001 }
1002}