rust-lang / rust-lang/rust

Match guard pattern as macro output is unused

Open
#154,305 17 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug F-guard_patterns needs-triage
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

guard patterns tracking issue: https://github.com/rust-lang/rust/issues/129967

Edit history:

  • corrected (0 -> 7) discriminant in code snippet to match expanded snippets

I tried this code:

#![feature(guard_patterns)]

macro_rules! guard {
    ($disc:literal if $cond:expr) => { $disc if $cond };
}

pub fn test(left: u64, right: u64) {
    match left {
        guard!(7 if 3 == right >> 1 & 0xf) => panic!("Bingo"),
        guard!(7 if 4 == right >> 1 & 0xf) => panic!("Bongo"),
        _ => (),
    }
}

I expected the guard macro to expand like this:

pub fn test(left: u64, right: u64) {
    match left {
        7 if 3 == right >> 1 & 0xf => {
            ::core::panicking::panic_fmt(format_args!("Bingo"));
        }
        7 if 4 == right >> 1 & 0xf => {
            ::core::panicking::panic_fmt(format_args!("Bongo"));
        }
        _ => (),
    }
}

Instead, this happened:

pub fn test(left: u64, right: u64) {
    match left {
        (7 if 3 == right >> 1 & 0xf) => {
            ::core::panicking::panic_fmt(format_args!("Bingo"));
        }
        (7 if 4 == right >> 1 & 0xf) => {
            ::core::panicking::panic_fmt(format_args!("Bongo"));
        }
        _ => (),
    }
}
Which caused the `right` parameter to be marked as unused and second match arm to be marked as unreachable.
cargo build
warning: the feature `guard_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
 --> src/lib.rs:1:12
  |
1 | #![feature(guard_patterns)]
  |            ^^^^^^^^^^^^^^
  |
  = note: see issue #129967 <https://github.com/rust-lang/rust/issues/129967> for more information
  = note: `#[warn(incomplete_features)]` on by default

warning: unreachable pattern
  --> src/lib.rs:10:16
   |
 9 |         guard!(7 if 3 == right >> 1 & 0xf) => panic!("Bingo"),
   |                - matches all the relevant values
10 |         guard!(7 if 4 == right >> 1 & 0xf) => panic!("Bongo"),
   |                ^ no value can reach this
   |
   = note: `#[warn(unreachable_patterns)]` (part of `#[warn(unused)]`) on by default

warning: unused variable: `right`
 --> src/lib.rs:7:24
  |
7 | pub fn test(left: u64, right: u64) {
  |                        ^^^^^ help: if this is intentional, prefix it with an underscore: `_right`
  |
  = note: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default

warning: `macro_test` (lib) generated 3 warnings (run `cargo fix --lib -p macro_test` to apply 1 suggestion)
In latest version of nightly in assembly even the left == 7 check is dropped
.section .text.unlikely.macro_test::test,"ax",@progbits
	.globl	macro_test::test
	.p2align	4
.type	macro_test::test,@function
macro_test::test:
	.cfi_startproc
	push rbp
	.cfi_def_cfa_offset 16
	.cfi_offset rbp, -16
	mov rbp, rsp
	.cfi_def_cfa_register rbp
	lea rdi, [rip + .Lanon.3d08d0a897f173f2df1f3db7ed6d9c12.0]
	lea rdx, [rip + .Lanon.3d08d0a897f173f2df1f3db7ed6d9c12.2]
	mov esi, 11
	call qword ptr [rip + core::panicking::panic_fmt@GOTPCREL]
In version from december 2025 the left check was still present
.section .text.macro_test::test,"ax",@progbits
	.globl	macro_test::test
	.p2align	4
.type	macro_test::test,@function
macro_test::test:
	.cfi_startproc
	cmp rdi, 7
	je .LBB0_2
	ret
.LBB0_2:
	push rbp
	.cfi_def_cfa_offset 16
	.cfi_offset rbp, -16
	mov rbp, rsp
	.cfi_def_cfa_register rbp
	lea rdi, [rip + .Lanon.bfdb341b1ef1d5aa463dafe853c0b238.0]
	lea rdx, [rip + .Lanon.bfdb341b1ef1d5aa463dafe853c0b238.2]
	mov esi, 11
	call qword ptr [rip + core::panicking::panic_fmt@GOTPCREL]
rustc 1.94.0-nightly (24139cf84 2025-12-20)
binary: rustc
commit-hash: 24139cf844095e574708faf406034dc78cb39143
commit-date: 2025-12-20
host: x86_64-unknown-linux-gnu
release: 1.94.0-nightly
LLVM version: 21.1.8
Meta

rustc --version --verbose:

rustc 1.96.0-nightly (f66622c7e 2026-03-23)
binary: rustc
commit-hash: f66622c7eca7fc48ccc4dac848ff911b09a4d566
commit-date: 2026-03-23
host: x86_64-unknown-linux-gnu
release: 1.96.0-nightly
LLVM version: 22.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.

Research direction

Start with the guard_patterns reproducer in src/lib.rs and compare its expected and actual behavior, including the unreachable-pattern and unused-variable warnings. Read the linked guard patterns tracking issue, then verify the generated assembly shown in the report. Done means macro-produced guard patterns retain the discriminant and condition checks without spurious warnings.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.