For block-tailed-expressions like match, when they appear in a position that a statement is valid, they are always treated as a statement. This ensures that the parse does not rely on types in the program, which is a very desirable property to keep syntax not interleaved with complicated and turing-complete type resolution.
Also, "lack of ;" would be an arbitrary-length lookahead and ambiguity; we don't rely on that either. The closing brace can be the end of the expression (match doesn't require a semicolon when used as a statement), and *num_apples could be the start of a new expression (dereferencing a pointer).
This is probably a somewhat stupid question, but why does match (or if for that mapneed a statement form at all? Why can't it just be expression whose value is discarded if used with a ;?
Do things like
let foo;
match bar {
Some(_) => foo = 1;
None => foo = 0;
}
// foo is now initialized
not work with expressions? I suppose I've never tried, but I don't immediately see a strong reason they couldn't.
EDIT: sorry I've realized I just answered my own question, it's so that they can used without a ; that they have a statement form, I got tripped up by the context.
That's what I should have written yes, I was wondering whether the initialization analysis would be able to observe that foo had been initialized in every execution path even if it's an expression rather than a statement.