4 #![warn(clippy, clippy_pedantic, option_unwrap_used)]
5 #![allow(blacklisted_name, unused, print_stdout, non_ascii_literal, new_without_default,
6 new_without_default_derive, missing_docs_in_private_items, needless_pass_by_value,
7 default_trait_access, use_self)]
9 use std::collections::BTreeMap;
10 use std::collections::HashMap;
11 use std::collections::HashSet;
12 use std::collections::VecDeque;
14 use std::iter::FromIterator;
15 use std::rc::{self, Rc};
16 use std::sync::{self, Arc};
21 pub fn add(self, other: T) -> T { self }
23 pub(crate) fn drop(&mut self) { } // no error, not public interfact
24 fn neg(self) -> Self { self } // no error, private function
25 fn eq(&self, other: T) -> bool { true } // no error, private function
27 fn sub(&self, other: T) -> &T { self } // no error, self is a ref
28 fn div(self) -> T { self } // no error, different #arguments
29 fn rem(self, other: T) { } // no error, wrong return type
31 fn into_u32(self) -> u32 { 0 } // fine
32 fn into_u16(&self) -> u16 { 0 }
34 fn to_something(self) -> u32 { 0 }
44 // The lifetime is different, but that’s irrelevant, see #734
45 #[allow(needless_lifetimes)]
46 pub fn new<'b>(s: &'b str) -> Lt<'b> { unimplemented!() }
54 // The lifetime is different, but that’s irrelevant, see #734
55 pub fn new(s: &str) -> Lt2 { unimplemented!() }
63 // The lifetime is different, but that’s irrelevant, see #734
64 pub fn new() -> Lt3<'static> { unimplemented!() }
71 fn new() -> Self { U }
72 fn to_something(self) -> u32 { 0 } // ok because U is Copy
80 fn new() -> Option<V<T>> { None }
85 fn mul(self, other: T) -> T { self } // no error, obviously
88 /// Utility macro to test linting behavior in `option_methods()`
89 /// The lints included in `option_methods()` should not lint if the call to map is partially
91 macro_rules! opt_map {
92 ($opt:expr, $map:expr) => {($opt).map($map)};
95 /// Checks implementation of the following lints:
96 /// * `OPTION_MAP_UNWRAP_OR`
97 /// * `OPTION_MAP_UNWRAP_OR_ELSE`
98 /// * `OPTION_MAP_OR_NONE`
102 // Check OPTION_MAP_UNWRAP_OR
104 let _ = opt.map(|x| x + 1)
106 .unwrap_or(0); // should lint even though this call is on a separate line
108 let _ = opt.map(|x| {
112 let _ = opt.map(|x| x + 1)
116 // single line `map(f).unwrap_or(None)` case
117 let _ = opt.map(|x| Some(x + 1)).unwrap_or(None);
118 // multiline `map(f).unwrap_or(None)` cases
119 let _ = opt.map(|x| {
124 .map(|x| Some(x + 1))
127 let _ = opt_map!(opt, |x| x + 1).unwrap_or(0); // should not lint
129 // Check OPTION_MAP_UNWRAP_OR_ELSE
131 let _ = opt.map(|x| x + 1)
133 .unwrap_or_else(|| 0); // should lint even though this call is on a separate line
135 let _ = opt.map(|x| {
138 ).unwrap_or_else(|| 0);
139 let _ = opt.map(|x| x + 1)
144 let _ = opt_map!(opt, |x| x + 1).unwrap_or_else(|| 0); // should not lint
146 // Check OPTION_MAP_OR_NONE
148 let _ = opt.map_or(None, |x| Some(x + 1));
150 let _ = opt.map_or(None, |x| {
156 /// Checks implementation of the following lints:
157 /// * `RESULT_MAP_UNWRAP_OR_ELSE`
158 fn result_methods() {
159 let res: Result<i32, ()> = Ok(1);
161 // Check RESULT_MAP_UNWRAP_OR_ELSE
163 let _ = res.map(|x| x + 1)
165 .unwrap_or_else(|e| 0); // should lint even though this call is on a separate line
167 let _ = res.map(|x| {
170 ).unwrap_or_else(|e| 0);
171 let _ = res.map(|x| x + 1)
176 let _ = opt_map!(res, |x| x + 1).unwrap_or_else(|e| 0); // should not lint
179 /// Struct to generate false positives for things with .iter()
180 #[derive(Copy, Clone)]
184 fn iter(self) -> IteratorFalsePositives {
185 IteratorFalsePositives { foo: 0 }
188 fn iter_mut(self) -> IteratorFalsePositives {
189 IteratorFalsePositives { foo: 0 }
193 /// Struct to generate false positive for Iterator-based lints
194 #[derive(Copy, Clone)]
195 struct IteratorFalsePositives {
199 impl IteratorFalsePositives {
200 fn filter(self) -> IteratorFalsePositives {
204 fn next(self) -> IteratorFalsePositives {
208 fn find(self) -> Option<u32> {
212 fn position(self) -> Option<u32> {
216 fn rposition(self) -> Option<u32> {
220 fn nth(self, n: usize) -> Option<u32> {
224 fn skip(self, _: usize) -> IteratorFalsePositives {
229 /// Checks implementation of `FILTER_NEXT` lint
231 let v = vec![3, 2, 1, 0, -1, -2, -3];
233 // check single-line case
234 let _ = v.iter().filter(|&x| *x < 0).next();
236 // check multi-line case
237 let _ = v.iter().filter(|&x| {
242 // check that we don't lint if the caller is not an Iterator
243 let foo = IteratorFalsePositives { foo: 0 };
244 let _ = foo.filter().next();
247 /// Checks implementation of `SEARCH_IS_SOME` lint
248 fn search_is_some() {
249 let v = vec![3, 2, 1, 0, -1, -2, -3];
251 // check `find().is_some()`, single-line
252 let _ = v.iter().find(|&x| *x < 0).is_some();
254 // check `find().is_some()`, multi-line
255 let _ = v.iter().find(|&x| {
260 // check `position().is_some()`, single-line
261 let _ = v.iter().position(|&x| x < 0).is_some();
263 // check `position().is_some()`, multi-line
264 let _ = v.iter().position(|&x| {
269 // check `rposition().is_some()`, single-line
270 let _ = v.iter().rposition(|&x| x < 0).is_some();
272 // check `rposition().is_some()`, multi-line
273 let _ = v.iter().rposition(|&x| {
278 // check that we don't lint if the caller is not an Iterator
279 let foo = IteratorFalsePositives { foo: 0 };
280 let _ = foo.find().is_some();
281 let _ = foo.position().is_some();
282 let _ = foo.rposition().is_some();
285 /// Checks implementation of the `OR_FUN_CALL` lint
290 fn new() -> Foo { Foo }
297 const fn make_const(i: i32) -> i32 { i }
299 fn make<T>() -> T { unimplemented!(); }
301 let with_enum = Some(Enum::A(1));
302 with_enum.unwrap_or(Enum::A(5));
304 let with_const_fn = Some(1);
305 with_const_fn.unwrap_or(make_const(5));
307 let with_constructor = Some(vec![1]);
308 with_constructor.unwrap_or(make());
310 let with_new = Some(vec![1]);
311 with_new.unwrap_or(Vec::new());
313 let with_const_args = Some(vec![1]);
314 with_const_args.unwrap_or(Vec::with_capacity(12));
316 let with_err : Result<_, ()> = Ok(vec![1]);
317 with_err.unwrap_or(make());
319 let with_err_args : Result<_, ()> = Ok(vec![1]);
320 with_err_args.unwrap_or(Vec::with_capacity(12));
322 let with_default_trait = Some(1);
323 with_default_trait.unwrap_or(Default::default());
325 let with_default_type = Some(1);
326 with_default_type.unwrap_or(u64::default());
328 let with_vec = Some(vec![1]);
329 with_vec.unwrap_or(vec![]);
331 // FIXME #944: ~|SUGGESTION with_vec.unwrap_or_else(|| vec![]);
333 let without_default = Some(Foo);
334 without_default.unwrap_or(Foo::new());
336 let mut map = HashMap::<u64, String>::new();
337 map.entry(42).or_insert(String::new());
339 let mut btree = BTreeMap::<u64, String>::new();
340 btree.entry(42).or_insert(String::new());
342 let stringy = Some(String::from(""));
343 let _ = stringy.unwrap_or("".to_owned());
346 /// Checks implementation of the `EXPECT_FUN_CALL` lint
347 fn expect_fun_call() {
351 fn new() -> Self { Foo }
353 fn expect(&self, msg: &str) {
358 let with_some = Some("value");
359 with_some.expect("error");
361 let with_none: Option<i32> = None;
362 with_none.expect("error");
364 let error_code = 123_i32;
365 let with_none_and_format: Option<i32> = None;
366 with_none_and_format.expect(&format!("Error {}: fake error", error_code));
368 let with_none_and_as_str: Option<i32> = None;
369 with_none_and_as_str.expect(format!("Error {}: fake error", error_code).as_str());
371 let with_ok: Result<(), ()> = Ok(());
372 with_ok.expect("error");
374 let with_err: Result<(), ()> = Err(());
375 with_err.expect("error");
377 let error_code = 123_i32;
378 let with_err_and_format: Result<(), ()> = Err(());
379 with_err_and_format.expect(&format!("Error {}: fake error", error_code));
381 let with_err_and_as_str: Result<(), ()> = Err(());
382 with_err_and_as_str.expect(format!("Error {}: fake error", error_code).as_str());
384 let with_dummy_type = Foo::new();
385 with_dummy_type.expect("another test string");
387 let with_dummy_type_and_format = Foo::new();
388 with_dummy_type_and_format.expect(&format!("Error {}: fake error", error_code));
390 let with_dummy_type_and_as_str = Foo::new();
391 with_dummy_type_and_as_str.expect(format!("Error {}: fake error", error_code).as_str());
394 /// Checks implementation of `ITER_NTH` lint
396 let mut some_vec = vec![0, 1, 2, 3];
397 let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);
398 let mut some_vec_deque: VecDeque<_> = some_vec.iter().cloned().collect();
401 // Make sure we lint `.iter()` for relevant types
402 let bad_vec = some_vec.iter().nth(3);
403 let bad_slice = &some_vec[..].iter().nth(3);
404 let bad_boxed_slice = boxed_slice.iter().nth(3);
405 let bad_vec_deque = some_vec_deque.iter().nth(3);
409 // Make sure we lint `.iter_mut()` for relevant types
410 let bad_vec = some_vec.iter_mut().nth(3);
413 let bad_slice = &some_vec[..].iter_mut().nth(3);
416 let bad_vec_deque = some_vec_deque.iter_mut().nth(3);
419 // Make sure we don't lint for non-relevant types
420 let false_positive = HasIter;
421 let ok = false_positive.iter().nth(3);
422 let ok_mut = false_positive.iter_mut().nth(3);
425 /// Checks implementation of `ITER_SKIP_NEXT` lint
426 fn iter_skip_next() {
427 let mut some_vec = vec![0, 1, 2, 3];
428 let _ = some_vec.iter().skip(42).next();
429 let _ = some_vec.iter().cycle().skip(42).next();
430 let _ = (1..10).skip(10).next();
431 let _ = &some_vec[..].iter().skip(3).next();
432 let foo = IteratorFalsePositives { foo : 0 };
433 let _ = foo.skip(42).next();
434 let _ = foo.filter().skip(42).next();
437 #[allow(similar_names)]
440 let _ = opt.unwrap();