rust-lang / rust-lang/rust-clippy

`#[expect(clippy::pattern_type_mismatch)]` does not work on match arms

Open
#17,494 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Summary

The pattern_type_mismatch lint sometimes conflicts with the needless_borrowed_references lint, but for a single match arm, using #[expect(clippy::pattern_type_mismatch)] does not suppress the lint, and instead results in unfulfilled_lint_expectations also being triggered

Reproducer

Code:

#![warn(clippy::pattern_type_mismatch)]
#![allow(clippy::match_like_matches_macro)]

#[derive(Debug, PartialEq, Eq, Clone)]
enum Expr {
    Boolean(Box<bool>),
    Number(Box<i64>),
    Boxed(Box<Expr>),
    Other(String),
}

impl Expr {
    fn is_scalar(&self) -> bool {
        match self {
            &Expr::Boolean(_) | &Expr::Number(_) => true,
            #[expect(clippy::pattern_type_mismatch, reason = "Conflicts with clippy::needless_borrowed_references")]
            Expr::Boxed(inner) => inner.is_scalar(),
            _ => false,
        }
    }
    fn is_other(&self) -> bool {
        #[expect(clippy::pattern_type_mismatch, reason = "Works on overall match")]
        match self {
            #[expect(unused_variables, reason = "Expect works on match arms")]
            Expr::Other(s) => true,
            _ => false,
        }
    }
}

fn main() {
    assert!(Expr::Boolean(Box::new(true)).is_scalar());
    assert!(Expr::Number(Box::new(5)).is_scalar());
    assert!(Expr::Boxed(Box::new(Expr::Boolean(Box::new(true)))).is_scalar());
    assert!(!Expr::Other(String::new()).is_scalar());
    assert!(Expr::Other(String::new()).is_other());
}

Current output:

    Checking playground v0.0.1 (/playground)
warning: type of pattern does not match the expression type
  --> src/main.rs:17:13
   |
17 |             Expr::Boxed(inner) => inner.is_scalar(),
   |             ^^^^^^^^^^^^^^^^^^
   |
   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
   = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.97.0/index.html#pattern_type_mismatch
note: the lint level is defined here
  --> src/main.rs:1:9
   |
 1 | #![warn(clippy::pattern_type_mismatch)]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: this lint expectation is unfulfilled
  --> src/main.rs:16:22
   |
16 |             #[expect(clippy::pattern_type_mismatch, reason = "Conflicts with clippy::needless_borrowed_references")]
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: Conflicts with clippy::needless_borrowed_references
   = note: `#[warn(unfulfilled_lint_expectations)]` on by default

warning: `playground` (bin "playground") generated 2 warnings
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.66s

Desired output:
No lints triggered

Version
Playground 1.97.1
Clippy 0.1.97 (2026-07-14 8bab26f4f6)
Additional Labels

No response

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.

Research direction

Start by running the reproducer in src/main.rs with the reported Rust and Clippy versions, and compare the arm-level and match-level #[expect] behavior. Trace the pattern_type_mismatch and unfulfilled_lint_expectations handling, then verify that the reproducer produces no lints while the overall-match expectation still works.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.