rust-lang / rust-lang/rust-clippy

`assert_is_empty` could catch non-`PartialEq` cases in Rust >= 1.96.0

Open
#17,659 1 comment 0 reactions 1 assignee View on GitHub

@durationextender is already working on this.

Since Aug 31, 2026.

C-bug I-false-negative
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

Summary

Currently, assert_is_empty requires that the type stored in array-like collections (arrays, Vecs, and slices) implement both Debug and PartialEq. However, since Rust 1.96.0, we've had access to assert_matches!, which provides nearly identical benefits without requiring PartialEq.

When checking if something is empty you can instead do:

assert_matches!(collection[..], []);

If it is not empty, this fails with:

assertion `left matches right` failed
  left: [HasDebug]
 right: []

Where [HasDebug] can be replaced by the Debug representation of the collection (which would depend on the type and how many are inside).

It is also possible to check if a collection is not empty using assert_matches!, but if this fails, you learn exactly as much as you would from assert!(!collection.is_empty()) failing: the collection actually is empty. But this is also true for the existing implementation using assert_ne!, so... here it is anyway?

When checking if something is not empty you can instead do:

assert_matches!(collection[..], [_, ..]);

If it is empty, this fails with:

assertion `left matches right` failed
  left: []
 right: [_, ..]
Lint Name

assert_is_empty

Reproducer

I tried this code:

#[cfg(test)]
mod test {

    #[derive(Debug)]
    struct HasDebug;

    #[test]
    fn empty_vec_is_empty() {
        let empty: Vec<HasDebug> = Vec::new();
        assert!(empty.is_empty());
    }

    #[test]
    fn vec_with_one_is_not_empty() {
        let one: Vec<HasDebug> = vec![HasDebug];
        assert!(!one.is_empty());
    }

    #[test]
    fn vec_with_multiple_is_not_empty() {
        let multiple: Vec<HasDebug> = vec![HasDebug, HasDebug];
        assert!(!multiple.is_empty());
    }

    #[test]
    #[should_panic]
    fn empty_vec_is_not_empty() {
        let empty: Vec<HasDebug> = Vec::new();
        assert!(!empty.is_empty());
    }

    #[test]
    #[should_panic]
    fn vec_with_one_is_empty() {
        let one: Vec<HasDebug> = vec![HasDebug];
        assert!(one.is_empty());
    }

    #[test]
    #[should_panic]
    fn vec_with_multiple_is_empty() {
        let multiple: Vec<HasDebug> = vec![HasDebug, HasDebug];
        assert!(multiple.is_empty());
    }
}

I expected to see this happen:

Clippy marks either all the assert!s OR at least those asserting that the Vec IS empty, and offers these automatic fixes:

#[cfg(test)]
mod test {
    use core::assert_matches;

    #[derive(Debug)]
    struct HasDebug;

    #[test]
    fn empty_vec_is_empty() {
        let empty: Vec<HasDebug> = Vec::new();
        assert_matches!(empty[..], []);
    }

    #[test]
    fn vec_with_one_is_not_empty() {
        let one: Vec<HasDebug> = vec![HasDebug];
        assert_matches!(one[..], [_, ..]);
    }

    #[test]
    fn vec_with_multiple_is_not_empty() {
        let multiple: Vec<HasDebug> = vec![HasDebug, HasDebug];
        assert_matches!(multiple[..], [_, ..]);
    }

    #[test]
    #[should_panic]
    fn empty_vec_is_not_empty() {
        let empty: Vec<HasDebug> = Vec::new();
        assert_matches!(empty[..], [_, ..]);
    }

    #[test]
    #[should_panic]
    fn vec_with_one_is_empty() {
        let one: Vec<HasDebug> = vec![HasDebug];
        assert_matches!(one[..], []);
    }

    #[test]
    #[should_panic]
    fn vec_with_multiple_is_empty() {
        let multiple: Vec<HasDebug> = vec![HasDebug, HasDebug];
        assert_matches!(multiple[..], []);
    }
}

Instead, this happened:

Clippy ignores all of these. The lint only fires if I also implement PartialEq.

Version
rustc 1.100.0-nightly (fb6531d55 2026-08-23)
binary: rustc
commit-hash: fb6531d550e0075b9eb9a51464f404805eec87d9
commit-date: 2026-08-23
host: x86_64-unknown-linux-gnu
release: 1.100.0-nightly
LLVM version: 23.1.0

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.