assert!
The assert! macro evaluates a boolean expression at runtime and panics if the expression evaluates to false. It is the foundational assertion macro in Rust's standard library for verifying invariants, boolean predicates, and pattern checks via matches!.
assert!(condition)
assert!(condition, "format string {}", arg)
|
+-- condition == true --> Continues execution normally
+-- condition == false --> Panics with file, line, column, and message
Basic Usage and Custom Diagnostic Messages
When called with a single boolean expression (assert!(expr)), a failure prints the stringified source expression (assertion failed: expr). Passing a format string and arguments as subsequent parameters (assert!(expr, "context: {val}")) formats a detailed diagnostic message only when the assertion fails.
fn is_sorted_ascending(slice: &[i32]) -> bool {
slice.windows(2).all(|w| w[0] <= w[1])
}
fn main() {
let data = [2, 4, 8, 16, 32];
// 1. Simple boolean assertion
assert!(!data.is_empty());
// 2. Assertion with lazy formatted diagnostic message
assert!(
is_sorted_ascending(&data),
"expected ascending order, but got {data:?}"
);
// 3. Combining `assert!` with `matches!` when a type does not implement PartialEq
let result: Result<i32, &str> = Ok(42);
assert!(
matches!(result, Ok(n) if n > 0),
"expected positive Ok value, got {result:?}"
);
println!("All assert! checks succeeded");
}
All assert! checks succeeded
Inspecting assert! Failure Output
When an assert! fails inside a test or main, the panic message reports the source file, line number, column number, and custom message:
fn main() {
let temperature = 105;
assert!(
(0..=100).contains(&temperature),
"temperature {temperature}°C is outside liquid water range (0..=100°C)"
);
}
thread 'main' panicked at src/main.rs:3:5:
temperature 105°C is outside liquid water range (0..=100°C)
assert! vs debug_assert!
| Macro | Active in Debug & cargo test? |
Active in Release (-C opt-level)? |
Primary Use Case |
|---|---|---|---|
assert! |
Yes | Yes | Unit tests, security/safety checks, and invariants that must always hold in production. |
debug_assert! |
Yes | No (compiled out unless -C debug-assertions) |
Expensive $O(n)$ internal invariant checks on hot paths. |
Never place an expression with required side effects inside debug_assert!(iter.next().is_some()), because the expression is not evaluated at all in release builds.