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 {: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 raw
184 );
185 }
186
187 unsafe impl<T> AsPackedValue for *const T
192 where
193 T: Sized,
194 {
195 const MIN_BIT_WIDTH: usize = 48;
196
197 fn encode(zelf: Self) -> TruncatedU64<Self> {
198 TruncatedU64::new(zelf as u64)
199 }
200
201 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
202 crate::utils::sign_extend(raw.read()) as *const T
203 }
204
205 fn is_rt_safe() -> bool {
206 assert_ptr_safety();
207 true
208 }
209 }
210
211 unsafe impl<T> AsPackedValue for *mut T
216 where
217 T: Sized,
218 {
219 const MIN_BIT_WIDTH: usize = 48;
220
221 fn encode(zelf: Self) -> TruncatedU64<Self> {
222 TruncatedU64::new(zelf as u64)
223 }
224
225 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
226 crate::utils::sign_extend(raw.read()) as *mut T
227 }
228
229 fn is_rt_safe() -> bool {
230 assert_ptr_safety();
231 true
232 }
233 }
234
235 unsafe impl<T> AsPackedValue for NonNull<T>
240 where
241 T: Sized,
242 {
243 const MIN_BIT_WIDTH: usize = 48;
244
245 fn encode(zelf: Self) -> TruncatedU64<Self> {
246 TruncatedU64::new(zelf.as_ptr() as u64)
247 }
248
249 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
250 Self::new(crate::utils::sign_extend(raw.read()) as *mut T)
251 .expect("tried to recosntruct a NonNull from 0")
252 }
253
254 fn is_rt_safe() -> bool {
255 assert_ptr_safety();
256 true
257 }
258 }
259
260 unsafe impl<T> AsPackedValue for &'static T {
265 const MIN_BIT_WIDTH: usize = 48;
266
267 fn encode(zelf: Self) -> TruncatedU64<Self> {
268 TruncatedU64::new(zelf as *const T as u64)
269 }
270
271 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
272 unsafe { &*(crate::utils::sign_extend(raw.read()) as *const T) }
275 }
276
277 fn is_rt_safe() -> bool {
278 assert_ptr_safety();
279 true
280 }
281 }
282
283 unsafe impl<T> AsPackedValue for &'static mut T {
288 const MIN_BIT_WIDTH: usize = 48;
289
290 fn encode(zelf: Self) -> TruncatedU64<Self> {
291 TruncatedU64::new(zelf as *mut T as u64)
292 }
293
294 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
295 unsafe { &mut *(crate::utils::sign_extend(raw.read()) as *mut T) }
298 }
299
300 fn is_rt_safe() -> bool {
301 assert_ptr_safety();
302 true
303 }
304 }
305
306 #[cfg(any(feature = "alloc", test))]
307 mod alloc_ {
308 use alloc::{
309 boxed::Box,
310 rc::{self, Rc},
311 sync::{self, Arc},
312 };
313
314 use super::*;
315
316 unsafe impl<T> AsPackedValue for Box<T> {
321 const MIN_BIT_WIDTH: usize = 48;
322
323 fn encode(zelf: Self) -> TruncatedU64<Self> {
324 let raw = Box::into_raw(zelf);
325 TruncatedU64::new(raw as u64)
326 }
327
328 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
329 unsafe { Box::from_raw(crate::utils::sign_extend(raw.read()) as *mut T) }
332 }
333
334 fn is_rt_safe() -> bool {
335 assert_ptr_safety();
336 true
337 }
338 }
339
340 unsafe impl<T> AsPackedValue for Rc<T> {
345 const MIN_BIT_WIDTH: usize = 48;
346
347 fn encode(zelf: Self) -> TruncatedU64<Self> {
348 let raw = Rc::into_raw(zelf);
349 TruncatedU64::new(raw as u64)
350 }
351
352 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
353 unsafe { Rc::from_raw(crate::utils::sign_extend(raw.read()) as *mut T) }
356 }
357
358 fn is_rt_safe() -> bool {
359 assert_ptr_safety();
360 true
361 }
362 }
363
364 unsafe impl<T> AsPackedValue for Arc<T> {
369 const MIN_BIT_WIDTH: usize = 48;
370
371 fn encode(zelf: Self) -> TruncatedU64<Self> {
372 let raw = Arc::into_raw(zelf);
373 TruncatedU64::new(raw as u64)
374 }
375
376 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
377 unsafe { Arc::from_raw(crate::utils::sign_extend(raw.read()) as *mut T) }
380 }
381
382 fn is_rt_safe() -> bool {
383 assert_ptr_safety();
384 true
385 }
386 }
387
388 unsafe impl<T> AsPackedValue for rc::Weak<T> {
393 const MIN_BIT_WIDTH: usize = 48;
394
395 fn encode(zelf: Self) -> TruncatedU64<Self> {
396 let raw = rc::Weak::into_raw(zelf);
397 TruncatedU64::new(raw as u64)
398 }
399
400 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
401 unsafe { rc::Weak::from_raw(crate::utils::sign_extend(raw.read()) as *mut T) }
404 }
405
406 fn is_rt_safe() -> bool {
407 assert_ptr_safety();
408 true
409 }
410 }
411
412 unsafe impl<T> AsPackedValue for sync::Weak<T> {
417 const MIN_BIT_WIDTH: usize = 48;
418
419 fn encode(zelf: Self) -> TruncatedU64<Self> {
420 let raw = sync::Weak::into_raw(zelf);
421 TruncatedU64::new(raw as u64)
422 }
423
424 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
425 unsafe { sync::Weak::from_raw(crate::utils::sign_extend(raw.read()) as *mut T) }
428 }
429
430 fn is_rt_safe() -> bool {
431 assert_ptr_safety();
432 true
433 }
434 }
435 }
436}
437
438#[cfg(all(
440 not(target_arch = "x86_64"),
441 not(target_arch = "aarch64"),
442 target_pointer_width = "64"
443))]
444mod full_bit64 {
445 use super::*;
446
447 unsafe impl<T> AsPackedValue for *const T
450 where
451 T: Sized,
452 {
453 const MIN_BIT_WIDTH: usize = 64;
454
455 fn encode(zelf: Self) -> TruncatedU64<Self> {
456 TruncatedU64::new(zelf as u64)
457 }
458
459 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
460 raw.read() as *const T
461 }
462
463 fn is_rt_safe() -> bool {
464 true
466 }
467 }
468
469 unsafe impl<T> AsPackedValue for *mut T
472 where
473 T: Sized,
474 {
475 const MIN_BIT_WIDTH: usize = 64;
476
477 fn encode(zelf: Self) -> TruncatedU64<Self> {
478 TruncatedU64::new(zelf as u64)
479 }
480
481 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
482 raw.read() as *mut T
483 }
484
485 fn is_rt_safe() -> bool {
486 true
488 }
489 }
490
491 unsafe impl<T> AsPackedValue for NonNull<T>
495 where
496 T: Sized,
497 {
498 const MIN_BIT_WIDTH: usize = 64;
499
500 fn encode(zelf: Self) -> TruncatedU64<Self> {
501 TruncatedU64::new(zelf.as_ptr() as u64)
502 }
503
504 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
505 Self::new(raw.read() as *mut T).expect("tried to recosntruct a NonNull from 0")
506 }
507
508 fn is_rt_safe() -> bool {
509 true
511 }
512 }
513
514 unsafe impl<T> AsPackedValue for &'static T {
517 const MIN_BIT_WIDTH: usize = 64;
518
519 fn encode(zelf: Self) -> TruncatedU64<Self> {
520 TruncatedU64::new(zelf as *const T as u64)
521 }
522
523 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
524 unsafe { &*(raw.read() as *const T) }
527 }
528
529 fn is_rt_safe() -> bool {
530 true
532 }
533 }
534
535 unsafe impl<T> AsPackedValue for &'static mut T {
538 const MIN_BIT_WIDTH: usize = 64;
539
540 fn encode(zelf: Self) -> TruncatedU64<Self> {
541 TruncatedU64::new(zelf as *mut T as u64)
542 }
543
544 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
545 unsafe { &mut *(raw.read() as *mut T) }
548 }
549
550 fn is_rt_safe() -> bool {
551 true
553 }
554 }
555
556 #[cfg(any(feature = "alloc", test))]
557 mod alloc_ {
558 use alloc::{
559 boxed::Box,
560 rc::{self, Rc},
561 sync::{self, Arc},
562 };
563
564 use super::*;
565
566 unsafe impl<T> AsPackedValue for Box<T> {
569 const MIN_BIT_WIDTH: usize = 64;
570
571 fn encode(zelf: Self) -> TruncatedU64<Self> {
572 TruncatedU64::new(Box::into_raw(zelf) as u64)
573 }
574
575 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
576 unsafe { Box::from_raw(raw.read() as *mut T) }
579 }
580
581 fn is_rt_safe() -> bool {
582 true
584 }
585 }
586
587 unsafe impl<T> AsPackedValue for Rc<T> {
590 const MIN_BIT_WIDTH: usize = 64;
591
592 fn encode(zelf: Self) -> TruncatedU64<Self> {
593 let raw = Rc::into_raw(zelf);
594 TruncatedU64::new(raw as u64)
595 }
596
597 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
598 unsafe { Rc::from_raw(raw.read() as *mut T) }
601 }
602
603 fn is_rt_safe() -> bool {
604 true
606 }
607 }
608
609 unsafe impl<T> AsPackedValue for Arc<T> {
612 const MIN_BIT_WIDTH: usize = 64;
613
614 fn encode(zelf: Self) -> TruncatedU64<Self> {
615 let raw = Arc::into_raw(zelf);
616 TruncatedU64::new(raw as u64)
617 }
618
619 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
620 unsafe { Arc::from_raw(raw.read() as *mut T) }
623 }
624
625 fn is_rt_safe() -> bool {
626 true
628 }
629 }
630
631 unsafe impl<T> AsPackedValue for rc::Weak<T> {
634 const MIN_BIT_WIDTH: usize = 64;
635
636 fn encode(zelf: Self) -> TruncatedU64<Self> {
637 let raw = rc::Weak::into_raw(zelf);
638 TruncatedU64::new(raw as u64)
639 }
640
641 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
642 unsafe { rc::Weak::from_raw(raw.read() as *mut T) }
645 }
646
647 fn is_rt_safe() -> bool {
648 true
650 }
651 }
652
653 unsafe impl<T> AsPackedValue for sync::Weak<T> {
656 const MIN_BIT_WIDTH: usize = 64;
657
658 fn encode(zelf: Self) -> TruncatedU64<Self> {
659 let raw = sync::Weak::into_raw(zelf);
660 TruncatedU64::new(raw as u64)
661 }
662
663 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
664 unsafe { sync::Weak::from_raw(raw.read() as *mut T) }
667 }
668
669 fn is_rt_safe() -> bool {
670 true
672 }
673 }
674 }
675}
676
677#[cfg(not(target_pointer_width = "64"))]
679mod bit32 {
680 use core::num::NonZeroUsize;
681
682 use super::*;
683
684 unsafe impl<T> AsPackedValue for *const T
687 where
688 T: Sized,
689 {
690 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
691
692 fn encode(zelf: Self) -> TruncatedU64<Self> {
693 TruncatedU64::new(zelf as u64)
694 }
695
696 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
697 raw.read() as *const T
698 }
699
700 fn is_rt_safe() -> bool {
701 true
703 }
704 }
705
706 unsafe impl<T> AsPackedValue for *mut T
709 where
710 T: Sized,
711 {
712 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
713
714 fn encode(zelf: Self) -> TruncatedU64<Self> {
715 TruncatedU64::new(zelf as u64)
716 }
717
718 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
719 raw.read() as *mut T
720 }
721
722 fn is_rt_safe() -> bool {
723 true
725 }
726 }
727
728 unsafe impl<T> AsPackedValue for NonNull<T>
731 where
732 T: Sized,
733 {
734 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
735
736 fn encode(zelf: Self) -> TruncatedU64<Self> {
737 TruncatedU64::new(zelf.as_ptr() as u64)
738 }
739
740 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
741 Self::new(raw.read() as *mut T)
742 .expect("Constructing a NonNull form a null ptr wich was not obtained from encode")
743 }
744
745 fn is_rt_safe() -> bool {
746 true
748 }
749 }
750
751 unsafe impl<T> AsPackedValue for &'static T {
754 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
755
756 fn encode(zelf: Self) -> TruncatedU64<Self> {
757 TruncatedU64::new(zelf as *const T as u64)
758 }
759
760 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
761 unsafe { &*(raw.read() as *const T) }
764 }
765
766 fn is_rt_safe() -> bool {
767 true
769 }
770 }
771
772 unsafe impl<T> AsPackedValue for &'static mut T {
775 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
776
777 fn encode(zelf: Self) -> TruncatedU64<Self> {
778 TruncatedU64::new(zelf as *mut T as u64)
779 }
780
781 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
782 unsafe { &mut *(raw.read() as *mut T) }
785 }
786
787 fn is_rt_safe() -> bool {
788 true
790 }
791 }
792
793 #[cfg(feature = "alloc")]
794 mod alloc_ {
795 use alloc::{
796 boxed::Box,
797 rc::{self, Rc},
798 sync::{self, Arc},
799 };
800
801 use super::*;
802
803 unsafe impl<T> AsPackedValue for Box<T> {
806 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
807
808 fn encode(zelf: Self) -> TruncatedU64<Self> {
809 TruncatedU64::new(Box::into_raw(zelf) as u64)
810 }
811
812 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
813 unsafe { Box::from_raw(raw.read() as *mut T) }
816 }
817
818 fn is_rt_safe() -> bool {
819 true
821 }
822 }
823
824 unsafe impl<T> AsPackedValue for Rc<T> {
827 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
828
829 fn encode(zelf: Self) -> TruncatedU64<Self> {
830 let raw = Rc::into_raw(zelf);
831 TruncatedU64::new(raw as u64)
832 }
833
834 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
835 unsafe { Rc::from_raw(raw.read() as *mut T) }
838 }
839
840 fn is_rt_safe() -> bool {
841 true
843 }
844 }
845
846 unsafe impl<T> AsPackedValue for Arc<T> {
849 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
850
851 fn encode(zelf: Self) -> TruncatedU64<Self> {
852 let raw = Arc::into_raw(zelf);
853 TruncatedU64::new(raw as u64)
854 }
855
856 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
857 unsafe { Arc::from_raw(raw.read() as *mut T) }
860 }
861
862 fn is_rt_safe() -> bool {
863 true
865 }
866 }
867
868 unsafe impl<T> AsPackedValue for rc::Weak<T> {
871 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
872
873 fn encode(zelf: Self) -> TruncatedU64<Self> {
874 let raw = rc::Weak::into_raw(zelf);
875 TruncatedU64::new(raw as u64)
876 }
877
878 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
879 unsafe { rc::Weak::from_raw(raw.read() as *mut T) }
882 }
883
884 fn is_rt_safe() -> bool {
885 true
887 }
888 }
889
890 unsafe impl<T> AsPackedValue for sync::Weak<T> {
893 const MIN_BIT_WIDTH: usize = size_of::<usize>() * 8;
894
895 fn encode(zelf: Self) -> TruncatedU64<Self> {
896 let raw = sync::Weak::into_raw(zelf);
897 TruncatedU64::new(raw as u64)
898 }
899
900 unsafe fn decode(raw: TruncatedU64<Self>) -> Self {
901 unsafe { sync::Weak::from_raw(raw.read() as *mut T) }
904 }
905
906 fn is_rt_safe() -> bool {
907 true
909 }
910 }
911 }
912
913 atomic_encode_primitive!(usize);
914 atomic_encode_non_zero_primitive!(NonZeroUsize, usize);
915}
916
917#[cfg(test)]
918mod tests {
919 use super::*;
920
921 #[test]
922 fn truncated_trait_impls() {
923 struct NotClone;
924
925 let packed = TruncatedU64::<NotClone> {
926 v: 0,
927 _phantom: PhantomData,
928 };
929
930 #[allow(clippy::clone_on_copy)]
931 let cloned = packed.clone();
932
933 assert_eq!(packed, cloned);
934 assert_eq!(format!("{:?}", packed), format!("{:?}", cloned));
935 }
936
937 macro_rules! generate_test {
938 ($name:ident: $constructor:expr, $type:ty, $deref:expr, $drop:expr) => {
939 #[test]
940 fn $name() {
941 #[allow(dead_code)]
942 static VALUE: i32 = 42;
943 const WIDTH: usize = <$type as AsPackedValue>::MIN_BIT_WIDTH;
944
945 assert!(<$type>::is_rt_safe());
946
947 let ptr1: $type = $constructor;
948 let expected = $deref(&ptr1);
949
950 let mut encoded = AsPackedValue::encode(ptr1);
951
952 if WIDTH < 64 {
953 let packed_encoded = pack!((!0, encoded.read()): WIDTH);
954 encoded = TruncatedU64::new(packed_encoded);
955 }
956
957 let decoded: $type = unsafe { AsPackedValue::decode(encoded) };
960
961 assert_eq!($deref(&decoded), expected);
962
963 #[allow(dropping_copy_types, dropping_references)]
964 $drop(decoded);
965 }
966 };
967 ($name:ident: $constructor:expr, $type:ty) => {
968 generate_test!($name: $constructor, $type, |x: &$type| x.clone(), drop);
969 };
970 }
971
972 generate_test!(raw: &VALUE as *const i32, *const i32);
973 generate_test!(raw_mut: &VALUE as *const i32 as *mut i32, *mut i32);
974 generate_test!(r#ref: &VALUE, &'static i32);
975 generate_test!(ref_mut: Box::leak(Box::new(VALUE)), & 'static mut i32, |x: &&'static mut i32| *x as *const i32,
977 |x: &'static mut i32|
978 unsafe {Box::from_raw(x as *mut i32)}
981 );
982 generate_test!(nonnull: NonNull::new(&VALUE as *const i32 as *mut i32).unwrap(), NonNull<i32>);
983 generate_test!(primitive_u32: 42, u32);
984 generate_test!(primitive_nonzero_u32: NonZeroU32::new(42).unwrap(), NonZeroU32);
985 generate_test!(unit: (), ());
986
987 #[cfg(feature = "alloc")]
988 mod alloc_ {
989 use alloc::{
990 boxed::Box,
991 rc::{self, Rc},
992 sync::{self, Arc},
993 };
994
995 use super::*;
996
997 generate_test!(r#box: Box::new(VALUE), Box<i32>);
998 generate_test!(r#arc: Arc::new(VALUE), Arc<i32>);
999 generate_test!(r#rc: Rc::new(VALUE), Rc<i32>);
1000 generate_test!(weak_rc: Rc::downgrade(&Rc::new(VALUE)), rc::Weak<i32>, |x: &rc::Weak<i32>| x.as_ptr(), drop);
1001 generate_test!(weak_arc: Arc::downgrade(&Arc::new(VALUE)), sync::Weak<i32>, |x: &sync::Weak<i32>| x.as_ptr(), drop);
1002 }
1003}