-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #3978 - phansch:rustfix_len_zero, r=flip1995
Add run-rustfix for len_zero lint * Extracts len_without_is_empty into separate file * Adds `// run-rustfix` to `tests/ui/len_zero.rs` cc #3630
- Loading branch information
Showing
5 changed files
with
367 additions
and
163 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
#![warn(clippy::len_without_is_empty)] | ||
#![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 | ||
} | ||
} | ||
|
||
pub trait PubTraitsToo { | ||
fn len(self: &Self) -> isize; | ||
} | ||
|
||
impl PubTraitsToo for One { | ||
fn len(self: &Self) -> isize { | ||
0 | ||
} | ||
} | ||
|
||
pub struct HasIsEmpty; | ||
|
||
impl HasIsEmpty { | ||
pub 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 | ||
} | ||
} | ||
|
||
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 | ||
} | ||
} | ||
|
||
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 | ||
} | ||
} | ||
|
||
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 trait Empty { | ||
fn is_empty(&self) -> bool; | ||
} | ||
|
||
pub trait InheritingEmpty: Empty { | ||
// Must not trigger `LEN_WITHOUT_IS_EMPTY`. | ||
fn len(&self) -> isize; | ||
} | ||
|
||
// This used to ICE. | ||
pub trait Foo: Sized {} | ||
|
||
pub trait DependsOnFoo: Foo { | ||
fn len(&mut self) -> usize; | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
error: item `PubOne` has a public `len` method but no corresponding `is_empty` method | ||
--> $DIR/len_without_is_empty.rs:6:1 | ||
| | ||
LL | / impl PubOne { | ||
LL | | pub fn len(self: &Self) -> isize { | ||
LL | | 1 | ||
LL | | } | ||
LL | | } | ||
| |_^ | ||
| | ||
= note: `-D clippy::len-without-is-empty` implied by `-D warnings` | ||
|
||
error: trait `PubTraitsToo` has a `len` method but no (possibly inherited) `is_empty` method | ||
--> $DIR/len_without_is_empty.rs:37:1 | ||
| | ||
LL | / pub trait PubTraitsToo { | ||
LL | | fn len(self: &Self) -> isize; | ||
LL | | } | ||
| |_^ | ||
|
||
error: item `HasIsEmpty` has a public `len` method but a private `is_empty` method | ||
--> $DIR/len_without_is_empty.rs:49:1 | ||
| | ||
LL | / impl HasIsEmpty { | ||
LL | | pub fn len(self: &Self) -> isize { | ||
LL | | 1 | ||
LL | | } | ||
... | | ||
LL | | } | ||
LL | | } | ||
| |_^ | ||
|
||
error: item `HasWrongIsEmpty` has a public `len` method but no corresponding `is_empty` method | ||
--> $DIR/len_without_is_empty.rs:61:1 | ||
| | ||
LL | / impl HasWrongIsEmpty { | ||
LL | | pub fn len(self: &Self) -> isize { | ||
LL | | 1 | ||
LL | | } | ||
... | | ||
LL | | } | ||
LL | | } | ||
| |_^ | ||
|
||
error: trait `DependsOnFoo` has a `len` method but no (possibly inherited) `is_empty` method | ||
--> $DIR/len_without_is_empty.rs:141:1 | ||
| | ||
LL | / pub trait DependsOnFoo: Foo { | ||
LL | | fn len(&mut self) -> usize; | ||
LL | | } | ||
| |_^ | ||
|
||
error: aborting due to 5 previous errors | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
// run-rustfix | ||
|
||
#![warn(clippy::len_zero)] | ||
#![allow(dead_code, unused, clippy::len_without_is_empty)] | ||
|
||
pub struct One; | ||
struct Wither; | ||
|
||
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 | ||
} | ||
} | ||
|
||
pub struct HasIsEmpty; | ||
|
||
impl HasIsEmpty { | ||
pub 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 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 | ||
} | ||
} | ||
|
||
fn main() { | ||
let x = [1, 2]; | ||
if x.is_empty() { | ||
println!("This should not happen!"); | ||
} | ||
|
||
if "".is_empty() {} | ||
|
||
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.is_empty() { | ||
println!("Or this!"); | ||
} | ||
if !has_is_empty.is_empty() { | ||
println!("Or this!"); | ||
} | ||
if !has_is_empty.is_empty() { | ||
println!("Or this!"); | ||
} | ||
if has_is_empty.is_empty() { | ||
println!("Or this!"); | ||
} | ||
if !has_is_empty.is_empty() { | ||
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 has_is_empty.is_empty() { | ||
println!("Or this!"); | ||
} | ||
if !has_is_empty.is_empty() { | ||
println!("Or this!"); | ||
} | ||
if !has_is_empty.is_empty() { | ||
println!("Or this!"); | ||
} | ||
if !has_is_empty.is_empty() { | ||
println!("Or this!"); | ||
} | ||
if has_is_empty.is_empty() { | ||
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.is_empty() { | ||
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.is_empty() {} | ||
} |
Oops, something went wrong.