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