]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/tests/ui/match_same_arms2.rs
Rollup merge of #102581 - jyn514:src-detection, r=Mark-Simulacrum
[rust.git] / src / tools / clippy / tests / ui / match_same_arms2.rs
1 #![warn(clippy::match_same_arms)]
2 #![allow(
3     clippy::disallowed_names,
4     clippy::diverging_sub_expression,
5     clippy::uninlined_format_args
6 )]
7
8 fn bar<T>(_: T) {}
9 fn foo() -> bool {
10     unimplemented!()
11 }
12
13 fn match_same_arms() {
14     let _ = match 42 {
15         42 => {
16             foo();
17             let mut a = 42 + [23].len() as i32;
18             if true {
19                 a += 7;
20             }
21             a = -31 - a;
22             a
23         },
24         _ => {
25             //~ ERROR match arms have same body
26             foo();
27             let mut a = 42 + [23].len() as i32;
28             if true {
29                 a += 7;
30             }
31             a = -31 - a;
32             a
33         },
34     };
35
36     let _ = match 42 {
37         42 => foo(),
38         51 => foo(), //~ ERROR match arms have same body
39         _ => true,
40     };
41
42     let _ = match Some(42) {
43         Some(_) => 24,
44         None => 24, //~ ERROR match arms have same body
45     };
46
47     let _ = match Some(42) {
48         Some(foo) => 24,
49         None => 24,
50     };
51
52     let _ = match Some(42) {
53         Some(42) => 24,
54         Some(a) => 24, // bindings are different
55         None => 0,
56     };
57
58     let _ = match Some(42) {
59         Some(a) if a > 0 => 24,
60         Some(a) => 24, // one arm has a guard
61         None => 0,
62     };
63
64     match (Some(42), Some(42)) {
65         (Some(a), None) => bar(a),
66         (None, Some(a)) => bar(a), //~ ERROR match arms have same body
67         _ => (),
68     }
69
70     match (Some(42), Some(42)) {
71         (Some(a), ..) => bar(a),
72         (.., Some(a)) => bar(a), //~ ERROR match arms have same body
73         _ => (),
74     }
75
76     let _ = match Some(()) {
77         Some(()) => 0.0,
78         None => -0.0,
79     };
80
81     match (Some(42), Some("")) {
82         (Some(a), None) => bar(a),
83         (None, Some(a)) => bar(a), // bindings have different types
84         _ => (),
85     }
86
87     let x: Result<i32, &str> = Ok(3);
88
89     // No warning because of the guard.
90     match x {
91         Ok(x) if x * x == 64 => println!("ok"),
92         Ok(_) => println!("ok"),
93         Err(_) => println!("err"),
94     }
95
96     // This used to be a false positive; see issue #1996.
97     match x {
98         Ok(3) => println!("ok"),
99         Ok(x) if x * x == 64 => println!("ok 64"),
100         Ok(_) => println!("ok"),
101         Err(_) => println!("err"),
102     }
103
104     match (x, Some(1i32)) {
105         (Ok(x), Some(_)) => println!("ok {}", x),
106         (Ok(_), Some(x)) => println!("ok {}", x),
107         _ => println!("err"),
108     }
109
110     // No warning; different types for `x`.
111     match (x, Some(1.0f64)) {
112         (Ok(x), Some(_)) => println!("ok {}", x),
113         (Ok(_), Some(x)) => println!("ok {}", x),
114         _ => println!("err"),
115     }
116
117     // False negative #2251.
118     match x {
119         Ok(_tmp) => println!("ok"),
120         Ok(3) => println!("ok"),
121         Ok(_) => println!("ok"),
122         Err(_) => {
123             unreachable!();
124         },
125     }
126
127     // False positive #1390
128     macro_rules! empty {
129         ($e:expr) => {};
130     }
131     match 0 {
132         0 => {
133             empty!(0);
134         },
135         1 => {
136             empty!(1);
137         },
138         x => {
139             empty!(x);
140         },
141     };
142
143     // still lint if the tokens are the same
144     match 0 {
145         0 => {
146             empty!(0);
147         },
148         1 => {
149             empty!(0);
150         },
151         x => {
152             empty!(x);
153         },
154     }
155
156     match_expr_like_matches_macro_priority();
157 }
158
159 fn match_expr_like_matches_macro_priority() {
160     enum E {
161         A,
162         B,
163         C,
164     }
165     let x = E::A;
166     let _ans = match x {
167         E::A => false,
168         E::B => false,
169         _ => true,
170     };
171 }
172
173 fn main() {
174     let _ = match Some(0) {
175         Some(0) => 0,
176         Some(1) => 1,
177         #[cfg(feature = "foo")]
178         Some(2) => 2,
179         _ => 1,
180     };
181
182     enum Foo {
183         X(u32),
184         Y(u32),
185         Z(u32),
186     }
187
188     // Don't lint. `Foo::X(0)` and `Foo::Z(_)` overlap with the arm in between.
189     let _ = match Foo::X(0) {
190         Foo::X(0) => 1,
191         Foo::X(_) | Foo::Y(_) | Foo::Z(0) => 2,
192         Foo::Z(_) => 1,
193         _ => 0,
194     };
195
196     // Suggest moving `Foo::Z(_)` up.
197     let _ = match Foo::X(0) {
198         Foo::X(0) => 1,
199         Foo::X(_) | Foo::Y(_) => 2,
200         Foo::Z(_) => 1,
201         _ => 0,
202     };
203
204     // Suggest moving `Foo::X(0)` down.
205     let _ = match Foo::X(0) {
206         Foo::X(0) => 1,
207         Foo::Y(_) | Foo::Z(0) => 2,
208         Foo::Z(_) => 1,
209         _ => 0,
210     };
211
212     // Don't lint.
213     let _ = match 0 {
214         -2 => 1,
215         -5..=50 => 2,
216         -150..=88 => 1,
217         _ => 3,
218     };
219
220     struct Bar {
221         x: u32,
222         y: u32,
223         z: u32,
224     }
225
226     // Lint.
227     let _ = match None {
228         Some(Bar { x: 0, y: 5, .. }) => 1,
229         Some(Bar { y: 10, z: 0, .. }) => 2,
230         None => 50,
231         Some(Bar { y: 0, x: 5, .. }) => 1,
232         _ => 200,
233     };
234
235     let _ = match 0 {
236         0 => todo!(),
237         1 => todo!(),
238         2 => core::convert::identity::<u32>(todo!()),
239         3 => core::convert::identity::<u32>(todo!()),
240         _ => 5,
241     };
242 }