Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A match guard is an additional if condition appended to a match arm pattern that must evaluate to true for that specific arm to execute. It allows for arbitrary boolean expressions to refine pattern matching beyond standard structural destructuring.
match expression {
    pattern if boolean_expression => result_expression,
    _ => fallback_expression,
}

Evaluation Mechanics

When a match statement executes, the compiler evaluates arms sequentially. For an arm containing a match guard:
  1. The compiler first checks if the value structurally matches the pattern.
  2. If the structural match succeeds, any variables defined in the pattern are bound.
  3. The boolean_expression (the guard) is then evaluated using those bound variables.
  4. If the guard evaluates to true, the result_expression executes.
  5. If the guard evaluates to false, the binding is discarded, and the compiler proceeds to evaluate the next match arm.
let target = Some(4);

match target {
    Some(x) if x % 2 == 0 => println!("Matched an even inner value: {}", x),
    Some(x) => println!("Matched an odd inner value: {}", x),
    None => println!("Matched None"),
}

Exhaustiveness Checking

The Rust compiler’s exhaustiveness checker ignores match guards. Because the compiler cannot statically determine if an arbitrary runtime boolean expression will evaluate to true, a pattern equipped with a match guard does not count toward making a match exhaustive. Even if a guard logically covers all possibilities, the compiler requires a fallback arm (an identical pattern without a guard, or a catch-all like _) to guarantee exhaustiveness.
let val = 10;

// This will NOT compile, even though x > 0 and x <= 0 covers all integers.
// The compiler considers the match non-exhaustive.
match val {
    x if x > 0 => println!("Positive"),
    x if x <= 0 => println!("Non-positive"),
}

// This WILL compile. The second arm acts as the exhaustive fallback.
match val {
    x if x > 0 => println!("Positive"),
    x => println!("Non-positive"),
}

Interaction with Compound Patterns

When a match guard is used alongside the pattern OR operator (|), the guard applies to the entire compound pattern, not just the pattern immediately preceding the if keyword. The syntax behaves as (Pattern1 | Pattern2) if condition, rather than Pattern1 | (Pattern2 if condition).
let x = 4;
let y = false;

match x {
    // The guard `if y` applies to 4, 5, AND 6.
    // Because y is false, this entire arm fails, even though x is 4.
    4 | 5 | 6 if y => println!("Matched"),
    _ => println!("Fell through to default"),
}

Variable Shadowing

Variables bound in the pattern of a match guard shadow variables of the same name in the outer scope. The match guard evaluates within the scope of the newly bound variables, not the outer variables.
let x = Some(5);
let y = 10;

match x {
    // 'y' here binds to the inner value of Some, shadowing the outer 'y' (10).
    // The guard evaluates `5 == 5`, which is true.
    Some(y) if y == 5 => println!("Inner value is 5"),
    _ => println!("Default"),
}
Master Rust with Deep Grasping Methodology!Learn More