Skip to content

len_without_is_empty is over-zealous about &mut #16190

@uazu

Description

@uazu

Summary

I have two signatures as follows:

     pub fn len(&mut self) -> std::io::Result<usize> {...}
     pub fn is_empty(&self) -> bool {...}

Clippy complains and says it wants is_empty(&mut self) -> bool. However I would rather that the is_empty call not be restricted in this way, to allow it to be called in more places. There is a good reason len has to be mut, but is_empty doesn't need to be. (I drop the internal File instance as soon as it is empty, so the code never has go to the OS to detect the empty case -- perfect example of is_empty() being more optimal than len()==0).

Lint Name

len_without_is_empty

Reproducer

I tried this code:

use std::fs::File;

const UNIT: usize = 65536;

pub struct Test {
    file: Option<File>,
}

impl Test {
    pub fn len(&mut self) -> std::io::Result<usize> {
        let mut len = UNIT;
        if let Some(ref mut file) = self.file {
            use std::io::Seek;
            len -= file.stream_position()? as usize;
        }
        Ok(len)
    }
    pub fn is_empty(&self) -> bool {
        // `file` is set `None` when last byte is read
        self.file.is_none()
    }
}

I saw this happen:

warning: struct `Test` has a public `len` method, but the `is_empty` method has an unexpected signature
  --> src/main.rs:14:5
   |
14 |     pub fn len(&mut self) -> std::io::Result<usize> {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: `is_empty` defined here
  --> src/main.rs:22:5
   |
22 |     pub fn is_empty(&self) -> bool {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: expected signature: `(&mut self) -> bool` or `(&mut self) -> Result<bool>

I expected to see this happen:

  • This code should pass without a warning

Version

rustc 1.91.1 (ed61e7d7e 2025-11-07)
binary: rustc
commit-hash: ed61e7d7e242494fb7057f2657300d9e77bb4fcb
commit-date: 2025-11-07
host: x86_64-unknown-linux-gnu
release: 1.91.1
LLVM version: 21.1.2

Additional Labels

No response

Metadata

Metadata

Assignees

Labels

C-bugCategory: Clippy is not doing the correct thingI-false-positiveIssue: The lint was triggered on code it shouldn't have

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions