2019-04-16 14:46:07 -05:00
|
|
|
#![warn(clippy::len_zero)]
|
2024-03-21 16:20:40 -05:00
|
|
|
#![allow(
|
|
|
|
dead_code,
|
|
|
|
unused,
|
|
|
|
clippy::needless_if,
|
|
|
|
clippy::len_without_is_empty,
|
|
|
|
clippy::const_is_empty
|
|
|
|
)]
|
2016-08-29 16:06:59 -05:00
|
|
|
|
2022-12-17 07:12:54 -06:00
|
|
|
extern crate core;
|
|
|
|
use core::ops::Deref;
|
|
|
|
|
2019-04-16 14:46:07 -05:00
|
|
|
pub struct One;
|
|
|
|
struct Wither;
|
2016-08-29 16:06:59 -05:00
|
|
|
|
2015-05-20 01:52:19 -05:00
|
|
|
trait TraitsToo {
|
2020-08-11 08:43:21 -05:00
|
|
|
fn len(&self) -> isize;
|
2019-01-30 19:15:29 -06:00
|
|
|
// No error; `len` is private; see issue #1085.
|
2015-05-20 01:52:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl TraitsToo for One {
|
2020-08-11 08:43:21 -05:00
|
|
|
fn len(&self) -> isize {
|
2015-08-11 13:22:20 -05:00
|
|
|
0
|
|
|
|
}
|
2015-05-20 01:52:19 -05:00
|
|
|
}
|
|
|
|
|
2019-04-16 14:46:07 -05:00
|
|
|
pub struct HasIsEmpty;
|
2016-08-29 16:06:59 -05:00
|
|
|
|
2019-04-16 14:46:07 -05:00
|
|
|
impl HasIsEmpty {
|
2020-08-11 08:43:21 -05:00
|
|
|
pub fn len(&self) -> isize {
|
2016-08-29 16:06:59 -05:00
|
|
|
1
|
|
|
|
}
|
|
|
|
|
2020-08-11 08:43:21 -05:00
|
|
|
fn is_empty(&self) -> bool {
|
2016-08-29 16:06:59 -05:00
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-16 14:46:07 -05:00
|
|
|
pub struct HasWrongIsEmpty;
|
2015-05-20 01:52:19 -05:00
|
|
|
|
2019-04-16 14:46:07 -05:00
|
|
|
impl HasWrongIsEmpty {
|
2020-08-11 08:43:21 -05:00
|
|
|
pub fn len(&self) -> isize {
|
2015-08-11 13:22:20 -05:00
|
|
|
1
|
|
|
|
}
|
2015-06-01 05:49:36 -05:00
|
|
|
|
2020-08-11 08:43:21 -05:00
|
|
|
pub fn is_empty(&self, x: u32) -> bool {
|
2015-08-11 13:22:20 -05:00
|
|
|
false
|
|
|
|
}
|
2015-06-01 05:49:36 -05:00
|
|
|
}
|
|
|
|
|
2016-08-29 16:06:59 -05:00
|
|
|
pub trait WithIsEmpty {
|
2020-08-11 08:43:21 -05:00
|
|
|
fn len(&self) -> isize;
|
|
|
|
fn is_empty(&self) -> bool;
|
2015-06-01 05:49:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl WithIsEmpty for Wither {
|
2020-08-11 08:43:21 -05:00
|
|
|
fn len(&self) -> isize {
|
2015-08-11 13:22:20 -05:00
|
|
|
1
|
|
|
|
}
|
2015-06-01 05:49:36 -05:00
|
|
|
|
2020-08-11 08:43:21 -05:00
|
|
|
fn is_empty(&self) -> bool {
|
2015-08-11 13:22:20 -05:00
|
|
|
false
|
|
|
|
}
|
2015-06-01 05:49:36 -05:00
|
|
|
}
|
|
|
|
|
2022-12-17 07:12:54 -06:00
|
|
|
struct DerefToDerefToString;
|
|
|
|
|
|
|
|
impl Deref for DerefToDerefToString {
|
|
|
|
type Target = DerefToString;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&DerefToString {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct DerefToString;
|
|
|
|
|
|
|
|
impl Deref for DerefToString {
|
|
|
|
type Target = str;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
"Hello, world!"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-20 01:52:19 -05:00
|
|
|
fn main() {
|
2015-08-11 13:22:20 -05:00
|
|
|
let x = [1, 2];
|
2016-02-24 13:52:47 -06:00
|
|
|
if x.len() == 0 {
|
2015-08-11 13:22:20 -05:00
|
|
|
println!("This should not happen!");
|
|
|
|
}
|
|
|
|
|
2018-05-05 08:01:51 -05:00
|
|
|
if "".len() == 0 {}
|
2016-03-12 14:12:35 -06:00
|
|
|
|
2022-12-17 07:12:54 -06:00
|
|
|
let s = "Hello, world!";
|
|
|
|
let s1 = &s;
|
|
|
|
let s2 = &s1;
|
|
|
|
let s3 = &s2;
|
|
|
|
let s4 = &s3;
|
|
|
|
let s5 = &s4;
|
|
|
|
let s6 = &s5;
|
|
|
|
println!("{}", *s1 == "");
|
|
|
|
println!("{}", **s2 == "");
|
|
|
|
println!("{}", ***s3 == "");
|
|
|
|
println!("{}", ****s4 == "");
|
|
|
|
println!("{}", *****s5 == "");
|
|
|
|
println!("{}", ******(s6) == "");
|
|
|
|
|
|
|
|
let d2s = DerefToDerefToString {};
|
|
|
|
println!("{}", &**d2s == "");
|
|
|
|
|
2015-08-11 13:22:20 -05:00
|
|
|
let y = One;
|
2018-05-05 08:01:51 -05:00
|
|
|
if y.len() == 0 {
|
2019-01-30 19:15:29 -06:00
|
|
|
// No error; `One` does not have `.is_empty()`.
|
2015-08-11 13:22:20 -05:00
|
|
|
println!("This should not happen either!");
|
|
|
|
}
|
|
|
|
|
2019-05-30 01:23:47 -05:00
|
|
|
let z: &dyn TraitsToo = &y;
|
2018-05-05 08:01:51 -05:00
|
|
|
if z.len() > 0 {
|
2019-01-30 19:15:29 -06:00
|
|
|
// No error; `TraitsToo` has no `.is_empty()` method.
|
2015-08-11 13:22:20 -05:00
|
|
|
println!("Nor should this!");
|
|
|
|
}
|
|
|
|
|
2016-03-01 03:13:54 -06:00
|
|
|
let has_is_empty = HasIsEmpty;
|
|
|
|
if has_is_empty.len() == 0 {
|
2015-08-11 13:22:20 -05:00
|
|
|
println!("Or this!");
|
|
|
|
}
|
2016-03-01 03:13:54 -06:00
|
|
|
if has_is_empty.len() != 0 {
|
2015-08-12 03:53:14 -05:00
|
|
|
println!("Or this!");
|
|
|
|
}
|
2016-03-01 03:13:54 -06:00
|
|
|
if has_is_empty.len() > 0 {
|
2015-08-12 03:53:14 -05:00
|
|
|
println!("Or this!");
|
|
|
|
}
|
2018-05-05 08:01:51 -05:00
|
|
|
if has_is_empty.len() < 1 {
|
|
|
|
println!("Or this!");
|
|
|
|
}
|
|
|
|
if has_is_empty.len() >= 1 {
|
|
|
|
println!("Or this!");
|
|
|
|
}
|
|
|
|
if has_is_empty.len() > 1 {
|
2019-01-30 19:15:29 -06:00
|
|
|
// No error.
|
2018-05-05 08:01:51 -05:00
|
|
|
println!("This can happen.");
|
|
|
|
}
|
|
|
|
if has_is_empty.len() <= 1 {
|
2019-01-30 19:15:29 -06:00
|
|
|
// No error.
|
2018-05-05 08:01:51 -05:00
|
|
|
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() {
|
2019-01-30 19:15:29 -06:00
|
|
|
// No error.
|
2018-05-05 08:01:51 -05:00
|
|
|
println!("This can happen.");
|
|
|
|
}
|
|
|
|
if 1 >= has_is_empty.len() {
|
2019-01-30 19:15:29 -06:00
|
|
|
// No error.
|
2018-05-05 08:01:51 -05:00
|
|
|
println!("This can happen.");
|
|
|
|
}
|
2016-03-01 03:13:54 -06:00
|
|
|
assert!(!has_is_empty.is_empty());
|
2015-08-11 13:22:20 -05:00
|
|
|
|
2019-05-30 01:23:47 -05:00
|
|
|
let with_is_empty: &dyn WithIsEmpty = &Wither;
|
2016-03-01 03:13:54 -06:00
|
|
|
if with_is_empty.len() == 0 {
|
2015-08-11 13:22:20 -05:00
|
|
|
println!("Or this!");
|
|
|
|
}
|
2016-03-01 03:13:54 -06:00
|
|
|
assert!(!with_is_empty.is_empty());
|
2015-08-11 13:22:20 -05:00
|
|
|
|
2016-03-01 03:13:54 -06:00
|
|
|
let has_wrong_is_empty = HasWrongIsEmpty;
|
2018-05-05 08:01:51 -05:00
|
|
|
if has_wrong_is_empty.len() == 0 {
|
2019-01-30 19:15:29 -06:00
|
|
|
// No error; `HasWrongIsEmpty` does not have `.is_empty()`.
|
2015-08-11 13:22:20 -05:00
|
|
|
println!("Or this!");
|
|
|
|
}
|
2023-04-23 06:03:09 -05:00
|
|
|
|
|
|
|
// issue #10529
|
|
|
|
(has_is_empty.len() > 0).then(|| println!("This can happen."));
|
|
|
|
(has_is_empty.len() == 0).then(|| println!("Or this!"));
|
2015-05-20 01:52:19 -05:00
|
|
|
}
|
2017-02-24 21:26:33 -06:00
|
|
|
|
|
|
|
fn test_slice(b: &[u8]) {
|
2018-05-05 08:01:51 -05:00
|
|
|
if b.len() != 0 {}
|
2017-02-24 21:26:33 -06:00
|
|
|
}
|
2024-04-04 12:52:55 -05:00
|
|
|
|
|
|
|
// issue #11992
|
|
|
|
fn binop_with_macros() {
|
|
|
|
macro_rules! len {
|
|
|
|
($seq:ident) => {
|
|
|
|
$seq.len()
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! compare_to {
|
|
|
|
($val:literal) => {
|
|
|
|
$val
|
|
|
|
};
|
|
|
|
($val:expr) => {{ $val }};
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! zero {
|
|
|
|
() => {
|
|
|
|
0
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
let has_is_empty = HasIsEmpty;
|
|
|
|
// Don't lint, suggesting changes might break macro compatibility.
|
|
|
|
(len!(has_is_empty) > 0).then(|| println!("This can happen."));
|
|
|
|
// Don't lint, suggesting changes might break macro compatibility.
|
|
|
|
if len!(has_is_empty) == 0 {}
|
|
|
|
// Don't lint
|
|
|
|
if has_is_empty.len() == compare_to!(if true { 0 } else { 1 }) {}
|
|
|
|
// This is fine
|
|
|
|
if has_is_empty.len() == compare_to!(1) {}
|
|
|
|
|
|
|
|
if has_is_empty.len() == compare_to!(0) {}
|
|
|
|
if has_is_empty.len() == zero!() {}
|
|
|
|
|
|
|
|
(compare_to!(0) < has_is_empty.len()).then(|| println!("This can happen."));
|
|
|
|
}
|