1 // compile-flags: -Zmiri-track-raw-pointers
2 #![feature(new_uninit)]
7 fn foo<T>(v: &[T]) -> Option<&[T]> {
15 fn foo_mut<T>(v: &mut [T]) -> Option<&mut [T]> {
16 let mut it = v.iter_mut();
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);
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);
34 // Converting Iter to a slice should never have a null pointer
35 assert!(foo(slice).is_some());
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);
43 let mut it = slice.iter_mut();
44 assert!(it.nth(5).is_some());
45 assert_eq!(it.count(), 4);
48 assert!(foo_mut(slice).is_some())
51 fn test_iter_ref_consistency() {
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 _],
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]);
68 assert_eq!(v.iter().nth(len), None, "nth(len) should return None");
70 // stepping through with nth(0)
72 let mut it = v.iter();
74 let next = it.nth(0).unwrap();
75 assert_eq!(next as *const _, v_ptrs[i]);
77 assert_eq!(it.nth(0), None);
82 let mut it = v.iter();
84 let remaining = len - i;
85 assert_eq!(it.size_hint(), (remaining, Some(remaining)));
87 let next = it.next().unwrap();
88 assert_eq!(next as *const _, v_ptrs[i]);
90 assert_eq!(it.size_hint(), (0, Some(0)));
91 assert_eq!(it.next(), None, "The final call to next() should return None");
96 let mut it = v.iter();
98 let remaining = len - i;
99 assert_eq!(it.size_hint(), (remaining, Some(remaining)));
101 let prev = it.next_back().unwrap();
102 assert_eq!(prev as *const _, v_ptrs[remaining-1]);
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");
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 _],
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]);
124 assert_eq!(v.iter().nth(len), None, "nth(len) should return None");
126 // stepping through with nth(0)
128 let mut it = v.iter();
130 let next = it.nth(0).unwrap();
131 assert_eq!(next as *const _, v_ptrs[i]);
133 assert_eq!(it.nth(0), None);
138 let mut it = v.iter_mut();
140 let remaining = len - i;
141 assert_eq!(it.size_hint(), (remaining, Some(remaining)));
143 let next = it.next().unwrap();
144 assert_eq!(next as *mut _, v_ptrs[i]);
146 assert_eq!(it.size_hint(), (0, Some(0)));
147 assert_eq!(it.next(), None, "The final call to next() should return None");
152 let mut it = v.iter_mut();
154 let remaining = len - i;
155 assert_eq!(it.size_hint(), (remaining, Some(remaining)));
157 let prev = it.next_back().unwrap();
158 assert_eq!(prev as *mut _, v_ptrs[remaining-1]);
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");
165 // Make sure iterators and slice patterns yield consistent addresses for various types,
169 test([0u32; 0]); // ZST with alignment > 0
172 test_mut([0u32; 0]); // ZST with alignment > 0
176 let mut values = Box::<[Box<u32>]>::new_uninit_slice(3);
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));
187 assert_eq!(values.iter().map(|x| **x).collect::<Vec<_>>(), vec![1, 2, 3])
192 test_iter_ref_consistency();