rust-lang / rust-lang/rust-clippy

match_same_arms reports same arm when strings in macro calls are different

Open
#13,522 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Summary

A match statement with arms that differ by the contents of string data passed into a macro falsely reports the match_same_arms.

Calling the println!() macro appears to works as intended, so there may already be special case testing for it.
Functions calls with differing string data appear to work as intended.
Functions and macro calls with differing numeric literal data appear to work as intended.

Lint Name

match_same_arms

Reproducer

I tried this code:

#![deny(clippy::match_same_arms)]

// Cargo.toml [dependencies] includes:
// defmt = "*"

pub enum Arms {
    This,
    That,
}

pub fn print_arms(a: Arms) {
    // defmt::info!() is a macro similar to println!(), used in embedded systems.
    // Clearly the two arms generate very different results,
    //  but the second gets flagged by match_same_arms 
    match a {
        Arms::This => defmt::info!("This"),
        Arms::That => defmt::info!("That"),
    }
}

I saw this happen:

% cargo clippy
    Checking replicate_match_same_arms_with_different_strings v0.1.0 (.../replicate_match_same_arms_with_different_strings)
error: this match arm has an identical body to another arm
  --> src/lib.rs:11:9
   |
11 |         Arms::That => defmt::info!("That"),
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: try changing either arm body
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_same_arms
note: the lint level is defined here
  --> src/lib.rs:1:9
   |
1  | #![deny(clippy::match_same_arms)]
   |         ^^^^^^^^^^^^^^^^^^^^^^^
help: or try merging the arm patterns
   |
11 |         Arms::That | Arms::This => defmt::info!("That"),
   |         ~~~~~~~~~~~~~~~~~~~~~~~
help: and remove this obsolete arm
   |
10 -         Arms::This => defmt::info!("This"),
   |

error: could not compile `replicate_match_same_arms_with_different_strings` (lib) due to 1 previous error
%

I expected to see this happen:
No error.

Version

rustc 1.81.0 (eeb90cda1 2024-09-04)
binary: rustc
commit-hash: eeb90cda1969383f56a2637cbd3037bdf598841c
commit-date: 2024-09-04
host: aarch64-apple-darwin
release: 1.81.0
LLVM version: 18.1.7

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 at the match_same_arms lint implementation and inspect how macro calls with string arguments are compared, including the existing println!() handling. Add a regression test based on the defmt::info!("This") and defmt::info!("That") reproducer, then run the lint tests or cargo clippy to confirm the distinct arms are no longer reported.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.