4 #![warn(clippy, clippy_pedantic)]
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
)]
8 use std
::collections
::BTreeMap
;
9 use std
::collections
::HashMap
;
10 use std
::collections
::HashSet
;
11 use std
::collections
::VecDeque
;
13 use std
::iter
::FromIterator
;
14 use std
::rc
::{self, Rc}
;
15 use std
::sync
::{self, Arc}
;
20 pub fn add(self, other
: T
) -> T { self }
22 pub(crate) fn drop(&mut self) { }
// no error, not public interfact
23 fn neg(self) -> Self { self }
// no error, private function
24 fn eq(&self, other
: T
) -> bool { true }
// no error, private function
26 fn sub(&self, other
: T
) -> &T { self }
// no error, self is a ref
27 fn div(self) -> T { self }
// no error, different #arguments
28 fn rem(self, other
: T
) { }
// no error, wrong return type
30 fn into_u32(self) -> u32 { 0 }
// fine
31 fn into_u16(&self) -> u16 { 0 }
33 fn to_something(self) -> u32 { 0 }
43 // The lifetime is different, but that’s irrelevant, see #734
44 #[allow(needless_lifetimes)]
45 pub fn new
<'b
>(s
: &'b
str) -> Lt
<'b
> { unimplemented!() }
53 // The lifetime is different, but that’s irrelevant, see #734
54 pub fn new(s
: &str) -> Lt2 { unimplemented!() }
62 // The lifetime is different, but that’s irrelevant, see #734
63 pub fn new() -> Lt3
<'
static> { unimplemented!() }
70 fn new() -> Self { U }
71 fn to_something(self) -> u32 { 0 }
// ok because U is Copy
79 fn new() -> Option
<V
<T
>> { None }
84 fn mul(self, other
: T
) -> T { self }
// no error, obviously
87 /// Utility macro to test linting behavior in `option_methods()`
88 /// The lints included in `option_methods()` should not lint if the call to map is partially
90 macro_rules
! opt_map
{
91 ($opt
:expr
, $map
:expr
) => {($opt).map($map)}
;
94 /// Checks implementation of the following lints:
95 /// * `OPTION_MAP_UNWRAP_OR`
96 /// * `OPTION_MAP_UNWRAP_OR_ELSE`
97 /// * `OPTION_MAP_OR_NONE`
101 // Check OPTION_MAP_UNWRAP_OR
103 let _
= opt
.map(|x
| x
+ 1)
105 .unwrap_or(0); // should lint even though this call is on a separate line
107 let _
= opt
.map(|x
| {
111 let _
= opt
.map(|x
| x
+ 1)
115 // single line `map(f).unwrap_or(None)` case
116 let _
= opt
.map(|x
| Some(x
+ 1)).unwrap_or(None
);
117 // multiline `map(f).unwrap_or(None)` cases
118 let _
= opt
.map(|x
| {
123 .map(|x
| Some(x
+ 1))
126 let _
= opt_map
!(opt
, |x
| x
+ 1).unwrap_or(0); // should not lint
128 // Check OPTION_MAP_UNWRAP_OR_ELSE
130 let _
= opt
.map(|x
| x
+ 1)
132 .unwrap_or_else(|| 0); // should lint even though this call is on a separate line
134 let _
= opt
.map(|x
| {
137 ).unwrap_or_else(|| 0);
138 let _
= opt
.map(|x
| x
+ 1)
143 let _
= opt_map
!(opt
, |x
| x
+ 1).unwrap_or_else(|| 0); // should not lint
145 // Check OPTION_MAP_OR_NONE
147 let _
= opt
.map_or(None
, |x
| Some(x
+ 1));
149 let _
= opt
.map_or(None
, |x
| {
155 /// Checks implementation of the following lints:
156 /// * `RESULT_MAP_UNWRAP_OR_ELSE`
157 fn result_methods() {
158 let res
: Result
<i32, ()> = Ok(1);
160 // Check RESULT_MAP_UNWRAP_OR_ELSE
162 let _
= res
.map(|x
| x
+ 1)
164 .unwrap_or_else(|e
| 0); // should lint even though this call is on a separate line
166 let _
= res
.map(|x
| {
169 ).unwrap_or_else(|e
| 0);
170 let _
= res
.map(|x
| x
+ 1)
175 let _
= opt_map
!(res
, |x
| x
+ 1).unwrap_or_else(|e
| 0); // should not lint
178 /// Struct to generate false positives for things with .iter()
179 #[derive(Copy, Clone)]
183 fn iter(self) -> IteratorFalsePositives
{
184 IteratorFalsePositives { foo: 0 }
187 fn iter_mut(self) -> IteratorFalsePositives
{
188 IteratorFalsePositives { foo: 0 }
192 /// Struct to generate false positive for Iterator-based lints
193 #[derive(Copy, Clone)]
194 struct IteratorFalsePositives
{
198 impl IteratorFalsePositives
{
199 fn filter(self) -> IteratorFalsePositives
{
203 fn next(self) -> IteratorFalsePositives
{
207 fn find(self) -> Option
<u32> {
211 fn position(self) -> Option
<u32> {
215 fn rposition(self) -> Option
<u32> {
219 fn nth(self, n
: usize) -> Option
<u32> {
223 fn skip(self, _
: usize) -> IteratorFalsePositives
{
228 /// Checks implementation of `FILTER_NEXT` lint
230 let v
= vec
![3, 2, 1, 0, -1, -2, -3];
232 // check single-line case
233 let _
= v
.iter().filter(|&x
| *x
< 0).next();
235 // check multi-line case
236 let _
= v
.iter().filter(|&x
| {
241 // check that we don't lint if the caller is not an Iterator
242 let foo
= IteratorFalsePositives { foo: 0 }
;
243 let _
= foo
.filter().next();
246 /// Checks implementation of `SEARCH_IS_SOME` lint
247 fn search_is_some() {
248 let v
= vec
![3, 2, 1, 0, -1, -2, -3];
250 // check `find().is_some()`, single-line
251 let _
= v
.iter().find(|&x
| *x
< 0).is_some();
253 // check `find().is_some()`, multi-line
254 let _
= v
.iter().find(|&x
| {
259 // check `position().is_some()`, single-line
260 let _
= v
.iter().position(|&x
| x
< 0).is_some();
262 // check `position().is_some()`, multi-line
263 let _
= v
.iter().position(|&x
| {
268 // check `rposition().is_some()`, single-line
269 let _
= v
.iter().rposition(|&x
| x
< 0).is_some();
271 // check `rposition().is_some()`, multi-line
272 let _
= v
.iter().rposition(|&x
| {
277 // check that we don't lint if the caller is not an Iterator
278 let foo
= IteratorFalsePositives { foo: 0 }
;
279 let _
= foo
.find().is_some();
280 let _
= foo
.position().is_some();
281 let _
= foo
.rposition().is_some();
284 /// Checks implementation of the `OR_FUN_CALL` lint
289 fn new() -> Foo { Foo }
296 const fn make_const(i
: i32) -> i32 { i }
298 fn make
<T
>() -> T { unimplemented!(); }
300 let with_enum
= Some(Enum
::A(1));
301 with_enum
.unwrap_or(Enum
::A(5));
303 let with_const_fn
= Some(1);
304 with_const_fn
.unwrap_or(make_const(5));
306 let with_constructor
= Some(vec
![1]);
307 with_constructor
.unwrap_or(make());
309 let with_new
= Some(vec
![1]);
310 with_new
.unwrap_or(Vec
::new());
312 let with_const_args
= Some(vec
![1]);
313 with_const_args
.unwrap_or(Vec
::with_capacity(12));
315 let with_err
: Result
<_
, ()> = Ok(vec
![1]);
316 with_err
.unwrap_or(make());
318 let with_err_args
: Result
<_
, ()> = Ok(vec
![1]);
319 with_err_args
.unwrap_or(Vec
::with_capacity(12));
321 let with_default_trait
= Some(1);
322 with_default_trait
.unwrap_or(Default
::default());
324 let with_default_type
= Some(1);
325 with_default_type
.unwrap_or(u64::default());
327 let with_vec
= Some(vec
![1]);
328 with_vec
.unwrap_or(vec
![]);
330 // FIXME #944: ~|SUGGESTION with_vec.unwrap_or_else(|| vec![]);
332 let without_default
= Some(Foo
);
333 without_default
.unwrap_or(Foo
::new());
335 let mut map
= HashMap
::<u64, String
>::new();
336 map
.entry(42).or_insert(String
::new());
338 let mut btree
= BTreeMap
::<u64, String
>::new();
339 btree
.entry(42).or_insert(String
::new());
341 let stringy
= Some(String
::from(""));
342 let _
= stringy
.unwrap_or("".to_owned());
345 /// Checks implementation of `ITER_NTH` lint
347 let mut some_vec
= vec
![0, 1, 2, 3];
348 let mut boxed_slice
: Box
<[u8]> = Box
::new([0, 1, 2, 3]);
349 let mut some_vec_deque
: VecDeque
<_
> = some_vec
.iter().cloned().collect();
352 // Make sure we lint `.iter()` for relevant types
353 let bad_vec
= some_vec
.iter().nth(3);
354 let bad_slice
= &some_vec
[..].iter().nth(3);
355 let bad_boxed_slice
= boxed_slice
.iter().nth(3);
356 let bad_vec_deque
= some_vec_deque
.iter().nth(3);
360 // Make sure we lint `.iter_mut()` for relevant types
361 let bad_vec
= some_vec
.iter_mut().nth(3);
364 let bad_slice
= &some_vec
[..].iter_mut().nth(3);
367 let bad_vec_deque
= some_vec_deque
.iter_mut().nth(3);
370 // Make sure we don't lint for non-relevant types
371 let false_positive
= HasIter
;
372 let ok
= false_positive
.iter().nth(3);
373 let ok_mut
= false_positive
.iter_mut().nth(3);
376 /// Checks implementation of `ITER_SKIP_NEXT` lint
377 fn iter_skip_next() {
378 let mut some_vec
= vec
![0, 1, 2, 3];
379 let _
= some_vec
.iter().skip(42).next();
380 let _
= some_vec
.iter().cycle().skip(42).next();
381 let _
= (1..10).skip(10).next();
382 let _
= &some_vec
[..].iter().skip(3).next();
383 let foo
= IteratorFalsePositives { foo : 0 }
;
384 let _
= foo
.skip(42).next();
385 let _
= foo
.filter().skip(42).next();
388 #[allow(similar_names)]
391 let _
= opt
.unwrap();