]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/tests/ui/single_match.rs
Rollup merge of #102812 - est31:remove_lazy, r=dtolnay
[rust.git] / src / tools / clippy / tests / ui / single_match.rs
1 #![warn(clippy::single_match)]
2 #![allow(clippy::uninlined_format_args)]
3
4 fn dummy() {}
5
6 fn single_match() {
7     let x = Some(1u8);
8
9     match x {
10         Some(y) => {
11             println!("{:?}", y);
12         },
13         _ => (),
14     };
15
16     let x = Some(1u8);
17     match x {
18         // Note the missing block braces.
19         // We suggest `if let Some(y) = x { .. }` because the macro
20         // is expanded before we can do anything.
21         Some(y) => println!("{:?}", y),
22         _ => (),
23     }
24
25     let z = (1u8, 1u8);
26     match z {
27         (2..=3, 7..=9) => dummy(),
28         _ => {},
29     };
30
31     // Not linted (pattern guards used)
32     match x {
33         Some(y) if y == 0 => println!("{:?}", y),
34         _ => (),
35     }
36
37     // Not linted (no block with statements in the single arm)
38     match z {
39         (2..=3, 7..=9) => println!("{:?}", z),
40         _ => println!("nope"),
41     }
42 }
43
44 enum Foo {
45     Bar,
46     Baz(u8),
47 }
48 use std::borrow::Cow;
49 use Foo::*;
50
51 fn single_match_know_enum() {
52     let x = Some(1u8);
53     let y: Result<_, i8> = Ok(1i8);
54
55     match x {
56         Some(y) => dummy(),
57         None => (),
58     };
59
60     match y {
61         Ok(y) => dummy(),
62         Err(..) => (),
63     };
64
65     let c = Cow::Borrowed("");
66
67     match c {
68         Cow::Borrowed(..) => dummy(),
69         Cow::Owned(..) => (),
70     };
71
72     let z = Foo::Bar;
73     // no warning
74     match z {
75         Bar => println!("42"),
76         Baz(_) => (),
77     }
78
79     match z {
80         Baz(_) => println!("42"),
81         Bar => (),
82     }
83 }
84
85 // issue #173
86 fn if_suggestion() {
87     let x = "test";
88     match x {
89         "test" => println!(),
90         _ => (),
91     }
92
93     #[derive(PartialEq, Eq)]
94     enum Foo {
95         A,
96         B,
97         C(u32),
98     }
99
100     let x = Foo::A;
101     match x {
102         Foo::A => println!(),
103         _ => (),
104     }
105
106     const FOO_C: Foo = Foo::C(0);
107     match x {
108         FOO_C => println!(),
109         _ => (),
110     }
111
112     match &&x {
113         Foo::A => println!(),
114         _ => (),
115     }
116
117     let x = &x;
118     match &x {
119         Foo::A => println!(),
120         _ => (),
121     }
122
123     enum Bar {
124         A,
125         B,
126     }
127     impl PartialEq for Bar {
128         fn eq(&self, rhs: &Self) -> bool {
129             matches!((self, rhs), (Self::A, Self::A) | (Self::B, Self::B))
130         }
131     }
132     impl Eq for Bar {}
133
134     let x = Bar::A;
135     match x {
136         Bar::A => println!(),
137         _ => (),
138     }
139
140     // issue #7038
141     struct X;
142     let x = Some(X);
143     match x {
144         None => println!(),
145         _ => (),
146     };
147 }
148
149 // See: issue #8282
150 fn ranges() {
151     enum E {
152         V,
153     }
154     let x = (Some(E::V), Some(42));
155
156     // Don't lint, because the `E` enum can be extended with additional fields later. Thus, the
157     // proposed replacement to `if let Some(E::V)` may hide non-exhaustive warnings that appeared
158     // because of `match` construction.
159     match x {
160         (Some(E::V), _) => {},
161         (None, _) => {},
162     }
163
164     // lint
165     match x {
166         (Some(_), _) => {},
167         (None, _) => {},
168     }
169
170     // lint
171     match x {
172         (Some(E::V), _) => todo!(),
173         (_, _) => {},
174     }
175
176     // lint
177     match (Some(42), Some(E::V), Some(42)) {
178         (.., Some(E::V), _) => {},
179         (..) => {},
180     }
181
182     // Don't lint, see above.
183     match (Some(E::V), Some(E::V), Some(E::V)) {
184         (.., Some(E::V), _) => {},
185         (.., None, _) => {},
186     }
187
188     // Don't lint, see above.
189     match (Some(E::V), Some(E::V), Some(E::V)) {
190         (Some(E::V), ..) => {},
191         (None, ..) => {},
192     }
193
194     // Don't lint, see above.
195     match (Some(E::V), Some(E::V), Some(E::V)) {
196         (_, Some(E::V), ..) => {},
197         (_, None, ..) => {},
198     }
199 }
200
201 fn skip_type_aliases() {
202     enum OptionEx {
203         Some(i32),
204         None,
205     }
206     enum ResultEx {
207         Err(i32),
208         Ok(i32),
209     }
210
211     use OptionEx::{None, Some};
212     use ResultEx::{Err, Ok};
213
214     // don't lint
215     match Err(42) {
216         Ok(_) => dummy(),
217         Err(_) => (),
218     };
219
220     // don't lint
221     match Some(1i32) {
222         Some(_) => dummy(),
223         None => (),
224     };
225 }
226
227 macro_rules! single_match {
228     ($num:literal) => {
229         match $num {
230             15 => println!("15"),
231             _ => (),
232         }
233     };
234 }
235
236 fn main() {
237     single_match!(5);
238
239     // Don't lint
240     let _ = match Some(0) {
241         #[cfg(feature = "foo")]
242         Some(10) => 11,
243         Some(x) => x,
244         _ => 0,
245     };
246 }