]> git.lizzy.rs Git - rust.git/blob - tests/ui/collapsible_match.rs
Add collapsible_match lint
[rust.git] / tests / ui / collapsible_match.rs
1 #![warn(clippy::collapsible_match)]
2 #![allow(clippy::needless_return, clippy::no_effect, clippy::single_match)]
3
4 fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>) {
5     // match without block
6     match res_opt {
7         Ok(val) => match val {
8             Some(n) => foo(n),
9             _ => return,
10         },
11         _ => return,
12     }
13
14     // match with block
15     match res_opt {
16         Ok(val) => match val {
17             Some(n) => foo(n),
18             _ => return,
19         },
20         _ => return,
21     }
22
23     // if let, if let
24     if let Ok(val) = res_opt {
25         if let Some(n) = val {
26             take(n);
27         }
28     }
29
30     // if let else, if let else
31     if let Ok(val) = res_opt {
32         if let Some(n) = val {
33             take(n);
34         } else {
35             return;
36         }
37     } else {
38         return;
39     }
40
41     // if let, match
42     if let Ok(val) = res_opt {
43         match val {
44             Some(n) => foo(n),
45             _ => (),
46         }
47     }
48
49     // match, if let
50     match res_opt {
51         Ok(val) => {
52             if let Some(n) = val {
53                 take(n);
54             }
55         },
56         _ => {},
57     }
58
59     // if let else, match
60     if let Ok(val) = res_opt {
61         match val {
62             Some(n) => foo(n),
63             _ => return,
64         }
65     } else {
66         return;
67     }
68
69     // match, if let else
70     match res_opt {
71         Ok(val) => {
72             if let Some(n) = val {
73                 take(n);
74             } else {
75                 return;
76             }
77         },
78         _ => return,
79     }
80
81     // None in inner match same as outer wild branch
82     match res_opt {
83         Ok(val) => match val {
84             Some(n) => foo(n),
85             None => return,
86         },
87         _ => return,
88     }
89
90     // None in outer match same as inner wild branch
91     match opt_opt {
92         Some(val) => match val {
93             Some(n) => foo(n),
94             _ => return,
95         },
96         None => return,
97     }
98
99     // if guards on outer match
100     {
101         match res_opt {
102             Ok(val) if make() => match val {
103                 Some(n) => foo(n),
104                 _ => return,
105             },
106             _ => return,
107         }
108         match res_opt {
109             Ok(val) => match val {
110                 Some(n) => foo(n),
111                 _ => return,
112             },
113             _ if make() => return,
114             _ => return,
115         }
116     }
117
118     // macro
119     {
120         macro_rules! mac {
121             ($outer:expr => $pat:pat, $e:expr => $inner_pat:pat, $then:expr) => {
122                 match $outer {
123                     $pat => match $e {
124                         $inner_pat => $then,
125                         _ => return,
126                     },
127                     _ => return,
128                 }
129             };
130         }
131         // Lint this since the patterns are not defined by the macro.
132         // Allows the lint to work on if_chain! for example.
133         // Fixing the lint requires knowledge of the specific macro, but we optimistically assume that
134         // there is still a better way to write this.
135         mac!(res_opt => Ok(val), val => Some(n), foo(n));
136     }
137 }
138
139 fn negative_cases(res_opt: Result<Option<u32>, String>, res_res: Result<Result<u32, String>, String>) {
140     // no wild pattern in outer match
141     match res_opt {
142         Ok(val) => match val {
143             Some(n) => foo(n),
144             _ => return,
145         },
146         Err(_) => return,
147     }
148
149     // inner branch is not wild or None
150     match res_res {
151         Ok(val) => match val {
152             Ok(n) => foo(n),
153             Err(_) => return,
154         },
155         _ => return,
156     }
157
158     // statement before inner match
159     match res_opt {
160         Ok(val) => {
161             "hi buddy";
162             match val {
163                 Some(n) => foo(n),
164                 _ => return,
165             }
166         },
167         _ => return,
168     }
169
170     // statement after inner match
171     match res_opt {
172         Ok(val) => {
173             match val {
174                 Some(n) => foo(n),
175                 _ => return,
176             }
177             "hi buddy";
178         },
179         _ => return,
180     }
181
182     // wild branches do not match
183     match res_opt {
184         Ok(val) => match val {
185             Some(n) => foo(n),
186             _ => {
187                 "sup";
188                 return;
189             },
190         },
191         _ => return,
192     }
193
194     // binding used in if guard
195     match res_opt {
196         Ok(val) if val.is_some() => match val {
197             Some(n) => foo(n),
198             _ => return,
199         },
200         _ => return,
201     }
202
203     // binding used in inner match body
204     match res_opt {
205         Ok(val) => match val {
206             Some(_) => take(val),
207             _ => return,
208         },
209         _ => return,
210     }
211
212     // if guard on inner match
213     {
214         match res_opt {
215             Ok(val) => match val {
216                 Some(n) if make() => foo(n),
217                 _ => return,
218             },
219             _ => return,
220         }
221         match res_opt {
222             Ok(val) => match val {
223                 _ => make(),
224                 _ if make() => return,
225             },
226             _ => return,
227         }
228     }
229
230     // differing macro contexts
231     {
232         macro_rules! mac {
233             ($val:ident) => {
234                 match $val {
235                     Some(n) => foo(n),
236                     _ => return,
237                 }
238             };
239         }
240         match res_opt {
241             Ok(val) => mac!(val),
242             _ => return,
243         }
244     }
245
246     // OR pattern
247     enum E<T> {
248         A(T),
249         B(T),
250         C(T),
251     };
252     match make::<E<Option<u32>>>() {
253         E::A(val) | E::B(val) => match val {
254             Some(n) => foo(n),
255             _ => return,
256         },
257         _ => return,
258     }
259     match make::<Option<E<u32>>>() {
260         Some(val) => match val {
261             E::A(val) | E::B(val) => foo(val),
262             _ => return,
263         },
264         _ => return,
265     }
266 }
267
268 fn make<T>() -> T {
269     unimplemented!()
270 }
271
272 fn foo<T, U>(t: T) -> U {
273     unimplemented!()
274 }
275
276 fn take<T>(t: T) {}
277
278 fn main() {}