]> git.lizzy.rs Git - rust.git/blob - library/alloc/tests/autotraits.rs
Rollup merge of #100462 - zohnannor:master, r=thomcc
[rust.git] / library / alloc / tests / autotraits.rs
1 fn require_sync<T: Sync>(_: T) {}
2 fn require_send_sync<T: Send + Sync>(_: T) {}
3
4 struct NotSend(*const ());
5 unsafe impl Sync for NotSend {}
6
7 #[test]
8 fn test_btree_map() {
9     // Tests of this form are prone to https://github.com/rust-lang/rust/issues/64552.
10     //
11     // In theory the async block's future would be Send if the value we hold
12     // across the await point is Send, and Sync if the value we hold across the
13     // await point is Sync.
14     //
15     // We test autotraits in this convoluted way, instead of a straightforward
16     // `require_send_sync::<TypeIWantToTest>()`, because the interaction with
17     // generators exposes some current limitations in rustc's ability to prove a
18     // lifetime bound on the erased generator witness types. See the above link.
19     //
20     // A typical way this would surface in real code is:
21     //
22     //     fn spawn<T: Future + Send>(_: T) {}
23     //
24     //     async fn f() {
25     //         let map = BTreeMap::<u32, Box<dyn Send + Sync>>::new();
26     //         for _ in &map {
27     //             async {}.await;
28     //         }
29     //     }
30     //
31     //     fn main() {
32     //         spawn(f());
33     //     }
34     //
35     // where with some unintentionally overconstrained Send impls in liballoc's
36     // internals, the future might incorrectly not be Send even though every
37     // single type involved in the program is Send and Sync.
38     require_send_sync(async {
39         let _v = None::<alloc::collections::btree_map::Iter<'_, &u32, &u32>>;
40         async {}.await;
41     });
42
43     // Testing like this would not catch all issues that the above form catches.
44     require_send_sync(None::<alloc::collections::btree_map::Iter<'_, &u32, &u32>>);
45
46     require_sync(async {
47         let _v = None::<alloc::collections::btree_map::Iter<'_, u32, NotSend>>;
48         async {}.await;
49     });
50
51     require_send_sync(async {
52         let _v = None::<alloc::collections::btree_map::BTreeMap<&u32, &u32>>;
53         async {}.await;
54     });
55
56     require_send_sync(async {
57         let _v = None::<
58             alloc::collections::btree_map::DrainFilter<
59                 '_,
60                 &u32,
61                 &u32,
62                 fn(&&u32, &mut &u32) -> bool,
63             >,
64         >;
65         async {}.await;
66     });
67
68     require_send_sync(async {
69         let _v = None::<alloc::collections::btree_map::Entry<'_, &u32, &u32>>;
70         async {}.await;
71     });
72
73     require_send_sync(async {
74         let _v = None::<alloc::collections::btree_map::IntoIter<&u32, &u32>>;
75         async {}.await;
76     });
77
78     require_send_sync(async {
79         let _v = None::<alloc::collections::btree_map::IntoKeys<&u32, &u32>>;
80         async {}.await;
81     });
82
83     require_send_sync(async {
84         let _v = None::<alloc::collections::btree_map::IntoValues<&u32, &u32>>;
85         async {}.await;
86     });
87
88     require_send_sync(async {
89         let _v = None::<alloc::collections::btree_map::Iter<'_, &u32, &u32>>;
90         async {}.await;
91     });
92
93     require_send_sync(async {
94         let _v = None::<alloc::collections::btree_map::IterMut<'_, &u32, &u32>>;
95         async {}.await;
96     });
97
98     require_send_sync(async {
99         let _v = None::<alloc::collections::btree_map::Keys<'_, &u32, &u32>>;
100         async {}.await;
101     });
102
103     require_send_sync(async {
104         let _v = None::<alloc::collections::btree_map::OccupiedEntry<'_, &u32, &u32>>;
105         async {}.await;
106     });
107
108     require_send_sync(async {
109         let _v = None::<alloc::collections::btree_map::OccupiedError<'_, &u32, &u32>>;
110         async {}.await;
111     });
112
113     require_send_sync(async {
114         let _v = None::<alloc::collections::btree_map::Range<'_, &u32, &u32>>;
115         async {}.await;
116     });
117
118     require_send_sync(async {
119         let _v = None::<alloc::collections::btree_map::RangeMut<'_, &u32, &u32>>;
120         async {}.await;
121     });
122
123     require_send_sync(async {
124         let _v = None::<alloc::collections::btree_map::VacantEntry<'_, &u32, &u32>>;
125         async {}.await;
126     });
127
128     require_send_sync(async {
129         let _v = None::<alloc::collections::btree_map::Values<'_, &u32, &u32>>;
130         async {}.await;
131     });
132
133     require_send_sync(async {
134         let _v = None::<alloc::collections::btree_map::ValuesMut<'_, &u32, &u32>>;
135         async {}.await;
136     });
137 }
138
139 #[test]
140 fn test_btree_set() {
141     require_send_sync(async {
142         let _v = None::<alloc::collections::btree_set::BTreeSet<&u32>>;
143         async {}.await;
144     });
145
146     require_send_sync(async {
147         let _v = None::<alloc::collections::btree_set::Difference<'_, &u32>>;
148         async {}.await;
149     });
150
151     require_send_sync(async {
152         let _v = None::<alloc::collections::btree_set::DrainFilter<'_, &u32, fn(&&u32) -> bool>>;
153         async {}.await;
154     });
155
156     require_send_sync(async {
157         let _v = None::<alloc::collections::btree_set::Intersection<'_, &u32>>;
158         async {}.await;
159     });
160
161     require_send_sync(async {
162         let _v = None::<alloc::collections::btree_set::IntoIter<&u32>>;
163         async {}.await;
164     });
165
166     require_send_sync(async {
167         let _v = None::<alloc::collections::btree_set::Iter<'_, &u32>>;
168         async {}.await;
169     });
170
171     require_send_sync(async {
172         let _v = None::<alloc::collections::btree_set::Range<'_, &u32>>;
173         async {}.await;
174     });
175
176     require_send_sync(async {
177         let _v = None::<alloc::collections::btree_set::SymmetricDifference<'_, &u32>>;
178         async {}.await;
179     });
180
181     require_send_sync(async {
182         let _v = None::<alloc::collections::btree_set::Union<'_, &u32>>;
183         async {}.await;
184     });
185 }
186
187 #[test]
188 fn test_binary_heap() {
189     require_send_sync(async {
190         let _v = None::<alloc::collections::binary_heap::BinaryHeap<&u32>>;
191         async {}.await;
192     });
193
194     require_send_sync(async {
195         let _v = None::<alloc::collections::binary_heap::Drain<'_, &u32>>;
196         async {}.await;
197     });
198
199     require_send_sync(async {
200         let _v = None::<alloc::collections::binary_heap::DrainSorted<'_, &u32>>;
201         async {}.await;
202     });
203
204     require_send_sync(async {
205         let _v = None::<alloc::collections::binary_heap::IntoIter<&u32>>;
206         async {}.await;
207     });
208
209     require_send_sync(async {
210         let _v = None::<alloc::collections::binary_heap::IntoIterSorted<&u32>>;
211         async {}.await;
212     });
213
214     require_send_sync(async {
215         let _v = None::<alloc::collections::binary_heap::Iter<'_, &u32>>;
216         async {}.await;
217     });
218
219     require_send_sync(async {
220         let _v = None::<alloc::collections::binary_heap::PeekMut<'_, &u32>>;
221         async {}.await;
222     });
223 }
224
225 #[test]
226 fn test_linked_list() {
227     require_send_sync(async {
228         let _v = None::<alloc::collections::linked_list::Cursor<'_, &u32>>;
229         async {}.await;
230     });
231
232     require_send_sync(async {
233         let _v = None::<alloc::collections::linked_list::CursorMut<'_, &u32>>;
234         async {}.await;
235     });
236
237     // FIXME
238     /*
239     require_send_sync(async {
240         let _v =
241             None::<alloc::collections::linked_list::DrainFilter<'_, &u32, fn(&mut &u32) -> bool>>;
242         async {}.await;
243     });
244     */
245
246     require_send_sync(async {
247         let _v = None::<alloc::collections::linked_list::IntoIter<&u32>>;
248         async {}.await;
249     });
250
251     require_send_sync(async {
252         let _v = None::<alloc::collections::linked_list::Iter<'_, &u32>>;
253         async {}.await;
254     });
255
256     require_send_sync(async {
257         let _v = None::<alloc::collections::linked_list::IterMut<'_, &u32>>;
258         async {}.await;
259     });
260
261     require_send_sync(async {
262         let _v = None::<alloc::collections::linked_list::LinkedList<&u32>>;
263         async {}.await;
264     });
265 }
266
267 #[test]
268 fn test_vec_deque() {
269     require_send_sync(async {
270         let _v = None::<alloc::collections::vec_deque::Drain<'_, &u32>>;
271         async {}.await;
272     });
273
274     require_send_sync(async {
275         let _v = None::<alloc::collections::vec_deque::IntoIter<&u32>>;
276         async {}.await;
277     });
278
279     require_send_sync(async {
280         let _v = None::<alloc::collections::vec_deque::Iter<'_, &u32>>;
281         async {}.await;
282     });
283
284     require_send_sync(async {
285         let _v = None::<alloc::collections::vec_deque::IterMut<'_, &u32>>;
286         async {}.await;
287     });
288
289     require_send_sync(async {
290         let _v = None::<alloc::collections::vec_deque::VecDeque<&u32>>;
291         async {}.await;
292     });
293 }