]> git.lizzy.rs Git - rust.git/blob - tests/run-pass/slices.rs
run some tests with raw pointer tracking
[rust.git] / tests / run-pass / slices.rs
1 // compile-flags: -Zmiri-track-raw-pointers
2 #![feature(new_uninit)]
3
4 use std::slice;
5
6 fn slice_of_zst() {
7     fn foo<T>(v: &[T]) -> Option<&[T]> {
8         let mut it = v.iter();
9         for _ in 0..5 {
10             it.next();
11         }
12         Some(it.as_slice())
13     }
14
15     fn foo_mut<T>(v: &mut [T]) -> Option<&mut [T]> {
16         let mut it = v.iter_mut();
17         for _ in 0..5 {
18             it.next();
19         }
20         Some(it.into_slice())
21     }
22
23     // In a slice of zero-size elements the pointer is meaningless.
24     // Ensure iteration still works even if the pointer is at the end of the address space.
25     let slice: &[()] = unsafe { slice::from_raw_parts(-5isize as *const (), 10) };
26     assert_eq!(slice.len(), 10);
27     assert_eq!(slice.iter().count(), 10);
28
29     // .nth() on the iterator should also behave correctly
30     let mut it = slice.iter();
31     assert!(it.nth(5).is_some());
32     assert_eq!(it.count(), 4);
33
34     // Converting Iter to a slice should never have a null pointer
35     assert!(foo(slice).is_some());
36
37     // Test mutable iterators as well
38     let slice: &mut [()] = unsafe { slice::from_raw_parts_mut(-5isize as *mut (), 10) };
39     assert_eq!(slice.len(), 10);
40     assert_eq!(slice.iter_mut().count(), 10);
41
42     {
43         let mut it = slice.iter_mut();
44         assert!(it.nth(5).is_some());
45         assert_eq!(it.count(), 4);
46     }
47
48     assert!(foo_mut(slice).is_some())
49 }
50
51 fn test_iter_ref_consistency() {
52     use std::fmt::Debug;
53
54     fn test<T : Copy + Debug + PartialEq>(x : T) {
55         let v : &[T] = &[x, x, x];
56         let v_ptrs : [*const T; 3] = match v {
57             [ref v1, ref v2, ref v3] => [v1 as *const _, v2 as *const _, v3 as *const _],
58             _ => unreachable!()
59         };
60         let len = v.len();
61
62         // nth(i)
63         for i in 0..len {
64             assert_eq!(&v[i] as *const _, v_ptrs[i]); // check the v_ptrs array, just to be sure
65             let nth = v.iter().nth(i).unwrap();
66             assert_eq!(nth as *const _, v_ptrs[i]);
67         }
68         assert_eq!(v.iter().nth(len), None, "nth(len) should return None");
69
70         // stepping through with nth(0)
71         {
72             let mut it = v.iter();
73             for i in 0..len {
74                 let next = it.nth(0).unwrap();
75                 assert_eq!(next as *const _, v_ptrs[i]);
76             }
77             assert_eq!(it.nth(0), None);
78         }
79
80         // next()
81         {
82             let mut it = v.iter();
83             for i in 0..len {
84                 let remaining = len - i;
85                 assert_eq!(it.size_hint(), (remaining, Some(remaining)));
86
87                 let next = it.next().unwrap();
88                 assert_eq!(next as *const _, v_ptrs[i]);
89             }
90             assert_eq!(it.size_hint(), (0, Some(0)));
91             assert_eq!(it.next(), None, "The final call to next() should return None");
92         }
93
94         // next_back()
95         {
96             let mut it = v.iter();
97             for i in 0..len {
98                 let remaining = len - i;
99                 assert_eq!(it.size_hint(), (remaining, Some(remaining)));
100
101                 let prev = it.next_back().unwrap();
102                 assert_eq!(prev as *const _, v_ptrs[remaining-1]);
103             }
104             assert_eq!(it.size_hint(), (0, Some(0)));
105             assert_eq!(it.next_back(), None, "The final call to next_back() should return None");
106         }
107     }
108
109     fn test_mut<T : Copy + Debug + PartialEq>(x : T) {
110         let v : &mut [T] = &mut [x, x, x];
111         let v_ptrs : [*mut T; 3] = match v {
112             [ref v1, ref v2, ref v3] =>
113               [v1 as *const _ as *mut _, v2 as *const _ as *mut _, v3 as *const _ as *mut _],
114             _ => unreachable!()
115         };
116         let len = v.len();
117
118         // nth(i)
119         for i in 0..len {
120             assert_eq!(&mut v[i] as *mut _, v_ptrs[i]); // check the v_ptrs array, just to be sure
121             let nth = v.iter_mut().nth(i).unwrap();
122             assert_eq!(nth as *mut _, v_ptrs[i]);
123         }
124         assert_eq!(v.iter().nth(len), None, "nth(len) should return None");
125
126         // stepping through with nth(0)
127         {
128             let mut it = v.iter();
129             for i in 0..len {
130                 let next = it.nth(0).unwrap();
131                 assert_eq!(next as *const _, v_ptrs[i]);
132             }
133             assert_eq!(it.nth(0), None);
134         }
135
136         // next()
137         {
138             let mut it = v.iter_mut();
139             for i in 0..len {
140                 let remaining = len - i;
141                 assert_eq!(it.size_hint(), (remaining, Some(remaining)));
142
143                 let next = it.next().unwrap();
144                 assert_eq!(next as *mut _, v_ptrs[i]);
145             }
146             assert_eq!(it.size_hint(), (0, Some(0)));
147             assert_eq!(it.next(), None, "The final call to next() should return None");
148         }
149
150         // next_back()
151         {
152             let mut it = v.iter_mut();
153             for i in 0..len {
154                 let remaining = len - i;
155                 assert_eq!(it.size_hint(), (remaining, Some(remaining)));
156
157                 let prev = it.next_back().unwrap();
158                 assert_eq!(prev as *mut _, v_ptrs[remaining-1]);
159             }
160             assert_eq!(it.size_hint(), (0, Some(0)));
161             assert_eq!(it.next_back(), None, "The final call to next_back() should return None");
162         }
163     }
164
165     // Make sure iterators and slice patterns yield consistent addresses for various types,
166     // including ZSTs.
167     test(0u32);
168     test(());
169     test([0u32; 0]); // ZST with alignment > 0
170     test_mut(0u32);
171     test_mut(());
172     test_mut([0u32; 0]); // ZST with alignment > 0
173 }
174
175 fn uninit_slice() {
176     let mut values = Box::<[Box<u32>]>::new_uninit_slice(3);
177
178     let values = unsafe {
179         // Deferred initialization:
180         values[0].as_mut_ptr().write(Box::new(1));
181         values[1].as_mut_ptr().write(Box::new(2));
182         values[2].as_mut_ptr().write(Box::new(3));
183
184         values.assume_init()
185     };
186
187     assert_eq!(values.iter().map(|x| **x).collect::<Vec<_>>(), vec![1, 2, 3])
188 }
189
190 fn main() {
191     slice_of_zst();
192     test_iter_ref_consistency();
193     uninit_slice();
194 }