Why this fires¶
A let PATTERN = expr else { ... } block ran to completion without returning, panicking, breaking, or continuing. If the else block can fall through, execution would continue into the pattern's bindings using a value that did NOT match the pattern — so Zolo requires every path through else to diverge.
struct Point { x: int, y: int }
fn f(p) {
let Point { x, .. } = p else { print("nope") }
// ^^^^^^^^^^^^^^^^^^ error[TE124]: `else` block of
// `let ... else` must diverge (return, panic, break, or continue)
print(x)
}A guard that contains a let clause has the same requirement, even when
the pattern is irrefutable or discards its value. Later comma filters may fail.
fn positive(candidate: int?) -> int {
guard let value = candidate, value > 0 else { print("invalid") } // TE124
return value
}Use else { return 0 } here so the continuation can safely use value.
The failure block resolves names in the original outer scope.
Fix it¶
Make every path through the else block diverge:
fn f(p) -> int {
let Point { x, .. } = p else { return 0 } // ok
return x
}fn f(p) {
let Point { x, .. } = p else { panic("not a point") } // ok
print(x)
}See also¶
TE125— a refutableletpattern with noelseat all.- /docs/pattern-matching —
let ... else.