]> git.lizzy.rs Git - rust.git/blob - src/tools/miri/tests/pass/vec.rs
Fix invalid float literal suggestions when recovering an integer
[rust.git] / src / tools / miri / tests / pass / vec.rs
1 //@compile-flags: -Zmiri-strict-provenance
2 #![feature(iter_advance_by, iter_next_chunk)]
3
4 // Gather all references from a mutable iterator and make sure Miri notices if
5 // using them is dangerous.
6 fn test_all_refs<'a, T: 'a>(dummy: &mut T, iter: impl Iterator<Item = &'a mut T>) {
7     // Gather all those references.
8     let mut refs: Vec<&mut T> = iter.collect();
9     // Use them all. Twice, to be sure we got all interleavings.
10     for r in refs.iter_mut() {
11         std::mem::swap(dummy, r);
12     }
13     for r in refs {
14         std::mem::swap(dummy, r);
15     }
16 }
17
18 fn make_vec() -> Vec<u8> {
19     let mut v = Vec::with_capacity(4);
20     v.push(1);
21     v.push(2);
22     v
23 }
24
25 fn make_vec_macro() -> Vec<u8> {
26     vec![1, 2]
27 }
28
29 fn make_vec_macro_repeat() -> Vec<u8> {
30     vec![42; 5]
31 }
32
33 fn make_vec_macro_repeat_zeroed() -> Vec<u8> {
34     vec![0; 7]
35 }
36
37 fn vec_into_iter() -> u8 {
38     vec![1, 2, 3, 4].into_iter().map(|x| x * x).fold(0, |x, y| x + y)
39 }
40
41 fn vec_into_iter_rev() -> u8 {
42     vec![1, 2, 3, 4].into_iter().rev().map(|x| x * x).fold(0, |x, y| x + y)
43 }
44
45 fn vec_into_iter_zst() {
46     for _ in vec![[0u64; 0]].into_iter() {}
47     let v = vec![[0u64; 0], [0u64; 0]].into_iter().map(|x| x.len()).sum::<usize>();
48     assert_eq!(v, 0);
49
50     let mut it = vec![[0u64; 0], [0u64; 0]].into_iter();
51     it.advance_by(1).unwrap();
52     drop(it);
53
54     let mut it = vec![[0u64; 0], [0u64; 0]].into_iter();
55     it.next_chunk::<1>().unwrap();
56     drop(it);
57
58     let mut it = vec![[0u64; 0], [0u64; 0]].into_iter();
59     it.next_chunk::<4>().unwrap_err();
60     drop(it);
61 }
62
63 fn vec_into_iter_rev_zst() {
64     for _ in vec![[0u64; 0]; 5].into_iter().rev() {}
65     let v = vec![[0u64; 0], [0u64; 0]].into_iter().rev().map(|x| x.len()).sum::<usize>();
66     assert_eq!(v, 0);
67 }
68
69 fn vec_iter_and_mut() {
70     let mut v = vec![1, 2, 3, 4];
71     for i in v.iter_mut() {
72         *i += 1;
73     }
74     assert_eq!(v.iter().sum::<i32>(), 2 + 3 + 4 + 5);
75
76     test_all_refs(&mut 13, v.iter_mut());
77 }
78
79 fn vec_iter_and_mut_rev() {
80     let mut v = vec![1, 2, 3, 4];
81     for i in v.iter_mut().rev() {
82         *i += 1;
83     }
84     assert_eq!(v.iter().sum::<i32>(), 2 + 3 + 4 + 5);
85 }
86
87 fn vec_reallocate() -> Vec<u8> {
88     let mut v = vec![1, 2];
89     v.push(3);
90     v.push(4);
91     v.push(5);
92     v
93 }
94
95 fn vec_push_ptr_stable() {
96     let mut v = Vec::with_capacity(10);
97     v.push(0);
98     let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
99     v.push(1);
100     let _val = *v0;
101 }
102
103 fn vec_extend_ptr_stable() {
104     let mut v = Vec::with_capacity(10);
105     v.push(0);
106     let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
107     // `slice::Iter` (with `T: Copy`) specialization
108     v.extend(&[1]);
109     let _val = *v0;
110     // `vec::IntoIter` specialization
111     v.extend(vec![2]);
112     let _val = *v0;
113     // `TrustedLen` specialization
114     v.extend(std::iter::once(3));
115     let _val = *v0;
116     // base case
117     v.extend(std::iter::once(3).filter(|_| true));
118     let _val = *v0;
119 }
120
121 fn vec_truncate_ptr_stable() {
122     let mut v = vec![0; 10];
123     let v0 = unsafe { &mut *(&mut v[0] as *mut _) }; // laundering the lifetime -- we take care that `v` does not reallocate, so that's okay.
124     v.truncate(5);
125     let _val = *v0;
126 }
127
128 fn push_str_ptr_stable() {
129     let mut buf = String::with_capacity(11);
130     buf.push_str("hello");
131     let hello: &str = unsafe { &*(buf.as_str() as *const _) }; // laundering the lifetime -- we take care that `buf` does not reallocate, so that's okay.
132     buf.push_str(" world");
133     assert_eq!(format!("{}", hello), "hello");
134 }
135
136 fn sort() {
137     let mut v = vec![1; 20];
138     v.push(0);
139     v.sort();
140 }
141
142 fn swap() {
143     let mut v = vec![1, 2, 3, 4];
144     v.swap(2, 2);
145 }
146
147 fn swap_remove() {
148     let mut a = 0;
149     let mut b = 1;
150     let mut vec = vec![&mut a, &mut b];
151
152     vec.swap_remove(1);
153 }
154
155 fn reverse() {
156     #[repr(align(2))]
157     #[derive(Debug)]
158     struct Foo(u8);
159
160     let mut v: Vec<_> = (0..50).map(Foo).collect();
161     v.reverse();
162     assert!(v[0].0 == 49);
163 }
164
165 fn main() {
166     assert_eq!(vec_reallocate().len(), 5);
167
168     assert_eq!(vec_into_iter(), 30);
169     assert_eq!(vec_into_iter_rev(), 30);
170     vec_iter_and_mut();
171     vec_into_iter_zst();
172     vec_into_iter_rev_zst();
173     vec_iter_and_mut_rev();
174
175     assert_eq!(make_vec().capacity(), 4);
176     assert_eq!(make_vec_macro(), [1, 2]);
177     assert_eq!(make_vec_macro_repeat(), [42; 5]);
178     assert_eq!(make_vec_macro_repeat_zeroed(), [0; 7]);
179
180     // Test interesting empty slice comparison
181     // (one is a real pointer, one an integer pointer).
182     assert_eq!((200..-5).step_by(1).collect::<Vec<isize>>(), []);
183
184     // liballoc has a more extensive test of this, but let's at least do a smoke test here.
185     vec_push_ptr_stable();
186     vec_extend_ptr_stable();
187     vec_truncate_ptr_stable();
188     push_str_ptr_stable();
189
190     sort();
191     swap();
192     swap_remove();
193     reverse();
194 }