2017-05-17 07:19:44 -05:00
|
|
|
#![warn(len_without_is_empty, len_zero)]
|
2016-08-29 16:06:59 -05:00
|
|
|
#![allow(dead_code, unused)]
|
|
|
|
|
|
|
|
pub struct PubOne;
|
|
|
|
|
|
|
|
impl PubOne {
|
2017-02-08 07:58:07 -06:00
|
|
|
pub fn len(self: &Self) -> isize {
|
2016-08-29 16:06:59 -05:00
|
|
|
1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-05 08:01:51 -05:00
|
|
|
impl PubOne {
|
|
|
|
// A second impl for this struct - the error span shouldn't mention this
|
2017-02-19 09:36:17 -06:00
|
|
|
pub fn irrelevant(self: &Self) -> bool {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Identical to PubOne, but with an allow attribute on the impl complaining len
|
|
|
|
pub struct PubAllowed;
|
|
|
|
|
|
|
|
#[allow(len_without_is_empty)]
|
|
|
|
impl PubAllowed {
|
|
|
|
pub fn len(self: &Self) -> isize {
|
|
|
|
1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-19 09:39:40 -06:00
|
|
|
// No allow attribute on this impl block, but that doesn't matter - we only require one on the
|
2017-02-19 09:36:17 -06:00
|
|
|
// impl containing len.
|
|
|
|
impl PubAllowed {
|
|
|
|
pub fn irrelevant(self: &Self) -> bool {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 16:06:59 -05:00
|
|
|
struct NotPubOne;
|
|
|
|
|
|
|
|
impl NotPubOne {
|
2018-05-05 08:01:51 -05:00
|
|
|
pub fn len(self: &Self) -> isize {
|
|
|
|
// no error, len is pub but `NotPubOne` is not exported anyway
|
2016-08-29 16:06:59 -05:00
|
|
|
1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-20 01:52:19 -05:00
|
|
|
struct One;
|
|
|
|
|
|
|
|
impl One {
|
2018-05-05 08:01:51 -05:00
|
|
|
fn len(self: &Self) -> isize {
|
|
|
|
// no error, len is private, see #1085
|
2015-08-11 13:22:20 -05:00
|
|
|
1
|
|
|
|
}
|
2015-05-20 01:52:19 -05:00
|
|
|
}
|
|
|
|
|
2016-08-29 16:06:59 -05:00
|
|
|
pub trait PubTraitsToo {
|
2017-02-08 07:58:07 -06:00
|
|
|
fn len(self: &Self) -> isize;
|
2016-08-29 16:06:59 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl PubTraitsToo for One {
|
|
|
|
fn len(self: &Self) -> isize {
|
|
|
|
0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-20 01:52:19 -05:00
|
|
|
trait TraitsToo {
|
2016-08-29 16:06:59 -05:00
|
|
|
fn len(self: &Self) -> isize; // no error, len is private, see #1085
|
2015-05-20 01:52:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl TraitsToo for One {
|
2015-08-11 13:22:20 -05:00
|
|
|
fn len(self: &Self) -> isize {
|
|
|
|
0
|
|
|
|
}
|
2015-05-20 01:52:19 -05:00
|
|
|
}
|
|
|
|
|
2016-08-29 16:06:59 -05:00
|
|
|
struct HasPrivateIsEmpty;
|
|
|
|
|
|
|
|
impl HasPrivateIsEmpty {
|
|
|
|
pub fn len(self: &Self) -> isize {
|
|
|
|
1
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_empty(self: &Self) -> bool {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct HasIsEmpty;
|
2015-05-20 01:52:19 -05:00
|
|
|
|
|
|
|
impl HasIsEmpty {
|
2017-02-08 07:58:07 -06:00
|
|
|
pub fn len(self: &Self) -> isize {
|
2015-08-11 13:22:20 -05:00
|
|
|
1
|
|
|
|
}
|
2015-06-01 05:49:36 -05:00
|
|
|
|
2015-08-11 13:22:20 -05:00
|
|
|
fn is_empty(self: &Self) -> bool {
|
|
|
|
false
|
|
|
|
}
|
2015-06-01 05:49:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
struct Wither;
|
|
|
|
|
2016-08-29 16:06:59 -05:00
|
|
|
pub trait WithIsEmpty {
|
2015-08-11 13:22:20 -05:00
|
|
|
fn len(self: &Self) -> isize;
|
|
|
|
fn is_empty(self: &Self) -> bool;
|
2015-06-01 05:49:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl WithIsEmpty for Wither {
|
2015-08-11 13:22:20 -05:00
|
|
|
fn len(self: &Self) -> isize {
|
|
|
|
1
|
|
|
|
}
|
2015-06-01 05:49:36 -05:00
|
|
|
|
2015-08-11 13:22:20 -05:00
|
|
|
fn is_empty(self: &Self) -> bool {
|
|
|
|
false
|
|
|
|
}
|
2015-06-01 05:49:36 -05:00
|
|
|
}
|
|
|
|
|
2016-08-29 16:06:59 -05:00
|
|
|
pub struct HasWrongIsEmpty;
|
2015-06-01 05:49:36 -05:00
|
|
|
|
|
|
|
impl HasWrongIsEmpty {
|
2017-02-08 07:58:07 -06:00
|
|
|
pub fn len(self: &Self) -> isize {
|
2015-08-11 13:22:20 -05:00
|
|
|
1
|
|
|
|
}
|
|
|
|
|
2018-05-05 08:01:51 -05:00
|
|
|
pub fn is_empty(self: &Self, x: u32) -> bool {
|
2015-08-11 13:22:20 -05:00
|
|
|
false
|
|
|
|
}
|
2015-05-20 01:52:19 -05:00
|
|
|
}
|
|
|
|
|
2017-08-28 16:13:56 -05:00
|
|
|
pub trait Empty {
|
|
|
|
fn is_empty(&self) -> bool;
|
|
|
|
}
|
|
|
|
|
2018-05-05 08:01:51 -05:00
|
|
|
pub trait InheritingEmpty: Empty {
|
|
|
|
//must not trigger LEN_WITHOUT_IS_EMPTY
|
2017-08-28 16:13:56 -05:00
|
|
|
fn len(&self) -> isize;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2015-08-11 13:22:20 -05:00
|
|
|
let y = One;
|
2018-05-05 08:01:51 -05:00
|
|
|
if y.len() == 0 {
|
|
|
|
//no error because One does not have .is_empty()
|
2015-08-11 13:22:20 -05:00
|
|
|
println!("This should not happen either!");
|
|
|
|
}
|
|
|
|
|
2018-05-05 08:01:51 -05:00
|
|
|
let z: &TraitsToo = &y;
|
|
|
|
if z.len() > 0 {
|
|
|
|
//no error, because 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 {
|
|
|
|
// 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.");
|
|
|
|
}
|
2016-03-01 03:13:54 -06:00
|
|
|
assert!(!has_is_empty.is_empty());
|
2015-08-11 13:22:20 -05:00
|
|
|
|
2016-03-01 03:13:54 -06:00
|
|
|
let with_is_empty: &WithIsEmpty = &Wither;
|
|
|
|
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 {
|
|
|
|
//no error as HasWrongIsEmpty does not have .is_empty()
|
2015-08-11 13:22:20 -05:00
|
|
|
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
|
|
|
}
|
2017-09-04 10:05:47 -05:00
|
|
|
|
|
|
|
// this used to ICE
|
|
|
|
pub trait Foo: Sized {}
|
|
|
|
|
|
|
|
pub trait DependsOnFoo: Foo {
|
|
|
|
fn len(&mut self) -> usize;
|
|
|
|
}
|