Why this fires¶
A let pattern is structurally refutable (it might not match the value — e.g. an enum-variant pattern, or an array-length pattern) but has no else clause to handle the non-matching case. Without else, a non-matching value would silently bind nonsense (or nil) into the pattern's names.
enum Maybe { Some(int), None }
fn f(m: Maybe) {
let Maybe::Some(x) = m
// ^^^^^^^^^^^^^^^^^^ error[TE125]: refutable pattern in `let` requires `else`
// (or use `if let`/`match`)
print(x)
}The same applies to parameter patterns:
enum Maybe { Some(int), None }
fn f(Maybe::Some(x)) { print(x) } // refutable enum pattern in param positionStruct patterns are exempt — a struct's own fields always match, so let Point { x, .. } = p needs no else.
Fix it¶
1. Add else¶
fn f(m: Maybe) {
let Maybe::Some(x) = m else { return } // ok
print(x)
}2. Use if let or match instead¶
fn f(m: Maybe) {
if let Maybe::Some(x) = m {
print(x)
}
}See also¶
TE124—let ... else'selseblock must diverge.- /docs/pattern-matching — refutable vs. irrefutable patterns.