stringify! and assert!
stringify! is a built-in macro that converts the syntactic form of
an expression into a string — not the value, but the code you wrote. This
is especially useful for debug and error messages that show what was in
the source, not just the numeric result.
The dbg! pattern below combines stringify! with the evaluated value
to produce output like [dbg] count * 2 = 14:
Built-in stringify! and a dbg! macro that shows the source code alongside the value.
// Feature: `stringify!` — converts an expression into a source string
// Syntax: `stringify!(expr)` — built-in macro
// When to use: assert/debug messages that show the original code, not
// just the value. Pairs beautifully with custom macros.
// `stringify!` captures the syntactic form of the expression.
let s = stringify!(1 + 2 * 3)
print(s)
// expected: 1 + 2 * 3
// Works with identifiers, calls, any expression.
let n = stringify!(hello_world)
print(n)
// expected: hello_world
let call = stringify!(foo(1, 2))
print(call)
// expected: foo(1, 2)
// Useful pattern: dbg! shows "expr = value".
macro dbg(x) {
print("[dbg] {stringify!($x)} = {$x}")
}
let count = 7
dbg!(count)
dbg!(count * 2)
dbg!(count > 5)
// expected:
// [dbg] count = 7
// [dbg] count * 2 = 14
// [dbg] count > 5 = true
With stringify! available, it is straightforward to build assertion
macros that display the expression that failed. assert! aborts with the
textual form of the condition; assert_eq! shows the left and right
sides separately:
assert! and assert_eq! with automatic failure messages via stringify!.
// Feature: Practical macros — `assert!` and `expect!`
// Syntax: combines `stringify!` with the expression for rich messages
// When to use: inline tests and validations with syntactic context.
// assert!: aborts if the condition is false, showing the original code.
macro assert(cond) {
if !$cond {
panic("assertion failed: {stringify!($cond)}")
}
}
assert!(1 + 1 == 2)
assert!("zolo".len() == 4)
print("all asserts passed")
// expected: all asserts passed
// assert_eq!: equality with a useful message on failure.
macro assert_eq(actual, expected) {
if $actual != $expected {
panic("assert_eq failed: {stringify!($actual)} != {$expected}, got {$actual}")
}
}
let result = 2 * 21
assert_eq!(result, 42)
print("ok")
// expected: ok
Challenge
Write a macro assert_gt!(a, b) that fails with the message
"expected {stringify!($a)} > {stringify!($b)}, but {$a} <= {$b}" when
a <= b. Test with assert_gt!(5, 3) (passes) and assert_gt!(2, 10)
(should abort).
See also