From bae7d29dbe7f59a1ffe4445355d4db0095005aef Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Tue, 16 Apr 2019 21:46:07 +0200 Subject: [PATCH] Add run-rustfix for len_zero lint * Extracts len_without_is_empty into separate file * Adds `// run-rustfix` to `tests/ui/len_zero.rs` --- tests/ui/len_without_is_empty.rs | 145 +++++++++++++++++++++++++++ tests/ui/len_without_is_empty.stderr | 54 ++++++++++ tests/ui/len_zero.fixed | 143 ++++++++++++++++++++++++++ tests/ui/len_zero.rs | 106 ++------------------ tests/ui/len_zero.stderr | 82 +++------------ 5 files changed, 367 insertions(+), 163 deletions(-) create mode 100644 tests/ui/len_without_is_empty.rs create mode 100644 tests/ui/len_without_is_empty.stderr create mode 100644 tests/ui/len_zero.fixed diff --git a/tests/ui/len_without_is_empty.rs b/tests/ui/len_without_is_empty.rs new file mode 100644 index 00000000000..3ef29dd6388 --- /dev/null +++ b/tests/ui/len_without_is_empty.rs @@ -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() {} diff --git a/tests/ui/len_without_is_empty.stderr b/tests/ui/len_without_is_empty.stderr new file mode 100644 index 00000000000..4493b17a4b4 --- /dev/null +++ b/tests/ui/len_without_is_empty.stderr @@ -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 + diff --git a/tests/ui/len_zero.fixed b/tests/ui/len_zero.fixed new file mode 100644 index 00000000000..56109a0fa5f --- /dev/null +++ b/tests/ui/len_zero.fixed @@ -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() {} +} diff --git a/tests/ui/len_zero.rs b/tests/ui/len_zero.rs index db97c2427f3..0a77f119462 100644 --- a/tests/ui/len_zero.rs +++ b/tests/ui/len_zero.rs @@ -1,66 +1,10 @@ -#![warn(clippy::len_without_is_empty, clippy::len_zero)] -#![allow(dead_code, unused)] +// run-rustfix -pub struct PubOne; +#![warn(clippy::len_zero)] +#![allow(dead_code, unused, clippy::len_without_is_empty)] -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 - } -} +pub struct One; +struct Wither; trait TraitsToo { fn len(self: &Self) -> isize; @@ -73,9 +17,9 @@ fn len(self: &Self) -> isize { } } -struct HasPrivateIsEmpty; +pub struct HasIsEmpty; -impl HasPrivateIsEmpty { +impl HasIsEmpty { pub fn len(self: &Self) -> isize { 1 } @@ -85,20 +29,18 @@ fn is_empty(self: &Self) -> bool { } } -pub struct HasIsEmpty; +pub struct HasWrongIsEmpty; -impl HasIsEmpty { +impl HasWrongIsEmpty { pub fn len(self: &Self) -> isize { 1 } - fn is_empty(self: &Self) -> bool { + pub fn is_empty(self: &Self, x: u32) -> bool { false } } -struct Wither; - pub trait WithIsEmpty { fn len(self: &Self) -> isize; fn is_empty(self: &Self) -> bool; @@ -114,27 +56,6 @@ fn is_empty(self: &Self) -> bool { } } -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 { @@ -220,10 +141,3 @@ fn main() { 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; -} diff --git a/tests/ui/len_zero.stderr b/tests/ui/len_zero.stderr index f2ad0bb9e1e..9a472b31e21 100644 --- a/tests/ui/len_zero.stderr +++ b/tests/ui/len_zero.stderr @@ -1,49 +1,5 @@ -error: item `PubOne` has a public `len` method but no corresponding `is_empty` method - --> $DIR/len_zero.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_zero.rs:55: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_zero.rs:90: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_zero.rs:119:1 - | -LL | / impl HasWrongIsEmpty { -LL | | pub fn len(self: &Self) -> isize { -LL | | 1 -LL | | } -... | -LL | | } -LL | | } - | |_^ - error: length comparison to zero - --> $DIR/len_zero.rs:140:8 + --> $DIR/len_zero.rs:61:8 | LL | if x.len() == 0 { | ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `x.is_empty()` @@ -51,90 +7,82 @@ LL | if x.len() == 0 { = note: `-D clippy::len-zero` implied by `-D warnings` error: length comparison to zero - --> $DIR/len_zero.rs:144:8 + --> $DIR/len_zero.rs:65:8 | LL | if "".len() == 0 {} | ^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `"".is_empty()` error: length comparison to zero - --> $DIR/len_zero.rs:159:8 + --> $DIR/len_zero.rs:80:8 | LL | if has_is_empty.len() == 0 { | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()` error: length comparison to zero - --> $DIR/len_zero.rs:162:8 + --> $DIR/len_zero.rs:83:8 | LL | if has_is_empty.len() != 0 { | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` error: length comparison to zero - --> $DIR/len_zero.rs:165:8 + --> $DIR/len_zero.rs:86:8 | LL | if has_is_empty.len() > 0 { | ^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` error: length comparison to one - --> $DIR/len_zero.rs:168:8 + --> $DIR/len_zero.rs:89:8 | LL | if has_is_empty.len() < 1 { | ^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()` error: length comparison to one - --> $DIR/len_zero.rs:171:8 + --> $DIR/len_zero.rs:92:8 | LL | if has_is_empty.len() >= 1 { | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` error: length comparison to zero - --> $DIR/len_zero.rs:182:8 + --> $DIR/len_zero.rs:103:8 | LL | if 0 == has_is_empty.len() { | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()` error: length comparison to zero - --> $DIR/len_zero.rs:185:8 + --> $DIR/len_zero.rs:106:8 | LL | if 0 != has_is_empty.len() { | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` error: length comparison to zero - --> $DIR/len_zero.rs:188:8 + --> $DIR/len_zero.rs:109:8 | LL | if 0 < has_is_empty.len() { | ^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` error: length comparison to one - --> $DIR/len_zero.rs:191:8 + --> $DIR/len_zero.rs:112:8 | LL | if 1 <= has_is_empty.len() { | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` error: length comparison to one - --> $DIR/len_zero.rs:194:8 + --> $DIR/len_zero.rs:115:8 | LL | if 1 > has_is_empty.len() { | ^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()` error: length comparison to zero - --> $DIR/len_zero.rs:208:8 + --> $DIR/len_zero.rs:129:8 | LL | if with_is_empty.len() == 0 { | ^^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `with_is_empty.is_empty()` error: length comparison to zero - --> $DIR/len_zero.rs:221:8 + --> $DIR/len_zero.rs:142:8 | LL | if b.len() != 0 {} | ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `!b.is_empty()` -error: trait `DependsOnFoo` has a `len` method but no (possibly inherited) `is_empty` method - --> $DIR/len_zero.rs:227:1 - | -LL | / pub trait DependsOnFoo: Foo { -LL | | fn len(&mut self) -> usize; -LL | | } - | |_^ - -error: aborting due to 19 previous errors +error: aborting due to 14 previous errors -- 2.44.0