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