2019-04-16 14:46:07 -05:00
|
|
|
#![warn(clippy::len_without_is_empty)]
|
|
|
|
#![allow(dead_code, unused)]
|
|
|
|
|
|
|
|
pub struct PubOne;
|
|
|
|
|
|
|
|
impl PubOne {
|
2020-08-04 20:37:29 -05:00
|
|
|
pub fn len(&self) -> isize {
|
2019-04-16 14:46:07 -05:00
|
|
|
1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PubOne {
|
|
|
|
// A second impl for this struct -- the error span shouldn't mention this.
|
2020-08-04 20:37:29 -05:00
|
|
|
pub fn irrelevant(&self) -> bool {
|
2019-04-16 14:46:07 -05:00
|
|
|
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 {
|
2020-08-04 20:37:29 -05:00
|
|
|
pub fn len(&self) -> isize {
|
2019-04-16 14:46:07 -05:00
|
|
|
1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// No `allow` attribute on this impl block, but that doesn't matter -- we only require one on the
|
|
|
|
// impl containing `len`.
|
|
|
|
impl PubAllowed {
|
2020-08-04 20:37:29 -05:00
|
|
|
pub fn irrelevant(&self) -> bool {
|
2019-04-16 14:46:07 -05:00
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-05 12:01:13 -06:00
|
|
|
pub struct PubAllowedFn;
|
|
|
|
|
|
|
|
impl PubAllowedFn {
|
|
|
|
#[allow(clippy::len_without_is_empty)]
|
|
|
|
pub fn len(&self) -> isize {
|
|
|
|
1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(clippy::len_without_is_empty)]
|
|
|
|
pub struct PubAllowedStruct;
|
|
|
|
|
|
|
|
impl PubAllowedStruct {
|
|
|
|
pub fn len(&self) -> isize {
|
|
|
|
1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-16 14:46:07 -05:00
|
|
|
pub trait PubTraitsToo {
|
2020-08-04 20:37:29 -05:00
|
|
|
fn len(&self) -> isize;
|
2019-04-16 14:46:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl PubTraitsToo for One {
|
2020-08-04 20:37:29 -05:00
|
|
|
fn len(&self) -> isize {
|
2019-04-16 14:46:07 -05:00
|
|
|
0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct HasIsEmpty;
|
|
|
|
|
|
|
|
impl HasIsEmpty {
|
2020-08-04 20:37:29 -05:00
|
|
|
pub fn len(&self) -> isize {
|
2019-04-16 14:46:07 -05:00
|
|
|
1
|
|
|
|
}
|
|
|
|
|
2020-08-04 20:37:29 -05:00
|
|
|
fn is_empty(&self) -> bool {
|
2019-04-16 14:46:07 -05:00
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct HasWrongIsEmpty;
|
|
|
|
|
|
|
|
impl HasWrongIsEmpty {
|
2020-08-04 20:37:29 -05:00
|
|
|
pub fn len(&self) -> isize {
|
2019-04-16 14:46:07 -05:00
|
|
|
1
|
|
|
|
}
|
|
|
|
|
2020-08-04 20:37:29 -05:00
|
|
|
pub fn is_empty(&self, x: u32) -> bool {
|
2019-04-16 14:46:07 -05:00
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-05 12:01:13 -06:00
|
|
|
pub struct MismatchedSelf;
|
|
|
|
|
|
|
|
impl MismatchedSelf {
|
|
|
|
pub fn len(self) -> isize {
|
|
|
|
1
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-16 14:46:07 -05:00
|
|
|
struct NotPubOne;
|
|
|
|
|
|
|
|
impl NotPubOne {
|
2020-08-04 20:37:29 -05:00
|
|
|
pub fn len(&self) -> isize {
|
2019-04-16 14:46:07 -05:00
|
|
|
// No error; `len` is pub but `NotPubOne` is not exported anyway.
|
|
|
|
1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct One;
|
|
|
|
|
|
|
|
impl One {
|
2020-08-04 20:37:29 -05:00
|
|
|
fn len(&self) -> isize {
|
2019-04-16 14:46:07 -05:00
|
|
|
// No error; `len` is private; see issue #1085.
|
|
|
|
1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
trait TraitsToo {
|
2020-08-04 20:37:29 -05:00
|
|
|
fn len(&self) -> isize;
|
2019-04-16 14:46:07 -05:00
|
|
|
// No error; `len` is private; see issue #1085.
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TraitsToo for One {
|
2020-08-04 20:37:29 -05:00
|
|
|
fn len(&self) -> isize {
|
2019-04-16 14:46:07 -05:00
|
|
|
0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct HasPrivateIsEmpty;
|
|
|
|
|
|
|
|
impl HasPrivateIsEmpty {
|
2020-08-04 20:37:29 -05:00
|
|
|
pub fn len(&self) -> isize {
|
2019-04-16 14:46:07 -05:00
|
|
|
1
|
|
|
|
}
|
|
|
|
|
2020-08-04 20:37:29 -05:00
|
|
|
fn is_empty(&self) -> bool {
|
2019-04-16 14:46:07 -05:00
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Wither;
|
|
|
|
|
|
|
|
pub trait WithIsEmpty {
|
2020-08-04 20:37:29 -05:00
|
|
|
fn len(&self) -> isize;
|
|
|
|
fn is_empty(&self) -> bool;
|
2019-04-16 14:46:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl WithIsEmpty for Wither {
|
2020-08-04 20:37:29 -05:00
|
|
|
fn len(&self) -> isize {
|
2019-04-16 14:46:07 -05:00
|
|
|
1
|
|
|
|
}
|
|
|
|
|
2020-08-04 20:37:29 -05:00
|
|
|
fn is_empty(&self) -> bool {
|
2019-04-16 14:46:07 -05:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-03-26 15:27:19 -05:00
|
|
|
// issue #1562
|
2021-03-05 12:01:13 -06:00
|
|
|
pub struct MultipleImpls;
|
|
|
|
|
|
|
|
impl MultipleImpls {
|
|
|
|
pub fn len(&self) -> usize {
|
|
|
|
1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MultipleImpls {
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-26 15:27:19 -05:00
|
|
|
// issue #6958
|
|
|
|
pub struct OptionalLen;
|
|
|
|
|
|
|
|
impl OptionalLen {
|
|
|
|
pub fn len(&self) -> Option<usize> {
|
|
|
|
Some(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_empty(&self) -> Option<bool> {
|
|
|
|
Some(true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct OptionalLen2;
|
|
|
|
impl OptionalLen2 {
|
|
|
|
pub fn len(&self) -> Option<usize> {
|
|
|
|
Some(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct OptionalLen3;
|
|
|
|
impl OptionalLen3 {
|
|
|
|
pub fn len(&self) -> usize {
|
|
|
|
0
|
|
|
|
}
|
|
|
|
|
|
|
|
// should lint, len is not an option
|
|
|
|
pub fn is_empty(&self) -> Option<bool> {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct ResultLen;
|
|
|
|
impl ResultLen {
|
|
|
|
pub fn len(&self) -> Result<usize, ()> {
|
|
|
|
Ok(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Differing result types
|
|
|
|
pub fn is_empty(&self) -> Option<bool> {
|
|
|
|
Some(true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct ResultLen2;
|
|
|
|
impl ResultLen2 {
|
|
|
|
pub fn len(&self) -> Result<usize, ()> {
|
|
|
|
Ok(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_empty(&self) -> Result<bool, ()> {
|
|
|
|
Ok(true)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct ResultLen3;
|
|
|
|
impl ResultLen3 {
|
|
|
|
pub fn len(&self) -> Result<usize, ()> {
|
|
|
|
Ok(0)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Non-fallible result is ok.
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct OddLenSig;
|
|
|
|
impl OddLenSig {
|
|
|
|
// don't lint
|
|
|
|
pub fn len(&self) -> bool {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// issue #6958
|
|
|
|
pub struct AsyncLen;
|
|
|
|
impl AsyncLen {
|
|
|
|
async fn async_task(&self) -> bool {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn len(&self) -> usize {
|
2022-09-14 01:27:56 -05:00
|
|
|
usize::from(!self.async_task().await)
|
2021-03-26 15:27:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn is_empty(&self) -> bool {
|
|
|
|
self.len().await == 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-29 12:48:06 -06:00
|
|
|
// issue #9520
|
|
|
|
pub struct NonStandardLenAndIsEmptySignature;
|
|
|
|
impl NonStandardLenAndIsEmptySignature {
|
|
|
|
// don't lint
|
|
|
|
pub fn len(&self, something: usize) -> usize {
|
|
|
|
something
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_empty(&self, something: usize) -> bool {
|
|
|
|
something == 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// test case for #9520 with generics in the function signature
|
|
|
|
pub trait TestResource {
|
|
|
|
type NonStandardSignatureWithGenerics: Copy;
|
|
|
|
fn lookup_content(&self, item: Self::NonStandardSignatureWithGenerics) -> Result<Option<&[u8]>, String>;
|
|
|
|
}
|
|
|
|
pub struct NonStandardSignatureWithGenerics(u32);
|
|
|
|
impl NonStandardSignatureWithGenerics {
|
|
|
|
pub fn is_empty<T, U>(self, resource: &T) -> bool
|
|
|
|
where
|
|
|
|
T: TestResource<NonStandardSignatureWithGenerics = U>,
|
|
|
|
U: Copy + From<NonStandardSignatureWithGenerics>,
|
|
|
|
{
|
|
|
|
if let Ok(Some(content)) = resource.lookup_content(self.into()) {
|
|
|
|
content.is_empty()
|
|
|
|
} else {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// test case for #9520 with generics in the function signature
|
|
|
|
pub fn len<T, U>(self, resource: &T) -> usize
|
|
|
|
where
|
|
|
|
T: TestResource<NonStandardSignatureWithGenerics = U>,
|
|
|
|
U: Copy + From<NonStandardSignatureWithGenerics>,
|
|
|
|
{
|
|
|
|
if let Ok(Some(content)) = resource.lookup_content(self.into()) {
|
|
|
|
content.len()
|
|
|
|
} else {
|
|
|
|
0_usize
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-16 14:46:07 -05:00
|
|
|
fn main() {}
|