]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/tests/ui/needless_match.rs
809c694bf400464bb4685b115010b04c63ce6147
[rust.git] / src / tools / clippy / tests / ui / needless_match.rs
1 // run-rustfix
2 #![warn(clippy::needless_match)]
3 #![allow(clippy::manual_map)]
4 #![allow(dead_code)]
5
6 #[derive(Clone, Copy)]
7 enum Simple {
8     A,
9     B,
10     C,
11     D,
12 }
13
14 fn useless_match() {
15     let i = 10;
16     let _: i32 = match i {
17         0 => 0,
18         1 => 1,
19         2 => 2,
20         _ => i,
21     };
22     let s = "test";
23     let _: &str = match s {
24         "a" => "a",
25         "b" => "b",
26         s => s,
27     };
28 }
29
30 fn custom_type_match() {
31     let se = Simple::A;
32     let _: Simple = match se {
33         Simple::A => Simple::A,
34         Simple::B => Simple::B,
35         Simple::C => Simple::C,
36         Simple::D => Simple::D,
37     };
38     // Don't trigger
39     let _: Simple = match se {
40         Simple::A => Simple::A,
41         Simple::B => Simple::B,
42         _ => Simple::C,
43     };
44     // Mingled, don't trigger
45     let _: Simple = match se {
46         Simple::A => Simple::B,
47         Simple::B => Simple::C,
48         Simple::C => Simple::D,
49         Simple::D => Simple::A,
50     };
51 }
52
53 fn option_match(x: Option<i32>) {
54     let _: Option<i32> = match x {
55         Some(a) => Some(a),
56         None => None,
57     };
58     // Don't trigger, this is the case for manual_map_option
59     let _: Option<i32> = match x {
60         Some(a) => Some(-a),
61         None => None,
62     };
63 }
64
65 fn func_ret_err<T>(err: T) -> Result<i32, T> {
66     Err(err)
67 }
68
69 fn result_match() {
70     let _: Result<i32, i32> = match Ok(1) {
71         Ok(a) => Ok(a),
72         Err(err) => Err(err),
73     };
74     let _: Result<i32, i32> = match func_ret_err(0_i32) {
75         Err(err) => Err(err),
76         Ok(a) => Ok(a),
77     };
78     // as ref, don't trigger
79     let res = &func_ret_err(0_i32);
80     let _: Result<&i32, &i32> = match *res {
81         Ok(ref x) => Ok(x),
82         Err(ref x) => Err(x),
83     };
84 }
85
86 fn if_let_option() {
87     let _ = if let Some(a) = Some(1) { Some(a) } else { None };
88
89     fn do_something() {}
90
91     // Don't trigger
92     let _ = if let Some(a) = Some(1) {
93         Some(a)
94     } else {
95         do_something();
96         None
97     };
98
99     // Don't trigger
100     let _ = if let Some(a) = Some(1) {
101         do_something();
102         Some(a)
103     } else {
104         None
105     };
106
107     // Don't trigger
108     let _ = if let Some(a) = Some(1) { Some(a) } else { Some(2) };
109 }
110
111 fn if_let_option_result() -> Result<(), ()> {
112     fn f(x: i32) -> Result<Option<i32>, ()> {
113         Ok(Some(x))
114     }
115     // Don't trigger
116     let _ = if let Some(v) = f(1)? { Some(v) } else { f(2)? };
117     Ok(())
118 }
119
120 fn if_let_result() {
121     let x: Result<i32, i32> = Ok(1);
122     let _: Result<i32, i32> = if let Err(e) = x { Err(e) } else { x };
123     let _: Result<i32, i32> = if let Ok(val) = x { Ok(val) } else { x };
124     // Input type mismatch, don't trigger
125     #[allow(clippy::question_mark)]
126     let _: Result<i32, i32> = if let Err(e) = Ok(1) { Err(e) } else { x };
127 }
128
129 fn if_let_custom_enum(x: Simple) {
130     let _: Simple = if let Simple::A = x {
131         Simple::A
132     } else if let Simple::B = x {
133         Simple::B
134     } else if let Simple::C = x {
135         Simple::C
136     } else {
137         x
138     };
139
140     // Don't trigger
141     let _: Simple = if let Simple::A = x {
142         Simple::A
143     } else if true {
144         Simple::B
145     } else {
146         x
147     };
148 }
149
150 mod issue8542 {
151     #[derive(Clone, Copy)]
152     enum E {
153         VariantA(u8, u8),
154         VariantB(u8, bool),
155     }
156
157     enum Complex {
158         A(u8),
159         B(u8, bool),
160         C(u8, i32, f64),
161         D(E, bool),
162     }
163
164     fn match_test() {
165         let ce = Complex::B(8, false);
166         let aa = 0_u8;
167         let bb = false;
168
169         let _: Complex = match ce {
170             Complex::A(a) => Complex::A(a),
171             Complex::B(a, b) => Complex::B(a, b),
172             Complex::C(a, b, c) => Complex::C(a, b, c),
173             Complex::D(E::VariantA(ea, eb), b) => Complex::D(E::VariantA(ea, eb), b),
174             Complex::D(E::VariantB(ea, eb), b) => Complex::D(E::VariantB(ea, eb), b),
175         };
176
177         // Don't trigger
178         let _: Complex = match ce {
179             Complex::A(_) => Complex::A(aa),
180             Complex::B(_, b) => Complex::B(aa, b),
181             Complex::C(_, b, _) => Complex::C(aa, b, 64_f64),
182             Complex::D(e, b) => Complex::D(e, b),
183         };
184
185         // Don't trigger
186         let _: Complex = match ce {
187             Complex::A(a) => Complex::A(a),
188             Complex::B(a, _) => Complex::B(a, bb),
189             Complex::C(a, _, _) => Complex::C(a, 32_i32, 64_f64),
190             _ => ce,
191         };
192     }
193 }
194
195 /// Lint triggered when type coercions happen.
196 /// Do NOT trigger on any of these.
197 mod issue8551 {
198     trait Trait {}
199     struct Struct;
200     impl Trait for Struct {}
201
202     fn optmap(s: Option<&Struct>) -> Option<&dyn Trait> {
203         match s {
204             Some(s) => Some(s),
205             None => None,
206         }
207     }
208
209     fn lint_tests() {
210         let option: Option<&Struct> = None;
211         let _: Option<&dyn Trait> = match option {
212             Some(s) => Some(s),
213             None => None,
214         };
215
216         let _: Option<&dyn Trait> = if true {
217             match option {
218                 Some(s) => Some(s),
219                 None => None,
220             }
221         } else {
222             None
223         };
224
225         let result: Result<&Struct, i32> = Err(0);
226         let _: Result<&dyn Trait, i32> = match result {
227             Ok(s) => Ok(s),
228             Err(e) => Err(e),
229         };
230
231         let _: Option<&dyn Trait> = if let Some(s) = option { Some(s) } else { None };
232     }
233 }
234
235 trait Tr {
236     fn as_mut(&mut self) -> Result<&mut i32, &mut i32>;
237 }
238 impl Tr for Result<i32, i32> {
239     fn as_mut(&mut self) -> Result<&mut i32, &mut i32> {
240         match self {
241             Ok(x) => Ok(x),
242             Err(e) => Err(e),
243         }
244     }
245 }
246
247 mod issue9084 {
248     fn wildcard_if() {
249         let mut some_bool = true;
250         let e = Some(1);
251
252         // should lint
253         let _ = match e {
254             _ if some_bool => e,
255             _ => e,
256         };
257
258         // should lint
259         let _ = match e {
260             Some(i) => Some(i),
261             _ if some_bool => e,
262             _ => e,
263         };
264
265         // should not lint
266         let _ = match e {
267             _ if some_bool => e,
268             _ => Some(2),
269         };
270
271         // should not lint
272         let _ = match e {
273             Some(i) => Some(i + 1),
274             _ if some_bool => e,
275             _ => e,
276         };
277
278         // should not lint (guard has side effects)
279         let _ = match e {
280             Some(i) => Some(i),
281             _ if {
282                 some_bool = false;
283                 some_bool
284             } =>
285             {
286                 e
287             },
288             _ => e,
289         };
290     }
291 }
292
293 fn main() {}