| #![warn(clippy::len_without_is_empty, clippy::len_zero)] |
| #![allow(dead_code, unused)] |
| |
| pub struct PubOne; |
| |
| impl PubOne { |
| pub fn len(self: &Self) -> isize { |
| 1 |
| } |
| } |
| |
| impl PubOne { |
| // A second impl for this struct -- the error span shouldn't mention this. |
| pub fn irrelevant(self: &Self) -> bool { |
| false |
| } |
| } |
| |
| // Identical to `PubOne`, but with an `allow` attribute on the impl complaining `len`. |
| pub struct PubAllowed; |
| |
| #[allow(clippy::len_without_is_empty)] |
| impl PubAllowed { |
| pub fn len(self: &Self) -> isize { |
| 1 |
| } |
| } |
| |
| // No `allow` attribute on this impl block, but that doesn't matter -- we only require one on the |
| // impl containing `len`. |
| impl PubAllowed { |
| pub fn irrelevant(self: &Self) -> bool { |
| false |
| } |
| } |
| |
| struct NotPubOne; |
| |
| impl NotPubOne { |
| pub fn len(self: &Self) -> isize { |
| // No error; `len` is pub but `NotPubOne` is not exported anyway. |
| 1 |
| } |
| } |
| |
| struct One; |
| |
| impl One { |
| fn len(self: &Self) -> isize { |
| // No error; `len` is private; see issue #1085. |
| 1 |
| } |
| } |
| |
| pub trait PubTraitsToo { |
| fn len(self: &Self) -> isize; |
| } |
| |
| impl PubTraitsToo for One { |
| fn len(self: &Self) -> isize { |
| 0 |
| } |
| } |
| |
| trait TraitsToo { |
| fn len(self: &Self) -> isize; |
| // No error; `len` is private; see issue #1085. |
| } |
| |
| impl TraitsToo for One { |
| fn len(self: &Self) -> isize { |
| 0 |
| } |
| } |
| |
| struct HasPrivateIsEmpty; |
| |
| impl HasPrivateIsEmpty { |
| pub fn len(self: &Self) -> isize { |
| 1 |
| } |
| |
| fn is_empty(self: &Self) -> bool { |
| false |
| } |
| } |
| |
| pub struct HasIsEmpty; |
| |
| impl HasIsEmpty { |
| pub fn len(self: &Self) -> isize { |
| 1 |
| } |
| |
| fn is_empty(self: &Self) -> bool { |
| false |
| } |
| } |
| |
| struct Wither; |
| |
| pub trait WithIsEmpty { |
| fn len(self: &Self) -> isize; |
| fn is_empty(self: &Self) -> bool; |
| } |
| |
| impl WithIsEmpty for Wither { |
| fn len(self: &Self) -> isize { |
| 1 |
| } |
| |
| fn is_empty(self: &Self) -> bool { |
| false |
| } |
| } |
| |
| pub struct HasWrongIsEmpty; |
| |
| impl HasWrongIsEmpty { |
| pub fn len(self: &Self) -> isize { |
| 1 |
| } |
| |
| pub fn is_empty(self: &Self, x: u32) -> bool { |
| false |
| } |
| } |
| |
| pub trait Empty { |
| fn is_empty(&self) -> bool; |
| } |
| |
| pub trait InheritingEmpty: Empty { |
| // Must not trigger `LEN_WITHOUT_IS_EMPTY`. |
| fn len(&self) -> isize; |
| } |
| |
| fn main() { |
| let x = [1, 2]; |
| if x.len() == 0 { |
| println!("This should not happen!"); |
| } |
| |
| if "".len() == 0 {} |
| |
| let y = One; |
| if y.len() == 0 { |
| // No error; `One` does not have `.is_empty()`. |
| println!("This should not happen either!"); |
| } |
| |
| let z: &TraitsToo = &y; |
| if z.len() > 0 { |
| // No error; `TraitsToo` has no `.is_empty()` method. |
| println!("Nor should this!"); |
| } |
| |
| let has_is_empty = HasIsEmpty; |
| if has_is_empty.len() == 0 { |
| println!("Or this!"); |
| } |
| if has_is_empty.len() != 0 { |
| println!("Or this!"); |
| } |
| if has_is_empty.len() > 0 { |
| println!("Or this!"); |
| } |
| if has_is_empty.len() < 1 { |
| println!("Or this!"); |
| } |
| if has_is_empty.len() >= 1 { |
| println!("Or this!"); |
| } |
| if has_is_empty.len() > 1 { |
| // No error. |
| println!("This can happen."); |
| } |
| if has_is_empty.len() <= 1 { |
| // No error. |
| println!("This can happen."); |
| } |
| if 0 == has_is_empty.len() { |
| println!("Or this!"); |
| } |
| if 0 != has_is_empty.len() { |
| println!("Or this!"); |
| } |
| if 0 < has_is_empty.len() { |
| println!("Or this!"); |
| } |
| if 1 <= has_is_empty.len() { |
| println!("Or this!"); |
| } |
| if 1 > has_is_empty.len() { |
| println!("Or this!"); |
| } |
| if 1 < has_is_empty.len() { |
| // No error. |
| println!("This can happen."); |
| } |
| if 1 >= has_is_empty.len() { |
| // No error. |
| println!("This can happen."); |
| } |
| assert!(!has_is_empty.is_empty()); |
| |
| let with_is_empty: &WithIsEmpty = &Wither; |
| if with_is_empty.len() == 0 { |
| println!("Or this!"); |
| } |
| assert!(!with_is_empty.is_empty()); |
| |
| let has_wrong_is_empty = HasWrongIsEmpty; |
| if has_wrong_is_empty.len() == 0 { |
| // No error; `HasWrongIsEmpty` does not have `.is_empty()`. |
| println!("Or this!"); |
| } |
| } |
| |
| fn test_slice(b: &[u8]) { |
| if b.len() != 0 {} |
| } |
| |
| // This used to ICE. |
| pub trait Foo: Sized {} |
| |
| pub trait DependsOnFoo: Foo { |
| fn len(&mut self) -> usize; |
| } |