]> git.proxmox.com Git - rustc.git/blame - src/tools/clippy/tests/ui/option_if_let_else.rs
New upstream version 1.65.0+dfsg1
[rustc.git] / src / tools / clippy / tests / ui / option_if_let_else.rs
CommitLineData
f20569fa
XL
1// run-rustfix
2#![warn(clippy::option_if_let_else)]
04454e1e 3#![allow(
064997fb 4 unused_tuple_struct_fields,
04454e1e
FG
5 clippy::redundant_closure,
6 clippy::ref_option_ref,
7 clippy::equatable_if_let,
8 clippy::let_unit_value
9)]
f20569fa
XL
10
11fn bad1(string: Option<&str>) -> (bool, &str) {
12 if let Some(x) = string {
13 (true, x)
14 } else {
15 (false, "hello")
16 }
17}
18
19fn else_if_option(string: Option<&str>) -> Option<(bool, &str)> {
20 if string.is_none() {
21 None
22 } else if let Some(x) = string {
23 Some((true, x))
24 } else {
25 Some((false, ""))
26 }
27}
28
29fn unop_bad(string: &Option<&str>, mut num: Option<i32>) {
30 let _ = if let Some(s) = *string { s.len() } else { 0 };
31 let _ = if let Some(s) = &num { s } else { &0 };
32 let _ = if let Some(s) = &mut num {
33 *s += 1;
34 s
35 } else {
36 &mut 0
37 };
38 let _ = if let Some(ref s) = num { s } else { &0 };
39 let _ = if let Some(mut s) = num {
40 s += 1;
41 s
42 } else {
43 0
44 };
45 let _ = if let Some(ref mut s) = num {
46 *s += 1;
47 s
48 } else {
49 &mut 0
50 };
51}
52
53fn longer_body(arg: Option<u32>) -> u32 {
54 if let Some(x) = arg {
55 let y = x * x;
56 y * y
57 } else {
58 13
59 }
60}
61
62fn impure_else(arg: Option<i32>) {
63 let side_effect = || {
64 println!("return 1");
65 1
66 };
67 let _ = if let Some(x) = arg {
68 x
69 } else {
70 // map_or_else must be suggested
71 side_effect()
72 };
73}
74
75fn test_map_or_else(arg: Option<u32>) {
76 let _ = if let Some(x) = arg {
77 x * x * x * x
78 } else {
79 let mut y = 1;
80 y = (y + 2 / y) / 2;
81 y = (y + 2 / y) / 2;
82 y
83 };
84}
85
86fn negative_tests(arg: Option<u32>) -> u32 {
87 let _ = if let Some(13) = arg { "unlucky" } else { "lucky" };
88 for _ in 0..10 {
89 let _ = if let Some(x) = arg {
90 x
91 } else {
92 continue;
93 };
94 }
95 let _ = if let Some(x) = arg {
96 return x;
97 } else {
98 5
99 };
100 7
101}
102
a2a8927a
XL
103// #7973
104fn pattern_to_vec(pattern: &str) -> Vec<String> {
105 pattern
106 .trim_matches('/')
107 .split('/')
108 .flat_map(|s| {
109 if let Some(idx) = s.find('.') {
110 vec![s[..idx].to_string(), s[idx..].to_string()]
111 } else {
112 vec![s.to_string()]
113 }
114 })
115 .collect::<Vec<_>>()
116}
117
118enum DummyEnum {
119 One(u8),
120 Two,
121}
122
123// should not warn since there is a compled complex subpat
124// see #7991
125fn complex_subpat() -> DummyEnum {
126 let x = Some(DummyEnum::One(1));
127 let _ = if let Some(_one @ DummyEnum::One(..)) = x { 1 } else { 2 };
128 DummyEnum::Two
129}
130
f20569fa
XL
131fn main() {
132 let optional = Some(5);
133 let _ = if let Some(x) = optional { x + 2 } else { 5 };
134 let _ = bad1(None);
135 let _ = else_if_option(None);
136 unop_bad(&None, None);
137 let _ = longer_body(None);
138 test_map_or_else(None);
139 let _ = negative_tests(None);
140 let _ = impure_else(None);
c295e0f8
XL
141
142 let _ = if let Some(x) = Some(0) {
143 loop {
144 if x == 0 {
145 break x;
146 }
147 }
148 } else {
149 0
150 };
151
152 // #7576
153 const fn _f(x: Option<u32>) -> u32 {
154 // Don't lint, `map_or` isn't const
155 if let Some(x) = x { x } else { 10 }
156 }
157
158 // #5822
159 let s = String::new();
160 // Don't lint, `Some` branch consumes `s`, but else branch uses `s`
161 let _ = if let Some(x) = Some(0) {
162 let s = s;
163 s.len() + x
164 } else {
165 s.len()
166 };
167
168 let s = String::new();
169 // Lint, both branches immutably borrow `s`.
170 let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() };
171
172 let s = String::new();
173 // Lint, `Some` branch consumes `s`, but else branch doesn't use `s`.
174 let _ = if let Some(x) = Some(0) {
175 let s = s;
176 s.len() + x
177 } else {
178 1
179 };
180
181 let s = Some(String::new());
182 // Don't lint, `Some` branch borrows `s`, but else branch consumes `s`
183 let _ = if let Some(x) = &s {
184 x.len()
185 } else {
186 let _s = s;
187 10
188 };
189
190 let mut s = Some(String::new());
191 // Don't lint, `Some` branch mutably borrows `s`, but else branch also borrows `s`
192 let _ = if let Some(x) = &mut s {
193 x.push_str("test");
194 x.len()
195 } else {
196 let _s = &s;
197 10
198 };
199
200 async fn _f1(x: u32) -> u32 {
201 x
202 }
203
204 async fn _f2() {
205 // Don't lint. `await` can't be moved into a closure.
206 let _ = if let Some(x) = Some(0) { _f1(x).await } else { 0 };
207 }
a2a8927a
XL
208
209 let _ = pattern_to_vec("hello world");
210 let _ = complex_subpat();
f2b60f7d
FG
211
212 // issue #8492
213 let _ = match s {
214 Some(string) => string.len(),
215 None => 1,
216 };
217 let _ = match Some(10) {
218 Some(a) => a + 1,
219 None => 5,
220 };
221
222 let res: Result<i32, i32> = Ok(5);
223 let _ = match res {
224 Ok(a) => a + 1,
225 _ => 1,
226 };
227 let _ = match res {
228 Err(_) => 1,
229 Ok(a) => a + 1,
230 };
231 let _ = if let Ok(a) = res { a + 1 } else { 5 };
f20569fa 232}