]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/tests/ui/option_if_let_else.fixed
Auto merge of #97944 - nikic:freebsd-update, r=Mark-Simulacrum
[rust.git] / src / tools / clippy / tests / ui / option_if_let_else.fixed
1 // run-rustfix
2 #![warn(clippy::option_if_let_else)]
3 #![allow(
4     clippy::redundant_closure,
5     clippy::ref_option_ref,
6     clippy::equatable_if_let,
7     clippy::let_unit_value
8 )]
9
10 fn bad1(string: Option<&str>) -> (bool, &str) {
11     string.map_or((false, "hello"), |x| (true, x))
12 }
13
14 fn else_if_option(string: Option<&str>) -> Option<(bool, &str)> {
15     if string.is_none() {
16         None
17     } else if let Some(x) = string {
18         Some((true, x))
19     } else {
20         Some((false, ""))
21     }
22 }
23
24 fn unop_bad(string: &Option<&str>, mut num: Option<i32>) {
25     let _ = string.map_or(0, |s| s.len());
26     let _ = num.as_ref().map_or(&0, |s| s);
27     let _ = num.as_mut().map_or(&mut 0, |s| {
28         *s += 1;
29         s
30     });
31     let _ = num.as_ref().map_or(&0, |s| s);
32     let _ = num.map_or(0, |mut s| {
33         s += 1;
34         s
35     });
36     let _ = num.as_mut().map_or(&mut 0, |s| {
37         *s += 1;
38         s
39     });
40 }
41
42 fn longer_body(arg: Option<u32>) -> u32 {
43     arg.map_or(13, |x| {
44         let y = x * x;
45         y * y
46     })
47 }
48
49 fn impure_else(arg: Option<i32>) {
50     let side_effect = || {
51         println!("return 1");
52         1
53     };
54     let _ = arg.map_or_else(|| side_effect(), |x| x);
55 }
56
57 fn test_map_or_else(arg: Option<u32>) {
58     let _ = arg.map_or_else(|| {
59         let mut y = 1;
60         y = (y + 2 / y) / 2;
61         y = (y + 2 / y) / 2;
62         y
63     }, |x| x * x * x * x);
64 }
65
66 fn negative_tests(arg: Option<u32>) -> u32 {
67     let _ = if let Some(13) = arg { "unlucky" } else { "lucky" };
68     for _ in 0..10 {
69         let _ = if let Some(x) = arg {
70             x
71         } else {
72             continue;
73         };
74     }
75     let _ = if let Some(x) = arg {
76         return x;
77     } else {
78         5
79     };
80     7
81 }
82
83 // #7973
84 fn pattern_to_vec(pattern: &str) -> Vec<String> {
85     pattern
86         .trim_matches('/')
87         .split('/')
88         .flat_map(|s| {
89             s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])
90         })
91         .collect::<Vec<_>>()
92 }
93
94 enum DummyEnum {
95     One(u8),
96     Two,
97 }
98
99 // should not warn since there is a compled complex subpat
100 // see #7991
101 fn complex_subpat() -> DummyEnum {
102     let x = Some(DummyEnum::One(1));
103     let _ = if let Some(_one @ DummyEnum::One(..)) = x { 1 } else { 2 };
104     DummyEnum::Two
105 }
106
107 fn main() {
108     let optional = Some(5);
109     let _ = optional.map_or(5, |x| x + 2);
110     let _ = bad1(None);
111     let _ = else_if_option(None);
112     unop_bad(&None, None);
113     let _ = longer_body(None);
114     test_map_or_else(None);
115     let _ = negative_tests(None);
116     let _ = impure_else(None);
117
118     let _ = Some(0).map_or(0, |x| loop {
119             if x == 0 {
120                 break x;
121             }
122         });
123
124     // #7576
125     const fn _f(x: Option<u32>) -> u32 {
126         // Don't lint, `map_or` isn't const
127         if let Some(x) = x { x } else { 10 }
128     }
129
130     // #5822
131     let s = String::new();
132     // Don't lint, `Some` branch consumes `s`, but else branch uses `s`
133     let _ = if let Some(x) = Some(0) {
134         let s = s;
135         s.len() + x
136     } else {
137         s.len()
138     };
139
140     let s = String::new();
141     // Lint, both branches immutably borrow `s`.
142     let _ = Some(0).map_or(s.len(), |x| s.len() + x);
143
144     let s = String::new();
145     // Lint, `Some` branch consumes `s`, but else branch doesn't use `s`.
146     let _ = Some(0).map_or(1, |x| {
147         let s = s;
148         s.len() + x
149     });
150
151     let s = Some(String::new());
152     // Don't lint, `Some` branch borrows `s`, but else branch consumes `s`
153     let _ = if let Some(x) = &s {
154         x.len()
155     } else {
156         let _s = s;
157         10
158     };
159
160     let mut s = Some(String::new());
161     // Don't lint, `Some` branch mutably borrows `s`, but else branch also borrows  `s`
162     let _ = if let Some(x) = &mut s {
163         x.push_str("test");
164         x.len()
165     } else {
166         let _s = &s;
167         10
168     };
169
170     async fn _f1(x: u32) -> u32 {
171         x
172     }
173
174     async fn _f2() {
175         // Don't lint. `await` can't be moved into a closure.
176         let _ = if let Some(x) = Some(0) { _f1(x).await } else { 0 };
177     }
178
179     let _ = pattern_to_vec("hello world");
180     let _ = complex_subpat();
181 }