Skip to content

Match guard pattern as macro output is unused #154305

@krzysiek4321

Description

@krzysiek4321

guard patterns tracking issue: #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

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.F-guard_patterns`#![feature(guard_patterns)]`needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions