Skip to content

Commit

Permalink
Merge pull request rust-lang#427 from ehuss/grammar-statements
Browse files Browse the repository at this point in the history
Grammar: Statements.
  • Loading branch information
matthewjasper committed Oct 20, 2018
2 parents b9fb838 + 3512dc8 commit 457b072
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 61 deletions.
6 changes: 5 additions & 1 deletion src/attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,16 @@ Attributes may be applied to many things in the language:

* All [item declarations] accept outer attributes while [external blocks],
[functions], [implementations], and [modules] accept inner attributes.
* [Statements] accept outer attributes.
* Most [statements] accept outer attributes (see [Expression Attributes] for
limitations on expression statements).
* [Block expressions] accept outer and inner attributes, but only when they are
the outer expression of an [expression statement] or the final expression of
another block expression.
* [Enum] variants and [struct] and [union] fields accept outer attributes.
* [Match expression arms][match expressions] accept outer attributes.
* [Generic lifetime or type parameter][generics] accept outer attributes.
* Expressions accept outer attributes in limited situations, see [Expression
Attributes] for details.

Some examples of attributes:

Expand Down Expand Up @@ -600,3 +603,4 @@ You can implement `derive` for your own traits through [procedural macros].
[`Termination`]: ../std/process/trait.Termination.html
[where clause]: items/where-clauses.html
[trait or lifetime bounds]: trait-bounds.html
[Expression Attributes]: expressions.html#expression-attributes
94 changes: 71 additions & 23 deletions src/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,42 @@

> **<sup>Syntax</sup>**\
> _Expression_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; [_LiteralExpression_]\
> &nbsp;&nbsp; | [_PathExpression_]\
> &nbsp;&nbsp; | [_BlockExpression_]\
> &nbsp;&nbsp; | [_OperatorExpression_]\
> &nbsp;&nbsp; | [_GroupedExpression_]\
> &nbsp;&nbsp; | [_ArrayExpression_]\
> &nbsp;&nbsp; | [_IndexExpression_]\
> &nbsp;&nbsp; | [_TupleExpression_]\
> &nbsp;&nbsp; | [_TupleIndexingExpression_]\
> &nbsp;&nbsp; | [_StructExpression_]\
> &nbsp;&nbsp; | [_EnumerationVariantExpression_]\
> &nbsp;&nbsp; | [_CallExpression_]\
> &nbsp;&nbsp; | [_MethodCallExpression_]\
> &nbsp;&nbsp; | [_FieldExpression_]\
> &nbsp;&nbsp; | [_ClosureExpression_]\
> &nbsp;&nbsp; | [_LoopExpression_]\
> &nbsp;&nbsp; | [_ContinueExpression_]\
> &nbsp;&nbsp; | [_BreakExpression_]\
> &nbsp;&nbsp; | [_RangeExpression_]\
> &nbsp;&nbsp; | [_IfExpression_]\
> &nbsp;&nbsp; | [_IfLetExpression_]\
> &nbsp;&nbsp; | [_MatchExpression_]\
> &nbsp;&nbsp; | [_ReturnExpression_]
> &nbsp;&nbsp; &nbsp;&nbsp; _ExpressionWithoutBlock_\
> &nbsp;&nbsp; | _ExpressionWithBlock_
>
> _ExpressionWithoutBlock_ :\
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>[](#expression-attributes)\
> &nbsp;&nbsp; (\
> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [_LiteralExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_PathExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_OperatorExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_GroupedExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_ArrayExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_IndexExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_TupleExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_TupleIndexingExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_StructExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_EnumerationVariantExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_CallExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_MethodCallExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_FieldExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_ClosureExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_ContinueExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_BreakExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_RangeExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_ReturnExpression_]\
> &nbsp;&nbsp; )
>
> _ExpressionWithBlock_ :\
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup>[](#expression-attributes)\
> &nbsp;&nbsp; (\
> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [_BlockExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_UnsafeBlockExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_LoopExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_IfExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_IfLetExpression_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | [_MatchExpression_]\
> &nbsp;&nbsp; )
An expression may have two roles: it always produces a *value*, and it may have
*effects* (otherwise known as "side effects"). An expression *evaluates to* a
Expand Down Expand Up @@ -235,6 +248,31 @@ Many of the following operators and expressions can also be overloaded for
other types using traits in `std::ops` or `std::cmp`. These traits also
exist in `core::ops` and `core::cmp` with the same names.

## Expression Attributes

[Outer attributes][_OuterAttribute_] before an expression are allowed only in
a few specific cases:

* Before an expression used as a [statement].
* Elements of [array expressions], [tuple expressions], [call expressions],
tuple-style [struct] and [enum variant] expressions.
<!--
These were likely stabilized inadvertently.
See https://github.com/rust-lang/rust/issues/32796 and
https://github.com/rust-lang/rust/issues/15701
-->
* The tail expression of [block expressions].
<!-- Keep list in sync with block-expr.md -->

They are never allowed before:

* [`if`][_IfExpression_] and [`if let`][_IfLetExpression_] expressions.
* [Range][_RangeExpression_] expressions.
* Binary operator expressions ([_ArithmeticOrLogicalExpression_],
[_ComparisonExpression_], [_LazyBooleanExpression_], [_TypeCastExpression_],
[_AssignmentExpression_], [_CompoundAssignmentExpression_]).


[block expressions]: expressions/block-expr.html
[call expressions]: expressions/call-expr.html
[closure expressions]: expressions/closure-expr.html
Expand Down Expand Up @@ -278,30 +316,40 @@ exist in `core::ops` and `core::cmp` with the same names.
[Mutable `static` items]: items/static-items.html#mutable-statics
[const contexts]: const_eval.html
[slice]: types.html#array-and-slice-types
[statement]: statements.html
[static variables]: items/static-items.html
[Temporary values]: #temporary-lifetimes
[Variables]: variables.html


[_ArithmeticOrLogicalExpression_]: expressions/operator-expr.html#arithmetic-and-logical-binary-operators
[_ArrayExpression_]: expressions/array-expr.html
[_AssignmentExpression_]: expressions/operator-expr.html#assignment-expressions
[_BlockExpression_]: expressions/block-expr.html
[_BreakExpression_]: expressions/loop-expr.html#break-expressions
[_CallExpression_]: expressions/call-expr.html
[_ClosureExpression_]: expressions/closure-expr.html
[_ComparisonExpression_]: expressions/operator-expr.html#comparison-operators
[_CompoundAssignmentExpression_]: expressions/operator-expr.html#compound-assignment-expressions
[_ContinueExpression_]: expressions/loop-expr.html#continue-expressions
[_EnumerationVariantExpression_]: expressions/enum-variant-expr.html
[_FieldExpression_]: expressions/field-expr.html
[_GroupedExpression_]: expressions/grouped-expr.html
[_IfExpression_]: expressions/if-expr.html#if-expressions
[_IfLetExpression_]: expressions/if-expr.html#if-let-expressions
[_IndexExpression_]: expressions/array-expr.html#array-and-slice-indexing-expressions
[_LazyBooleanExpression_]: expressions/operator-expr.html#lazy-boolean-operators
[_LiteralExpression_]: expressions/literal-expr.html
[_LoopExpression_]: expressions/loop-expr.html
[_MatchExpression_]: expressions/match-expr.html
[_MethodCallExpression_]: expressions/method-call-expr.html
[_OperatorExpression_]: expressions/operator-expr.html
[_OuterAttribute_]: attributes.html
[_PathExpression_]: expressions/path-expr.html
[_RangeExpression_]: expressions/range-expr.html
[_ReturnExpression_]: expressions/return-expr.html
[_StructExpression_]: expressions/struct-expr.html
[_TupleExpression_]: expressions/tuple-expr.html
[_TupleIndexingExpression_]: expressions/tuple-expr.html#tuple-indexing-expressions
[_TypeCastExpression_]: expressions/operator-expr.html#type-cast-expressions
[_UnsafeBlockExpression_]: expressions/block-expr.html#unsafe-blocks
23 changes: 17 additions & 6 deletions src/expressions/array-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

> **<sup>Syntax</sup>**\
> _ArrayExpression_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; `[` `]`\
> &nbsp;&nbsp; | `[` [_Expression_] ( `,` [_Expression_] )<sup>\*</sup> `,`<sup>?</sup> `]`\
> &nbsp;&nbsp; | `[` [_Expression_] `;` [_Expression_] `]`
> &nbsp;&nbsp; `[` [_InnerAttribute_]<sup>\*</sup> _ArrayElements_<sup>?</sup> `]`
>
> _ArrayElements_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; [_Expression_] ( `,` [_Expression_] )<sup>\*</sup> `,`<sup>?</sup>\
> &nbsp;&nbsp; | [_Expression_] `;` [_Expression_]
An _[array](types.html#array-and-slice-types) expression_ can be written by
enclosing zero or more comma-separated expressions of uniform type in square
Expand All @@ -30,6 +32,12 @@ greater than 1 then this requires that the type of `a` is
[[1, 0, 0], [0, 1, 0], [0, 0, 1]]; // 2D array
```

### Array expression attributes

[Inner attributes] are allowed directly after the opening bracket of an array
expression in the same expression contexts as [attributes on block
expressions].

## Array and slice indexing expressions

> **<sup>Syntax</sup>**\
Expand Down Expand Up @@ -73,8 +81,11 @@ arr[10]; // warning: index out of bounds
The array index expression can be implemented for types other than arrays and slices
by implementing the [Index] and [IndexMut] traits.

[_Expression_]: expressions.html
[memory location]: expressions.html#place-expressions-and-value-expressions
[Index]: ../std/ops/trait.Index.html
[IndexMut]: ../std/ops/trait.IndexMut.html
[Index]: ../std/ops/trait.Index.html
[Inner attributes]: attributes.html
[_Expression_]: expressions.html
[_InnerAttribute_]: attributes.html
[attributes on block expressions]: expressions/block-expr.html#attributes-on-block-expressions
[constant expression]: const_eval.html#constant-expressions
[memory location]: expressions.html#place-expressions-and-value-expressions
63 changes: 38 additions & 25 deletions src/expressions/block-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,15 @@
> _BlockExpression_ :\
> &nbsp;&nbsp; `{`\
> &nbsp;&nbsp; &nbsp;&nbsp; [_InnerAttribute_]<sup>\*</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; _Statements_<sup>\*</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; [_Expression_]<sup>?</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; _Statements_<sup>?</sup>\
> &nbsp;&nbsp; `}`
>
> _Statements_ :\
> &nbsp;&nbsp; ( `;`\
> &nbsp;&nbsp; | [_ItemDeclaration_]\
> &nbsp;&nbsp; | [_LetStatement_] ;\
> &nbsp;&nbsp; | [_NonControlFlowExpressionStatement_][expression statement] ;\
> &nbsp;&nbsp; | [_FlowControlExpressionStatement_][expression statement] ;<sup>?</sup>\
> &nbsp;&nbsp; )<sup>\*</sup>
A *block expression*, or *block*, is a control flow expression and anonymouse
> &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. As an anonymous namespace
Expand Down Expand Up @@ -60,7 +56,7 @@ assert_eq!(5, five);
> expression of an expression statement, the expected type is `()` unless it
> is followed immediately by a semicolon.
Blocks are always [value expressions] and evaluate the last expression in
Blocks are always [value expressions] and evaluate the last expression in
value expression context. This can be used to force moving a value if really
needed. For example, the following example fails on the call to `consume_self`
because the struct was moved out of `s` in the block expression.
Expand Down Expand Up @@ -109,11 +105,19 @@ let a = unsafe { an_unsafe_fn() };

## Attributes on block expressions

Block expressions allow [outer attributes] and [inner attributes] directly after
the opening brace when the block expression is the outer expression of an
[expression statement] or the final expression of another block expression. The
attributes that have meaning on a block expression are [`cfg`] and [the lint
check attributes].
[Inner attributes] are allowed directly after the opening brace of a block
expression in the following situations:

* [Function] and [method] bodies.
* Loop bodies ([`loop`], [`while`], [`while let`], and [`for`]).
* Block expressions used as a [statement].
* Block expressions as elements of [array expressions], [tuple expressions],
[call expressions], tuple-style [struct] and [enum variant] expressions.
* A block expression as the tail expression of another block expression.
<!-- Keep list in sync with expressions.md -->

The attributes that have meaning on a block expression are [`cfg`] and [the
lint check attributes].

For example, this function returns `true` on unix platforms and `false` on other
platforms.
Expand All @@ -125,17 +129,26 @@ fn is_unix_platform() -> bool {
}
```

[_ExpressionWithoutBlock_]: expressions.html
[_InnerAttribute_]: attributes.html
[_ItemDeclaration_]: items.html
[_LetStatement_]: statements.html#let-statements
[expression statement]: statements.html#expression-statements
[_Expression_]: expressions.html
[_Statement_]: statements.html
[`cfg`]: conditional-compilation.html
[`for`]: expressions/loop-expr.html#iterator-loops
[`loop`]: expressions/loop-expr.html#infinite-loops
[`while let`]: expressions/loop-expr.html#predicate-pattern-loops
[`while`]: expressions/loop-expr.html#predicate-loops
[array expressions]: expressions/array-expr.html
[call expressions]: expressions/call-expr.html
[enum variant]: expressions/enum-variant-expr.html
[expression attributes]: expressions.html#expression-attributes
[expression]: expressions.html
[statements]: statements.html
[value expressions]: expressions.html#place-expressions-and-value-expressions
[outer attributes]: attributes.html
[function]: items/functions.html
[inner attributes]: attributes.html
[expression statement]: statements.html#expression-statements
[`cfg`]: conditional-compilation.html
[method]: items/associated-items.html#methods
[statement]: statements.html
[statements]: statements.html
[struct]: expressions/struct-expr.html
[the lint check attributes]: attributes.html#lint-check-attributes
[tuple expressions]: expressions/tuple-expr.html
[unsafe operations]: unsafety.html
[value expressions]: expressions.html#place-expressions-and-value-expressions
11 changes: 10 additions & 1 deletion src/expressions/grouped-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> **<sup>Syntax</sup>**\
> _GroupedExpression_ :\
> &nbsp;&nbsp; `(` [_Expression_] `)`
> &nbsp;&nbsp; `(` [_InnerAttribute_]<sup>\*</sup> [_Expression_] `)`
An expression enclosed in parentheses evaluates to the result of the enclosed
expression. Parentheses can be used to explicitly specify evaluation order
Expand Down Expand Up @@ -35,4 +35,13 @@ assert_eq!( a.f (), "The method f");
assert_eq!((a.f)(), "The field f");
```

## Group expression attributes

[Inner attributes] are allowed directly after the opening parenthesis of a
group expression in the same expression contexts as [attributes on block
expressions].

[Inner attributes]: attributes.html
[_Expression_]: expressions.html
[_InnerAttribute_]: attributes.html
[attributes on block expressions]: expressions/block-expr.html#attributes-on-block-expressions
6 changes: 6 additions & 0 deletions src/expressions/match-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ let message = match maybe_digit {
Outer attributes are allowed on match arms. The only attributes that have
meaning on match arms are [`cfg`], `cold`, and the [lint check attributes].
[Inner attributes] are allowed directly after the opening brace of the match
expression in the same expression contexts as [attributes on block
expressions].
[_Expression_]: expressions.html
[_BlockExpression_]: expressions/block-expr.html#block-expressions
[place expression]: expressions.html#place-expressions-and-value-expressions
Expand All @@ -133,8 +137,10 @@ meaning on match arms are [`cfg`], `cold`, and the [lint check attributes].
[_Pattern_]: patterns.html
[pattern]: patterns.html
[Identifier Patterns]: patterns.html#identifier-patterns
[Inner attributes]: attributes.html
[Struct Patterns]: patterns.html#struct-patterns
[Tuple Struct Patterns]: patterns.html#tuplestruct-patterns
[Tuple Patterns]: patterns.html#tuple-patterns
[Range Pattern]: patterns.html#range-patterns
[attributes on block expressions]: expressions/block-expr.html#attributes-on-block-expressions
[binding mode]: patterns.html#binding-modes
14 changes: 12 additions & 2 deletions src/expressions/struct-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
> &nbsp;&nbsp; | _StructExprUnit_
>
> _StructExprStruct_ :\
> &nbsp;&nbsp; [_PathInExpression_] `{` (_StructExprFields_ | _StructBase_)<sup>?</sup> `}`
> &nbsp;&nbsp; [_PathInExpression_] `{` [_InnerAttribute_]<sup>\*</sup> (_StructExprFields_ | _StructBase_)<sup>?</sup> `}`
>
> _StructExprFields_ :\
> &nbsp;&nbsp; _StructExprField_ (`,` _StructExprField_)<sup>\*</sup> (`,` _StructBase_ | `,`<sup>?</sup>)
Expand All @@ -16,10 +16,12 @@
> &nbsp;&nbsp; &nbsp;&nbsp; [IDENTIFIER]\
> &nbsp;&nbsp; | ([IDENTIFIER] | [TUPLE_INDEX]) `:` [_Expression_]
>
> _StructBase_ : `..` [_Expression_]
> _StructBase_ :\
> &nbsp;&nbsp; `..` [_Expression_]
>
> _StructExprTuple_ :\
> &nbsp;&nbsp; [_PathInExpression_] `(`\
> &nbsp;&nbsp; &nbsp;&nbsp; [_InnerAttribute_]<sup>\*</sup>\
> &nbsp;&nbsp; &nbsp;&nbsp; ( [_Expression_] (`,` [_Expression_])<sup>\*</sup> `,`<sup>?</sup> )<sup>?</sup>\
> &nbsp;&nbsp; `)`
>
Expand Down Expand Up @@ -126,11 +128,19 @@ let a = Gamma; // Gamma unit value.
let b = Gamma{}; // Exact same value as `a`.
```

## Struct expression attributes

[Inner attributes] are allowed directly after the opening brace or parenthesis
of a struct expression in the same expression contexts as [attributes on block
expressions].

[IDENTIFIER]: identifiers.html
[Inner attributes]: attributes.html
[TUPLE_INDEX]: tokens.html#integer-literals
[_Expression_]: expressions.html
[_InnerAttribute_]: attributes.html
[_PathInExpression_]: paths.html#paths-in-expressions
[attributes on block expressions]: expressions/block-expr.html#attributes-on-block-expressions
[call expression]: expressions/call-expr.html
[if let]: expressions/if-expr.html#if-let-expressions
[if]: expressions/if-expr.html#if-expressions
Expand Down
Loading

0 comments on commit 457b072

Please sign in to comment.