]> git.proxmox.com Git - rustc.git/blob - src/tools/clippy/tests/ui/or_fun_call.rs
New upstream version 1.73.0+dfsg1
[rustc.git] / src / tools / clippy / tests / ui / or_fun_call.rs
1 //@run-rustfix
2 #![warn(clippy::or_fun_call)]
3 #![allow(dead_code)]
4 #![allow(
5 clippy::borrow_as_ptr,
6 clippy::uninlined_format_args,
7 clippy::unnecessary_wraps,
8 clippy::unnecessary_literal_unwrap,
9 clippy::useless_vec
10 )]
11
12 use std::collections::{BTreeMap, HashMap};
13 use std::time::Duration;
14
15 /// Checks implementation of the `OR_FUN_CALL` lint.
16 fn or_fun_call() {
17 struct Foo;
18
19 impl Foo {
20 fn new() -> Foo {
21 Foo
22 }
23 }
24
25 struct FakeDefault;
26 impl FakeDefault {
27 fn default() -> Self {
28 FakeDefault
29 }
30 }
31
32 impl Default for FakeDefault {
33 fn default() -> Self {
34 FakeDefault
35 }
36 }
37
38 enum Enum {
39 A(i32),
40 }
41
42 fn make<T>() -> T {
43 unimplemented!();
44 }
45
46 let with_enum = Some(Enum::A(1));
47 with_enum.unwrap_or(Enum::A(5));
48
49 let with_const_fn = Some(Duration::from_secs(1));
50 with_const_fn.unwrap_or(Duration::from_secs(5));
51
52 let with_constructor = Some(vec![1]);
53 with_constructor.unwrap_or(make());
54
55 let with_new = Some(vec![1]);
56 with_new.unwrap_or(Vec::new());
57
58 let with_const_args = Some(vec![1]);
59 with_const_args.unwrap_or(Vec::with_capacity(12));
60
61 let with_err: Result<_, ()> = Ok(vec![1]);
62 with_err.unwrap_or(make());
63
64 let with_err_args: Result<_, ()> = Ok(vec![1]);
65 with_err_args.unwrap_or(Vec::with_capacity(12));
66
67 let with_default_trait = Some(1);
68 with_default_trait.unwrap_or(Default::default());
69
70 let with_default_type = Some(1);
71 with_default_type.unwrap_or(u64::default());
72
73 let self_default = None::<FakeDefault>;
74 self_default.unwrap_or(<FakeDefault>::default());
75
76 let real_default = None::<FakeDefault>;
77 real_default.unwrap_or(<FakeDefault as Default>::default());
78
79 let with_vec = Some(vec![1]);
80 with_vec.unwrap_or(vec![]);
81
82 let without_default = Some(Foo);
83 without_default.unwrap_or(Foo::new());
84
85 let mut map = HashMap::<u64, String>::new();
86 map.entry(42).or_insert(String::new());
87
88 let mut map_vec = HashMap::<u64, Vec<i32>>::new();
89 map_vec.entry(42).or_insert(vec![]);
90
91 let mut btree = BTreeMap::<u64, String>::new();
92 btree.entry(42).or_insert(String::new());
93
94 let mut btree_vec = BTreeMap::<u64, Vec<i32>>::new();
95 btree_vec.entry(42).or_insert(vec![]);
96
97 let stringy = Some(String::new());
98 let _ = stringy.unwrap_or(String::new());
99
100 let opt = Some(1);
101 let hello = "Hello";
102 let _ = opt.ok_or(format!("{} world.", hello));
103
104 // index
105 let map = HashMap::<u64, u64>::new();
106 let _ = Some(1).unwrap_or(map[&1]);
107 let map = BTreeMap::<u64, u64>::new();
108 let _ = Some(1).unwrap_or(map[&1]);
109 // don't lint index vec
110 let vec = vec![1];
111 let _ = Some(1).unwrap_or(vec[1]);
112 }
113
114 struct Foo(u8);
115 struct Bar(String, Duration);
116 #[rustfmt::skip]
117 fn test_or_with_ctors() {
118 let opt = Some(1);
119 let opt_opt = Some(Some(1));
120 // we also test for const promotion, this makes sure we don't hit that
121 let two = 2;
122
123 let _ = opt_opt.unwrap_or(Some(2));
124 let _ = opt_opt.unwrap_or(Some(two));
125 let _ = opt.ok_or(Some(2));
126 let _ = opt.ok_or(Some(two));
127 let _ = opt.ok_or(Foo(2));
128 let _ = opt.ok_or(Foo(two));
129 let _ = opt.or(Some(2));
130 let _ = opt.or(Some(two));
131
132 let _ = Some("a".to_string()).or(Some("b".to_string()));
133
134 let b = "b".to_string();
135 let _ = Some(Bar("a".to_string(), Duration::from_secs(1)))
136 .or(Some(Bar(b, Duration::from_secs(2))));
137
138 let vec = vec!["foo"];
139 let _ = opt.ok_or(vec.len());
140
141 let array = ["foo"];
142 let _ = opt.ok_or(array.len());
143
144 let slice = &["foo"][..];
145 let _ = opt.ok_or(slice.len());
146
147 let string = "foo";
148 let _ = opt.ok_or(string.len());
149 }
150
151 // Issue 4514 - early return
152 fn f() -> Option<()> {
153 let a = Some(1);
154 let b = 1i32;
155
156 let _ = a.unwrap_or(b.checked_mul(3)?.min(240));
157
158 Some(())
159 }
160
161 mod issue6675 {
162 unsafe fn ptr_to_ref<'a, T>(p: *const T) -> &'a T {
163 #[allow(unused)]
164 let x = vec![0; 1000]; // future-proofing, make this function expensive.
165 &*p
166 }
167
168 unsafe fn foo() {
169 let s = "test".to_owned();
170 let s = &s as *const _;
171 None.unwrap_or(ptr_to_ref(s));
172 }
173
174 fn bar() {
175 let s = "test".to_owned();
176 let s = &s as *const _;
177 None.unwrap_or(unsafe { ptr_to_ref(s) });
178 #[rustfmt::skip]
179 None.unwrap_or( unsafe { ptr_to_ref(s) } );
180 }
181 }
182
183 mod issue8239 {
184 fn more_than_max_suggestion_highest_lines_0() {
185 let frames = Vec::new();
186 frames
187 .iter()
188 .map(|f: &String| f.to_lowercase())
189 .reduce(|mut acc, f| {
190 acc.push_str(&f);
191 acc
192 })
193 .unwrap_or(String::new());
194 }
195
196 fn more_to_max_suggestion_highest_lines_1() {
197 let frames = Vec::new();
198 let iter = frames.iter();
199 iter.map(|f: &String| f.to_lowercase())
200 .reduce(|mut acc, f| {
201 let _ = "";
202 let _ = "";
203 acc.push_str(&f);
204 acc
205 })
206 .unwrap_or(String::new());
207 }
208
209 fn equal_to_max_suggestion_highest_lines() {
210 let frames = Vec::new();
211 let iter = frames.iter();
212 iter.map(|f: &String| f.to_lowercase())
213 .reduce(|mut acc, f| {
214 let _ = "";
215 acc.push_str(&f);
216 acc
217 })
218 .unwrap_or(String::new());
219 }
220
221 fn less_than_max_suggestion_highest_lines() {
222 let frames = Vec::new();
223 let iter = frames.iter();
224 let map = iter.map(|f: &String| f.to_lowercase());
225 map.reduce(|mut acc, f| {
226 acc.push_str(&f);
227 acc
228 })
229 .unwrap_or(String::new());
230 }
231 }
232
233 mod issue9608 {
234 fn sig_drop() {
235 enum X {
236 X(std::fs::File),
237 Y(u32),
238 }
239
240 let _ = None.unwrap_or(X::Y(0));
241 }
242 }
243
244 mod issue8993 {
245 fn g() -> i32 {
246 3
247 }
248
249 fn f(n: i32) -> i32 {
250 n
251 }
252
253 fn test_map_or() {
254 let _ = Some(4).map_or(g(), |v| v);
255 let _ = Some(4).map_or(g(), f);
256 let _ = Some(4).map_or(0, f);
257 }
258 }
259
260 mod lazy {
261 use super::*;
262
263 fn foo() {
264 struct Foo;
265
266 impl Foo {
267 fn new() -> Foo {
268 Foo
269 }
270 }
271
272 struct FakeDefault;
273 impl FakeDefault {
274 fn default() -> Self {
275 FakeDefault
276 }
277 }
278
279 impl Default for FakeDefault {
280 fn default() -> Self {
281 FakeDefault
282 }
283 }
284
285 let with_new = Some(vec![1]);
286 with_new.unwrap_or_else(Vec::new);
287
288 let with_default_trait = Some(1);
289 with_default_trait.unwrap_or_else(Default::default);
290
291 let with_default_type = Some(1);
292 with_default_type.unwrap_or_else(u64::default);
293
294 let real_default = None::<FakeDefault>;
295 real_default.unwrap_or_else(<FakeDefault as Default>::default);
296
297 let mut map = HashMap::<u64, String>::new();
298 map.entry(42).or_insert_with(String::new);
299
300 let mut btree = BTreeMap::<u64, String>::new();
301 btree.entry(42).or_insert_with(String::new);
302
303 let stringy = Some(String::new());
304 let _ = stringy.unwrap_or_else(String::new);
305
306 // negative tests
307 let self_default = None::<FakeDefault>;
308 self_default.unwrap_or_else(<FakeDefault>::default);
309
310 let without_default = Some(Foo);
311 without_default.unwrap_or_else(Foo::new);
312 }
313 }
314
315 fn main() {}