Common Standard Macros

matches!

The matches! macro tests whether an expression matches a given pattern (and optional if guard) and returns a bool (true or false), providing a concise expression form of a two-arm match.

Syntax and Expansion

matches!(expression, pattern $(if guard)?)

Under the hood, matches! expands directly to a match expression:

match expression {
    pattern $(if guard)? => true,
    _ => false,
}

Testing Enum Variants, Ranges, Or-Patterns, and Match Guards

Unlike ==, which requires implementing PartialEq and constructing a specific value to compare against, matches! works on any type (even types that do not implement PartialEq), supports wildcard payloads (MyEnum::Variant(_)), range patterns ('a'..='z'), | or-patterns, and if guards:

#[derive(Debug)]
enum Response {
    Ok(u16),
    Redirect(&'static str),
    ServerError { code: u16, retryable: bool },
}

fn main() {
    let r1 = Response::Ok(204);
    let r2 = Response::ServerError {
        code: 503,
        retryable: true,
    };

    // 1. Pattern with range and or-pattern:
    let is_success = matches!(r1, Response::Ok(200..=299));

    // 2. Struct variant pattern with an `if` guard:
    let should_retry = matches!(
        r2,
        Response::Redirect(_) | Response::ServerError { retryable: true, code } if code >= 500
    );

    // 3. Character classification with range patterns:
    let ch = '7';
    let is_hex = matches!(ch, '0'..='9' | 'a'..='f' | 'A'..='F');

    println!("is_success:   {is_success}");
    println!("should_retry: {should_retry}");
    println!("is_hex('7'):  {is_hex}");
}
is_success:   true
should_retry: true
is_hex('7'):  true

Using matches! Inside Iterator .filter() and Assertions

matches! is especially ergonomic inside iterator predicates (.filter(|x| matches!(x, ...))) and unit test assertions (assert!(matches!(result, Err(MyError::Timeout)))):

fn main() {
    let inputs: [Result<i32, &str>; 4] = [Ok(10), Err("timeout"), Ok(-5), Err("fatal")];

    // Keep only positive `Ok` values using `matches!`:
    let positive_ok_count = inputs
        .iter()
        .filter(|res| matches!(res, Ok(n) if *n > 0))
        .count();

    assert!(matches!(inputs[1], Err("timeout")));
    println!("Positive Ok count: {positive_ok_count}");
}
Positive Ok count: 1