From 9fc99ce42a3eb2e417951f53cd6dcf51a58c8c28 Mon Sep 17 00:00:00 2001 From: Tomek Czajka Date: Tue, 10 Oct 2023 10:30:48 +0200 Subject: [PATCH] Fix the syntax of the last expression of a block. --- src/expressions/block-expr.md | 16 +++++----------- src/statements.md | 15 +++++++-------- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/expressions/block-expr.md b/src/expressions/block-expr.md index bd9c0a623..673d7eb04 100644 --- a/src/expressions/block-expr.md +++ b/src/expressions/block-expr.md @@ -4,13 +4,8 @@ > _BlockExpression_ :\ >    `{`\ >       [_InnerAttribute_]\*\ ->       _Statements_?\ +>       ([_Statement_]\* ([_StatementNotExpression_] | [_Expression_]))?\ >    `}` -> -> _Statements_ :\ ->       [_Statement_]\+\ ->    | [_Statement_]\+ [_ExpressionWithoutBlock_]\ ->    | [_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. @@ -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. @@ -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 diff --git a/src/statements.md b/src/statements.md index c2ae585a0..835fda6d2 100644 --- a/src/statements.md +++ b/src/statements.md @@ -2,10 +2,14 @@ > **Syntax**\ > _Statement_ :\ +>       _StatementNotExpression_\ +>    | [_ExpressionWithBlock_] +> +> _StatementNotExpression_ :\ >       `;`\ >    | [_Item_]\ >    | [_LetStatement_]\ ->    | [_ExpressionStatement_]\ +>    | [_Expression_] `;`\ >    | [_MacroInvocationSemi_] @@ -75,18 +79,13 @@ let [u, v] = [v[0], v[1]] else { // This pattern is irrefutable, so the compiler ## Expression statements -> **Syntax**\ -> _ExpressionStatement_ :\ ->       [_ExpressionWithoutBlock_][expression] `;`\ ->    | [_ExpressionWithBlock_][expression] `;`? - 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]; @@ -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