Skip to content

Commit

Permalink
Auto merge of #3978 - phansch:rustfix_len_zero, r=flip1995
Browse files Browse the repository at this point in the history
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
bors committed Apr 18, 2019
2 parents c6e43b1 + bae7d29 commit 38d26df
Show file tree
Hide file tree
Showing 5 changed files with 367 additions and 163 deletions.
145 changes: 145 additions & 0 deletions tests/ui/len_without_is_empty.rs
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() {}
54 changes: 54 additions & 0 deletions tests/ui/len_without_is_empty.stderr
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

143 changes: 143 additions & 0 deletions tests/ui/len_zero.fixed
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() {}
}
Loading

0 comments on commit 38d26df

Please sign in to comment.