1 //@compile-flags: -Zmiri-permissive-provenance
2 #![feature(ptr_metadata, const_raw_ptr_comparison)]
4 use std::mem::{self, transmute};
7 fn one_line_ref() -> i16 {
11 fn basic_ref() -> i16 {
16 fn basic_ref_mut() -> i16 {
22 fn basic_ref_mut_var() -> i16 {
31 fn tuple_ref_mut() -> (i8, i8) {
40 fn match_ref_mut() -> i8 {
43 let opt = Some(&mut t);
45 Some(&mut (ref mut x, ref mut y)) => *x += *y,
52 fn dangling_pointer() -> *const i32 {
53 let b = Box::new((42, 42)); // make it bigger than the alignment, so that there is some "room" after this pointer
58 let a: *const dyn Send = &1 as &dyn Send;
59 let b: *const dyn Send = &1 as &dyn Send;
67 let a: *const [u8] = unsafe { transmute((1usize, 1usize)) };
68 let b: *const [u8] = unsafe { transmute((1usize, 2usize)) };
69 // confirmed with rustc.
78 fn metadata_vtable() {
79 let p = &0i32 as &dyn std::fmt::Debug;
80 let meta: ptr::DynMetadata<_> = ptr::metadata(p as *const _);
81 assert_eq!(meta.size_of(), mem::size_of::<i32>());
82 assert_eq!(meta.align_of(), mem::align_of::<i32>());
85 let p = &T::default() as &dyn std::fmt::Debug;
86 let meta: ptr::DynMetadata<_> = ptr::metadata(p as *const _);
87 assert_eq!(meta.size_of(), mem::size_of::<T>());
88 assert_eq!(meta.align_of(), mem::align_of::<T>());
92 assert_eq!(one_line_ref(), 1);
93 assert_eq!(basic_ref(), 1);
94 assert_eq!(basic_ref_mut(), 3);
95 assert_eq!(basic_ref_mut_var(), 3);
96 assert_eq!(tuple_ref_mut(), (10, 22));
97 assert_eq!(match_ref_mut(), 42);
99 // Compare even dangling pointers with NULL, and with others in the same allocation, including
101 assert!(dangling_pointer() != std::ptr::null());
102 assert!(match dangling_pointer() as usize {
106 let dangling = dangling_pointer();
107 assert!(dangling == dangling);
108 assert!(dangling.wrapping_add(1) != dangling);
109 assert!(dangling.wrapping_sub(1) != dangling);
111 // Compare pointer with BIG integers
112 let dangling = dangling as usize;
113 assert!(dangling != usize::MAX);
114 assert!(dangling != usize::MAX - 1);
115 assert!(dangling != usize::MAX - 2);
116 assert!(dangling != usize::MAX - 3); // this is even 4-aligned, but it still cannot be equal because of the extra "room" after this pointer
117 assert_eq!((usize::MAX - 3) % 4, 0); // just to be sure we got this right
119 // Compare pointer with unaligned integers
120 assert!(dangling != 1usize);
121 assert!(dangling != 2usize);
122 assert!(dangling != 3usize);
123 // 4 is a possible choice! So we cannot compare with that.
124 assert!(dangling != 5usize);
125 assert!(dangling != 6usize);
126 assert!(dangling != 7usize);
128 // Using inequality to do the comparison.
129 assert!(dangling > 0);
130 assert!(dangling > 1);
131 assert!(dangling > 2);
132 assert!(dangling > 3);
133 assert!(dangling >= 4);
135 // CTFE-specific equality tests, need to also work at runtime.
136 let addr = &13 as *const i32;
137 let addr2 = (addr as usize).wrapping_add(usize::MAX).wrapping_add(1);
138 assert!(addr.guaranteed_eq(addr2 as *const _));
139 assert!(addr.guaranteed_ne(0x100 as *const _));