Skip to content

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

Description

@hashcatHitman

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

Metadata

Metadata

Labels

C-bugCategory: Clippy is not doing the correct thingI-false-negativeIssue: The lint should have been triggered on code, but wasn't

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions