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