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