]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/tests/ui/collapsible_match.rs
Rollup merge of #84221 - ABouttefeux:generic-arg-elision, r=estebank
[rust.git] / src / tools / clippy / 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
100 fn negative_cases(res_opt: Result<Option<u32>, String>, res_res: Result<Result<u32, String>, String>) {
101     // no wild pattern in outer match
102     match res_opt {
103         Ok(val) => match val {
104             Some(n) => foo(n),
105             _ => return,
106         },
107         Err(_) => return,
108     }
109
110     // inner branch is not wild or None
111     match res_res {
112         Ok(val) => match val {
113             Ok(n) => foo(n),
114             Err(_) => return,
115         },
116         _ => return,
117     }
118
119     // statement before inner match
120     match res_opt {
121         Ok(val) => {
122             "hi buddy";
123             match val {
124                 Some(n) => foo(n),
125                 _ => return,
126             }
127         },
128         _ => return,
129     }
130
131     // statement after inner match
132     match res_opt {
133         Ok(val) => {
134             match val {
135                 Some(n) => foo(n),
136                 _ => return,
137             }
138             "hi buddy";
139         },
140         _ => return,
141     }
142
143     // wild branches do not match
144     match res_opt {
145         Ok(val) => match val {
146             Some(n) => foo(n),
147             _ => {
148                 "sup";
149                 return;
150             },
151         },
152         _ => return,
153     }
154
155     // binding used in if guard
156     match res_opt {
157         Ok(val) if val.is_some() => match val {
158             Some(n) => foo(n),
159             _ => return,
160         },
161         _ => return,
162     }
163
164     // binding used in inner match body
165     match res_opt {
166         Ok(val) => match val {
167             Some(_) => take(val),
168             _ => return,
169         },
170         _ => return,
171     }
172
173     // if guard on inner match
174     {
175         match res_opt {
176             Ok(val) => match val {
177                 Some(n) if make() => foo(n),
178                 _ => return,
179             },
180             _ => return,
181         }
182         match res_opt {
183             Ok(val) => match val {
184                 _ => make(),
185                 _ if make() => return,
186             },
187             _ => return,
188         }
189     }
190
191     // differing macro contexts
192     {
193         macro_rules! mac {
194             ($val:ident) => {
195                 match $val {
196                     Some(n) => foo(n),
197                     _ => return,
198                 }
199             };
200         }
201         match res_opt {
202             Ok(val) => mac!(val),
203             _ => return,
204         }
205     }
206
207     // OR pattern
208     enum E<T> {
209         A(T),
210         B(T),
211         C(T),
212     };
213     match make::<E<Option<u32>>>() {
214         E::A(val) | E::B(val) => match val {
215             Some(n) => foo(n),
216             _ => return,
217         },
218         _ => return,
219     }
220     match make::<Option<E<u32>>>() {
221         Some(val) => match val {
222             E::A(val) | E::B(val) => foo(val),
223             _ => return,
224         },
225         _ => return,
226     }
227     if let Ok(val) = res_opt {
228         if let Some(n) = val {
229             let _ = || {
230                 // usage in closure
231                 println!("{:?}", val);
232             };
233         }
234     }
235     let _: &dyn std::any::Any = match &Some(Some(1)) {
236         Some(e) => match e {
237             Some(e) => e,
238             e => e,
239         },
240         // else branch looks the same but the binding is different
241         e => e,
242     };
243 }
244
245 fn make<T>() -> T {
246     unimplemented!()
247 }
248
249 fn foo<T, U>(t: T) -> U {
250     unimplemented!()
251 }
252
253 fn take<T>(t: T) {}
254
255 fn main() {}