Expression Statements
An expression followed by a semicolon becomes an expression statement.
expr_stmt = expression ";" ;
The expression is evaluated and its value is discarded; the expression statement itself has type (). This is the core calculus's discarding sequence e1 ; e2 (docs/formal/01-core-calculus.md §5.3, §6.7, rule (D-Seq)): e1 is reduced to a value, that value is dropped, and control passes to the following statement e2 — whose value is the value of the enclosing block.
fn side_effect() { }
fn main() -> i32 {
side_effect(); // expression statement
42
}
Expression statements are useful for calling functions for their side effects while discarding their return values.
Block-like expression statements
A block-like expression is an if, match, while, loop, or block ({ ... }) expression: one whose syntax is terminated by a closing brace. When a block-like expression appears in statement position (as an item of a block, rather than as an operand within a larger expression), it forms a complete statement on its own and does not require a trailing semicolon.
A block-like expression in statement position is complete on its own and does not continue into a surrounding infix binary expression. When such an expression is immediately followed by an infix binary operator (for example +, *, ==, &&), it is a syntax error at the operator, rather than the block-like expression becoming the left operand of that operator. To use a block-like expression as the operand of a binary operator, wrap it in parentheses, which places it in operand position: (if c { a } else { b }) + x. The one exception is the - operator, described next.
fn main() -> i32 {
if true { 10 } else { 20 } + 5 // error: `+` cannot continue a
// statement-position block-like expression
(if true { 10 } else { 20 }) + 5 // ok: parentheses opt into operand use
}
The - operator is the sole exception to the syntax-error rule above, because it is the only operator that is both a unary (prefix) and a binary (infix) operator, so its meaning at this boundary is otherwise ambiguous. When a block-like expression in statement position is immediately followed by a -, the - begins a new statement — a unary negation — rather than continuing the block-like expression as the left operand of a subtraction. For example, in a block containing if c { a } else { b } immediately followed by -x, the if expression is one statement and -x is a separate statement whose - is unary negation, not the subtraction (if c { a } else { b }) - x. Both the syntax-error rule and this - exception apply only in statement position: a block-like expression used as an operand (for example, on the right-hand side of a let binding, as in let n = if c { a } else { b } - x;) participates in the surrounding expression as usual.
fn main() -> i32 {
if true { 999 } else { 888 } // a complete statement; value discarded
-1 // a separate statement: unary negation
}