Skip to content

Commit

Permalink
Fix the syntax of the last expression of a block.
Browse files Browse the repository at this point in the history
  • Loading branch information
tczajka committed Oct 10, 2023
1 parent 142b2ed commit 9fc99ce
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 19 deletions.
16 changes: 5 additions & 11 deletions src/expressions/block-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,8 @@
> _BlockExpression_ :\
>    `{`\
> &nbsp;&nbsp; &nbsp;&nbsp; [_InnerAttribute_]<sup>\*</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; _Statements_<sup>?</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; ([_Statement_]<sup>\*</sup> ([_StatementNotExpression_] | [_Expression_]))<sup>?</sup>\
> &nbsp;&nbsp; `}`
>
> _Statements_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; [_Statement_]<sup>\+</sup>\
> &nbsp;&nbsp; | [_Statement_]<sup>\+</sup> [_ExpressionWithoutBlock_]\
> &nbsp;&nbsp; | [_ExpressionWithoutBlock_]
A *block expression*, or *block*, is a control flow expression and anonymous namespace scope for items and variable declarations.
As a control flow expression, a block sequentially executes its component non-item declaration statements and then its final optional expression.
Expand All @@ -20,10 +15,8 @@ The syntax for a block is `{`, then any [inner attributes], then any number of [

Statements are usually required to be followed by a semicolon, with two exceptions:

1. Item declaration statements do not need to be followed by a semicolon.
2. Expression statements usually require a following semicolon except if its outer expression is a flow control expression.

Furthermore, extra semicolons between statements are allowed, but these semicolons do not affect semantics.
1. Item declaration statements.
2. Expression statements that end with a `}` and are not at the end of the block.

When evaluating a block expression, each statement, except for item declaration statements, is executed sequentially.
Then the final operand is executed, if given.
Expand Down Expand Up @@ -167,9 +160,10 @@ fn is_unix_platform() -> bool {
}
```

[_ExpressionWithoutBlock_]: ../expressions.md
[_Expression_]: ../expressions.md
[_InnerAttribute_]: ../attributes.md
[_Statement_]: ../statements.md
[_StatementNotExpression_]: ../statements.md
[`await` expressions]: await-expr.md
[`cfg`]: ../conditional-compilation.md
[`for`]: loop-expr.md#iterator-loops
Expand Down
15 changes: 7 additions & 8 deletions src/statements.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@

> **<sup>Syntax</sup>**\
> _Statement_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; _StatementNotExpression_\
> &nbsp;&nbsp; | [_ExpressionWithBlock_]
>
> _StatementNotExpression_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; `;`\
> &nbsp;&nbsp; | [_Item_]\
> &nbsp;&nbsp; | [_LetStatement_]\
> &nbsp;&nbsp; | [_ExpressionStatement_]\
> &nbsp;&nbsp; | [_Expression_] `;`\
> &nbsp;&nbsp; | [_MacroInvocationSemi_]

Expand Down Expand Up @@ -75,18 +79,13 @@ let [u, v] = [v[0], v[1]] else { // This pattern is irrefutable, so the compiler

## Expression statements

> **<sup>Syntax</sup>**\
> _ExpressionStatement_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; [_ExpressionWithoutBlock_][expression] `;`\
> &nbsp;&nbsp; | [_ExpressionWithBlock_][expression] `;`<sup>?</sup>
An *expression statement* is one that evaluates an [expression] and ignores its result.
As a rule, an expression statement's purpose is to trigger the effects of evaluating its expression.

An expression that consists of only a [block expression][block] or control flow expression, if used in a context where a statement is permitted, can omit the trailing semicolon.
This can cause an ambiguity between it being parsed as a standalone statement and as a part of another expression;
in this case, it is parsed as a statement.
The type of [_ExpressionWithBlock_][expression] expressions when used as statements must be the unit type.
The type of [_ExpressionWithBlock_] expressions when used as statements must be the unit type.

```rust
# let mut v = vec![1, 2, 3];
Expand Down Expand Up @@ -135,8 +134,8 @@ The attributes that have meaning on a statement are [`cfg`], and [the lint check
[the lint check attributes]: attributes/diagnostics.md#lint-check-attributes
[pattern]: patterns.md
[_BlockExpression_]: expressions/block-expr.md
[_ExpressionStatement_]: #expression-statements
[_Expression_]: expressions.md
[_ExpressionWithBlock_]: expressions.md
[_Item_]: items.md
[_LazyBooleanExpression_]: expressions/operator-expr.md#lazy-boolean-operators
[_LetStatement_]: #let-statements
Expand Down

0 comments on commit 9fc99ce

Please sign in to comment.