1 #![allow(unstable_name_collisions)]
2 
3 use itertools::Itertools;
4 
5 #[derive(Debug, Clone)]
6 #[must_use = "iterators are lazy and do nothing unless consumed"]
7 struct Panicking;
8 
9 impl Iterator for Panicking {
10     type Item = u8;
11 
next(&mut self) -> Option<u8>12     fn next(&mut self) -> Option<u8> {
13         panic!("iterator adaptor is not lazy")
14     }
15 
size_hint(&self) -> (usize, Option<usize>)16     fn size_hint(&self) -> (usize, Option<usize>) {
17         (0, Some(0))
18     }
19 }
20 
21 impl ExactSizeIterator for Panicking {}
22 
23 /// ## Usage example
24 /// ```compile_fail
25 /// must_use_tests! {
26 ///     name {
27 ///         Panicking.name(); // Add `let _ =` only if required (encountered error).
28 ///     }
29 ///     // ...
30 /// }
31 /// ```
32 ///
33 /// **TODO:** test missing `must_use` attributes better, maybe with a new lint.
34 macro_rules! must_use_tests {
35     ($($(#[$attr:meta])* $name:ident $body:block)*) => {
36         $(
37             /// `#[deny(unused_must_use)]` should force us to ignore the resulting iterators
38             /// by adding `let _ = ...;` on every iterator.
39             /// If it does not, then a `must_use` attribute is missing on the associated struct.
40             ///
41             /// However, it's only helpful if we don't add `let _ =` before seeing if there is an error or not.
42             /// And it does not protect us against removed `must_use` attributes.
43             /// There is no simple way to test this yet.
44             #[deny(unused_must_use)]
45             #[test]
46             $(#[$attr])*
47             fn $name() $body
48         )*
49     };
50 }
51 
52 must_use_tests! {
53     // Itertools trait:
54     interleave {
55         let _ = Panicking.interleave(Panicking);
56     }
57     interleave_shortest {
58         let _ = Panicking.interleave_shortest(Panicking);
59     }
60     intersperse {
61         let _ = Panicking.intersperse(0);
62     }
63     intersperse_with {
64         let _ = Panicking.intersperse_with(|| 0);
65     }
66     get {
67         let _ = Panicking.get(1..4);
68         let _ = Panicking.get(1..=4);
69         let _ = Panicking.get(1..);
70         let _ = Panicking.get(..4);
71         let _ = Panicking.get(..=4);
72         let _ = Panicking.get(..);
73     }
74     zip_longest {
75         let _ = Panicking.zip_longest(Panicking);
76     }
77     zip_eq {
78         let _ = Panicking.zip_eq(Panicking);
79     }
80     batching {
81         let _ = Panicking.batching(Iterator::next);
82     }
83     chunk_by {
84         // ChunkBy
85         let _ = Panicking.chunk_by(|x| *x);
86         // Groups
87         let _ = Panicking.chunk_by(|x| *x).into_iter();
88     }
89     chunks {
90         // IntoChunks
91         let _ = Panicking.chunks(1);
92         let _ = Panicking.chunks(2);
93         // Chunks
94         let _ = Panicking.chunks(1).into_iter();
95         let _ = Panicking.chunks(2).into_iter();
96     }
97     tuple_windows {
98         let _ = Panicking.tuple_windows::<(_,)>();
99         let _ = Panicking.tuple_windows::<(_, _)>();
100         let _ = Panicking.tuple_windows::<(_, _, _)>();
101     }
102     circular_tuple_windows {
103         let _ = Panicking.circular_tuple_windows::<(_,)>();
104         let _ = Panicking.circular_tuple_windows::<(_, _)>();
105         let _ = Panicking.circular_tuple_windows::<(_, _, _)>();
106     }
107     tuples {
108         let _ = Panicking.tuples::<(_,)>();
109         let _ = Panicking.tuples::<(_, _)>();
110         let _ = Panicking.tuples::<(_, _, _)>();
111     }
112     tee {
113         let _ = Panicking.tee();
114     }
115     map_into {
116         let _ = Panicking.map_into::<u16>();
117     }
118     map_ok {
119         let _ = Panicking.map(Ok::<u8, ()>).map_ok(|x| x + 1);
120     }
121     filter_ok {
122         let _ = Panicking.map(Ok::<u8, ()>).filter_ok(|x| x % 2 == 0);
123     }
124     filter_map_ok {
125         let _ = Panicking.map(Ok::<u8, ()>).filter_map_ok(|x| {
126             if x % 2 == 0 {
127                 Some(x + 1)
128             } else {
129                 None
130             }
131         });
132     }
133     flatten_ok {
134         let _ = Panicking.map(|x| Ok::<_, ()>([x])).flatten_ok();
135     }
136     merge {
137         let _ = Panicking.merge(Panicking);
138     }
139     merge_by {
140         let _ = Panicking.merge_by(Panicking, |_, _| true);
141     }
142     merge_join_by {
143         let _ = Panicking.merge_join_by(Panicking, |_, _| true);
144         let _ = Panicking.merge_join_by(Panicking, Ord::cmp);
145     }
146     #[should_panic]
147     kmerge {
148         let _ = Panicking.map(|_| Panicking).kmerge();
149     }
150     #[should_panic]
151     kmerge_by {
152         let _ = Panicking.map(|_| Panicking).kmerge_by(|_, _| true);
153     }
154     cartesian_product {
155         let _ = Panicking.cartesian_product(Panicking);
156     }
157     multi_cartesian_product {
158         let _ = vec![Panicking, Panicking, Panicking].into_iter().multi_cartesian_product();
159     }
160     coalesce {
161         let _ = Panicking.coalesce(|x, y| if x == y { Ok(x) } else { Err((x, y)) });
162     }
163     dedup {
164         let _ = Panicking.dedup();
165     }
166     dedup_by {
167         let _ = Panicking.dedup_by(|_, _| true);
168     }
169     dedup_with_count {
170         let _ = Panicking.dedup_with_count();
171     }
172     dedup_by_with_count {
173         let _ = Panicking.dedup_by_with_count(|_, _| true);
174     }
175     duplicates {
176         let _ = Panicking.duplicates();
177     }
178     duplicates_by {
179         let _ = Panicking.duplicates_by(|x| *x);
180     }
181     unique {
182         let _ = Panicking.unique();
183     }
184     unique_by {
185         let _ = Panicking.unique_by(|x| *x);
186     }
187     peeking_take_while {
188         let _ = Panicking.peekable().peeking_take_while(|x| x % 2 == 0);
189     }
190     take_while_ref {
191         let _ = Panicking.take_while_ref(|x| x % 2 == 0);
192     }
193     take_while_inclusive {
194         let _ = Panicking.take_while_inclusive(|x| x % 2 == 0);
195     }
196     while_some {
197         let _ = Panicking.map(Some).while_some();
198     }
199     tuple_combinations1 {
200         let _ = Panicking.tuple_combinations::<(_,)>();
201     }
202     #[should_panic]
203     tuple_combinations2 {
204         let _ = Panicking.tuple_combinations::<(_, _)>();
205     }
206     #[should_panic]
207     tuple_combinations3 {
208         let _ = Panicking.tuple_combinations::<(_, _, _)>();
209     }
210     combinations {
211         let _ = Panicking.combinations(0);
212         let _ = Panicking.combinations(1);
213         let _ = Panicking.combinations(2);
214     }
215     combinations_with_replacement {
216         let _ = Panicking.combinations_with_replacement(0);
217         let _ = Panicking.combinations_with_replacement(1);
218         let _ = Panicking.combinations_with_replacement(2);
219     }
220     permutations {
221         let _ = Panicking.permutations(0);
222         let _ = Panicking.permutations(1);
223         let _ = Panicking.permutations(2);
224     }
225     powerset {
226         let _ = Panicking.powerset();
227     }
228     pad_using {
229         let _ = Panicking.pad_using(25, |_| 10);
230     }
231     with_position {
232         let _ = Panicking.with_position();
233     }
234     positions {
235         let _ = Panicking.positions(|v| v % 2 == 0);
236     }
237     update {
238         let _ = Panicking.update(|n| *n += 1);
239     }
240     multipeek {
241         let _ = Panicking.multipeek();
242     }
243     // Not iterator themselves but still lazy.
244     into_grouping_map {
245         let _ = Panicking.map(|x| (x, x + 1)).into_grouping_map();
246     }
247     into_grouping_map_by {
248         let _ = Panicking.into_grouping_map_by(|x| *x);
249     }
250     // Macros:
251     iproduct {
252         let _ = itertools::iproduct!(Panicking);
253         let _ = itertools::iproduct!(Panicking, Panicking);
254         let _ = itertools::iproduct!(Panicking, Panicking, Panicking);
255     }
256     izip {
257         let _ = itertools::izip!(Panicking);
258         let _ = itertools::izip!(Panicking, Panicking);
259         let _ = itertools::izip!(Panicking, Panicking, Panicking);
260     }
261     chain {
262         let _ = itertools::chain!(Panicking);
263         let _ = itertools::chain!(Panicking, Panicking);
264         let _ = itertools::chain!(Panicking, Panicking, Panicking);
265     }
266     // Free functions:
267     multizip {
268         let _ = itertools::multizip((Panicking, Panicking));
269     }
270     put_back {
271         let _ = itertools::put_back(Panicking);
272         let _ = itertools::put_back(Panicking).with_value(15);
273     }
274     peek_nth {
275         let _ = itertools::peek_nth(Panicking);
276     }
277     put_back_n {
278         let _ = itertools::put_back_n(Panicking);
279     }
280     rciter {
281         let _ = itertools::rciter(Panicking);
282     }
283 }
284