From cadf497c73fd8a745d2cbbcdd5539003f48f3c1b Mon Sep 17 00:00:00 2001 From: "Ryan Scheel (isHavvy)" Date: Wed, 28 Sep 2022 16:51:48 -0700 Subject: [PATCH 1/3] One line one sentence for main Expressions chapter. --- src/expressions.md | 137 +++++++++++++++++---------------------------- 1 file changed, 52 insertions(+), 85 deletions(-) diff --git a/src/expressions.md b/src/expressions.md index 0c01238c3..b2411cd8e 100644 --- a/src/expressions.md +++ b/src/expressions.md @@ -42,28 +42,24 @@ >       | [_MatchExpression_]\ >    ) -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 -value, and has effects during *evaluation*. Many expressions contain -sub-expressions, called the *operands* of the expression. The meaning of each -kind of expression dictates several things: +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 value, and has effects during *evaluation*. +Many expressions contain sub-expressions, called the *operands* of the expression. +The meaning of each kind of expression dictates several things: * Whether or not to evaluate the operands when evaluating the expression * The order in which to evaluate the operands * How to combine the operands' values to obtain the value of the expression In this way, the structure of expressions dictates the structure of execution. -Blocks are just another kind of expression, so blocks, statements, expressions, -and blocks again can recursively nest inside each other to an arbitrary depth. +Blocks are just another kind of expression, so blocks, statements, expressions, and blocks again can recursively nest inside each other to an arbitrary depth. -> **Note**: We give names to the operands of expressions so that we may discuss -> them, but these names are not stable and may be changed. +> **Note**: We give names to the operands of expressions so that we may discuss them, but these names are not stable and may be changed. ## Expression precedence -The precedence of Rust operators and expressions is ordered as follows, going -from strong to weak. Binary Operators at the same precedence level are grouped -in the order given by their associativity. +The precedence of Rust operators and expressions is ordered as follows, going from strong to weak. +Binary Operators at the same precedence level are grouped in the order given by their associativity. | Operator/Expression | Associativity | |-----------------------------|---------------------| @@ -89,9 +85,8 @@ in the order given by their associativity. ## Evaluation order of operands -The following list of expressions all evaluate their operands the same way, as -described after the list. Other expressions either don't take operands or -evaluate them conditionally as described on their respective pages. +The following list of expressions all evaluate their operands the same way, as described after the list. +Other expressions either don't take operands or evaluate them conditionally as described on their respective pages. * Dereference expression * Error propagation expression @@ -113,15 +108,13 @@ evaluate them conditionally as described on their respective pages. * Range expression * Return expression -The operands of these expressions are evaluated prior to applying the effects of -the expression. Expressions taking multiple operands are evaluated left to right -as written in the source code. +The operands of these expressions are evaluated prior to applying the effects of the expression. +Expressions taking multiple operands are evaluated left to right as written in the source code. > **Note**: Which subexpressions are the operands of an expression is > determined by expression precedence as per the previous section. -For example, the two `next` method calls will always be called in the same -order: +For example, the two `next` method calls will always be called in the same order: ```rust # // Using vec instead of array to avoid references @@ -134,23 +127,18 @@ assert_eq!( ); ``` -> **Note**: Since this is applied recursively, these expressions are also -> evaluated from innermost to outermost, ignoring siblings until there are no -> inner subexpressions. +> **Note**: Since this is applied recursively, these expressions are also evaluated from innermost to outermost, ignoring siblings until there are no inner subexpressions. ## Place Expressions and Value Expressions -Expressions are divided into two main categories: place expressions and value -expressions; there is also a third, minor category of expressions called -assignee expressions. Within each expression, operands may likewise occur in -either place context or value context. The evaluation of an expression depends -both on its own category and the context it occurs within. +Expressions are divided into two main categories: place expressions and value expressions; +there is also a third, minor category of expressions called assignee expressions. +Within each expression, operands may likewise occur in either place context or value context. +The evaluation of an expression depends both on its own category and the context it occurs within. -A *place expression* is an expression that represents a memory location. These -expressions are [paths] which refer to local variables, [static variables], -[dereferences][deref] (`*expr`), [array indexing] expressions (`expr[expr]`), -[field] references (`expr.f`) and parenthesized place expressions. All other -expressions are value expressions. +A *place expression* is an expression that represents a memory location. +These expressions are [paths] which refer to local variables, [static variables], [dereferences][deref] (`*expr`), [array indexing] expressions (`expr[expr]`), [field] references (`expr.f`) and parenthesized place expressions. +All other expressions are value expressions. A *value expression* is an expression that represents an actual value. @@ -166,11 +154,10 @@ The following contexts are *place expression* contexts: expression. * The base of a [functional update] struct expression. -> Note: Historically, place expressions were called *lvalues* and value -> expressions were called *rvalues*. +> Note: Historically, place expressions were called *lvalues* and value expressions were called *rvalues*. -An *assignee expression* is an expression that appears in the left operand of an -[assignment][assign] expression. Explicitly, the assignee expressions are: +An *assignee expression* is an expression that appears in the left operand of an [assignment][assign] expression. +Explicitly, the assignee expressions are: - Place expressions. - [Underscores][_UnderscoreExpression_]. @@ -185,59 +172,49 @@ Arbitrary parenthesisation is permitted inside assignee expressions. ### Moved and copied types -When a place expression is evaluated in a value expression context, or is bound -by value in a pattern, it denotes the value held _in_ that memory location. If -the type of that value implements [`Copy`], then the value will be copied. In -the remaining situations, if that type is [`Sized`], then it may be possible to -move the value. Only the following place expressions may be moved out of: +When a place expression is evaluated in a value expression context, or is bound by value in a pattern, it denotes the value held _in_ that memory location. +If the type of that value implements [`Copy`], then the value will be copied. +In the remaining situations, if that type is [`Sized`], then it may be possible to move the value. +Only the following place expressions may be moved out of: * [Variables] which are not currently borrowed. * [Temporary values](#temporaries). -* [Fields][field] of a place expression which can be moved out of and - don't implement [`Drop`]. -* The result of [dereferencing][deref] an expression with type [`Box`] and - that can also be moved out of. +* [Fields][field] of a place expression which can be moved out of and don't implement [`Drop`]. +* The result of [dereferencing][deref] an expression with type [`Box`] and that can also be moved out of. -After moving out of a place expression that evaluates to a local variable, the -location is deinitialized and cannot be read from again until it is -reinitialized. In all other cases, trying to use a place expression in a value -expression context is an error. +After moving out of a place expression that evaluates to a local variable, the location is deinitialized and cannot be read from again until it is reinitialized. +In all other cases, trying to use a place expression in a value expression context is an error. ### Mutability -For a place expression to be [assigned][assign] to, mutably [borrowed][borrow], -[implicitly mutably borrowed], or bound to a pattern containing `ref mut`, it -must be _mutable_. We call these *mutable place expressions*. In contrast, -other place expressions are called *immutable place expressions*. +For a place expression to be [assigned][assign] to, mutably [borrowed][borrow], [implicitly mutably borrowed], or bound to a pattern containing `ref mut`, it must be _mutable_. +We call these *mutable place expressions*. +In contrast, other place expressions are called *immutable place expressions*. The following expressions can be mutable place expression contexts: * Mutable [variables] which are not currently borrowed. * [Mutable `static` items]. * [Temporary values]. -* [Fields][field]: this evaluates the subexpression in a mutable place - expression context. +* [Fields][field]: this evaluates the subexpression in a mutable place expression context. * [Dereferences][deref] of a `*mut T` pointer. -* Dereference of a variable, or field of a variable, with type `&mut T`. Note: - This is an exception to the requirement of the next rule. -* Dereferences of a type that implements `DerefMut`: this then requires that - the value being dereferenced is evaluated in a mutable place expression context. -* [Array indexing] of a type that implements `IndexMut`: this - then evaluates the value being indexed, but not the index, in mutable place - expression context. +* Dereference of a variable, or field of a variable, with type `&mut T`. + Note: This is an exception to the requirement of the next rule. +* Dereferences of a type that implements `DerefMut`: + this then requires that the value being dereferenced is evaluated in a mutable place expression context. +* [Array indexing] of a type that implements `IndexMut`: + this then evaluates the value being indexed, but not the index, in mutable place expression context. ### Temporaries -When using a value expression in most place expression contexts, a temporary -unnamed memory location is created and initialized to that value. The expression -evaluates to that location instead, except if [promoted] to a `static`. The -[drop scope] of the temporary is usually the end of the enclosing statement. +When using a value expression in most place expression contexts, a temporary unnamed memory location is created and initialized to that value. +The expression evaluates to that location instead, except if [promoted] to a `static`. +The [drop scope] of the temporary is usually the end of the enclosing statement. ### Implicit Borrows -Certain expressions will treat an expression as a place expression by implicitly -borrowing it. For example, it is possible to compare two unsized [slices][slice] for -equality directly, because the `==` operator implicitly borrows its operands: +Certain expressions will treat an expression as a place expression by implicitly borrowing it. +For example, it is possible to compare two unsized [slices][slice] for equality directly, because the `==` operator implicitly borrows its operands: ```rust # let c = [1, 2, 3]; @@ -264,31 +241,21 @@ Implicit borrows may be taken in the following expressions: ## Overloading Traits -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. +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: +[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], - and tuple-style [struct] expressions. - +* Elements of [array expressions], [tuple expressions], [call expressions], and tuple-style [struct] expressions. * The tail expression of [block expressions]. They are never allowed before: * [Range][_RangeExpression_] expressions. -* Binary operator expressions ([_ArithmeticOrLogicalExpression_], - [_ComparisonExpression_], [_LazyBooleanExpression_], [_TypeCastExpression_], - [_AssignmentExpression_], [_CompoundAssignmentExpression_]). +* Binary operator expressions ([_ArithmeticOrLogicalExpression_], [_ComparisonExpression_], [_LazyBooleanExpression_], [_TypeCastExpression_], [_AssignmentExpression_], [_CompoundAssignmentExpression_]). [block expressions]: expressions/block-expr.md From e076c6ed0caa11c33842dc0d22961947c8bf236a Mon Sep 17 00:00:00 2001 From: "Ryan Scheel (isHavvy)" Date: Wed, 28 Sep 2022 17:20:41 -0700 Subject: [PATCH 2/3] One line one sentence for the Statements chapter. --- src/expressions.md | 9 +++++++ src/statements.md | 62 +++++++++++++++++----------------------------- 2 files changed, 32 insertions(+), 39 deletions(-) diff --git a/src/expressions.md b/src/expressions.md index b2411cd8e..0b446af2b 100644 --- a/src/expressions.md +++ b/src/expressions.md @@ -129,6 +129,15 @@ assert_eq!( > **Note**: Since this is applied recursively, these expressions are also evaluated from innermost to outermost, ignoring siblings until there are no inner subexpressions. +## Early Termination + +Expressions may be *terminated* early, whether by a jump expression or unwinding. +When terminated, evaluation of the expression stops. +If the expression is the target of termination by a jump expression, then it evaluates to the value specified by the jump expression. +Otherwise, it evaluates to the never type. + +**Note**: Destructors are still executed for the expression after being terminated. + ## Place Expressions and Value Expressions Expressions are divided into two main categories: place expressions and value expressions; diff --git a/src/statements.md b/src/statements.md index 7acb0dc25..c2ae585a0 100644 --- a/src/statements.md +++ b/src/statements.md @@ -9,35 +9,27 @@ >    | [_MacroInvocationSemi_] -A *statement* is a component of a [block], which is in turn a component of an -outer [expression] or [function]. +A *statement* is a component of a [block], which is in turn a component of an outer [expression] or [function]. -Rust has two kinds of statement: [declaration -statements](#declaration-statements) and [expression -statements](#expression-statements). +Rust has two kinds of statement: [declaration statements](#declaration-statements) and [expression statements](#expression-statements). ## Declaration statements -A *declaration statement* is one that introduces one or more *names* into the -enclosing statement block. The declared names may denote new variables or new -[items][item]. +A *declaration statement* is one that introduces one or more *names* into the enclosing statement block. +The declared names may denote new variables or new [items][item]. -The two kinds of declaration statements are item declarations and `let` -statements. +The two kinds of declaration statements are item declarations and `let` statements. ### Item declarations -An *item declaration statement* has a syntactic form identical to an -[item declaration][item] within a [module]. Declaring an item within a statement -block restricts its scope to the block containing the statement. The item is not -given a [canonical path] nor are any sub-items it may declare. The exception to -this is that associated items defined by [implementations] are still accessible -in outer scopes as long as the item and, if applicable, trait are accessible. +An *item declaration statement* has a syntactic form identical to an [item declaration][item] within a [module]. +Declaring an item within a statement block restricts its scope to the block containing the statement. +The item is not given a [canonical path] nor are any sub-items it may declare. +The exception to this is that associated items defined by [implementations] are still accessible in outer scopes as long as the item and, if applicable, trait are accessible. It is otherwise identical in meaning to declaring the item inside a module. -There is no implicit capture of the containing function's generic parameters, -parameters, and local variables. For example, `inner` may not access -`outer_var`. +There is no implicit capture of the containing function's generic parameters, parameters, and local variables. +For example, `inner` may not access `outer_var`. ```rust fn outer() { @@ -61,18 +53,13 @@ fn outer() { > _Expression_ must not be a [_LazyBooleanExpression_], or end with a `}`. A *`let` statement* introduces a new set of [variables], given by a [pattern]. -The pattern is followed optionally by a type annotation and then either ends, -or is followed by an initializer expression plus an optional `else` block. -When no type annotation is given, the compiler will infer the type, or signal -an error if insufficient type information is available for definite -inference. Any variables introduced by a variable declaration are visible -from the point of declaration until the end of the enclosing block scope, -except when they are shadowed by another variable declaration. +The pattern is followed optionally by a type annotation and then either ends, or is followed by an initializer expression plus an optional `else` block. +When no type annotation is given, the compiler will infer the type, or signal an error if insufficient type information is available for definite inference. +Any variables introduced by a variable declaration are visible from the point of declaration until the end of the enclosing block scope, except when they are shadowed by another variable declaration. If an `else` block is not present, the pattern must be irrefutable. If an `else` block is present, the pattern may be refutable. -If the pattern does not match (this requires it to be refutable), the `else` -block is executed. +If the pattern does not match (this requires it to be refutable), the `else` block is executed. The `else` block must always diverge (evaluate to the [never type]). ```rust @@ -93,16 +80,13 @@ let [u, v] = [v[0], v[1]] else { // This pattern is irrefutable, so the compiler >       [_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 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. +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. ```rust # let mut v = vec![1, 2, 3]; @@ -134,8 +118,8 @@ if true { ## Attributes on Statements -Statements accept [outer attributes]. The attributes that have meaning on a -statement are [`cfg`], and [the lint check attributes]. +Statements accept [outer attributes]. +The attributes that have meaning on a statement are [`cfg`], and [the lint check attributes]. [block]: expressions/block-expr.md [expression]: expressions.md From 45c47cd38654388910a8a92f5435570355ea2762 Mon Sep 17 00:00:00 2001 From: "Ryan Scheel (isHavvy)" Date: Wed, 28 Sep 2022 17:21:45 -0700 Subject: [PATCH 3/3] One line one sentence the statements and expressions chapter. --- src/expressions.md | 9 --------- src/statements-and-expressions.md | 12 ++++-------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/src/expressions.md b/src/expressions.md index 0b446af2b..b2411cd8e 100644 --- a/src/expressions.md +++ b/src/expressions.md @@ -129,15 +129,6 @@ assert_eq!( > **Note**: Since this is applied recursively, these expressions are also evaluated from innermost to outermost, ignoring siblings until there are no inner subexpressions. -## Early Termination - -Expressions may be *terminated* early, whether by a jump expression or unwinding. -When terminated, evaluation of the expression stops. -If the expression is the target of termination by a jump expression, then it evaluates to the value specified by the jump expression. -Otherwise, it evaluates to the never type. - -**Note**: Destructors are still executed for the expression after being terminated. - ## Place Expressions and Value Expressions Expressions are divided into two main categories: place expressions and value expressions; diff --git a/src/statements-and-expressions.md b/src/statements-and-expressions.md index b093972a9..fede41196 100644 --- a/src/statements-and-expressions.md +++ b/src/statements-and-expressions.md @@ -1,11 +1,7 @@ # Statements and expressions -Rust is _primarily_ an expression language. This means that most forms of -value-producing or effect-causing evaluation are directed by the uniform syntax -category of _expressions_. Each kind of expression can typically _nest_ within -each other kind of expression, and rules for evaluation of expressions involve -specifying both the value produced by the expression and the order in which its -sub-expressions are themselves evaluated. +Rust is _primarily_ an expression language. +This means that most forms of value-producing or effect-causing evaluation are directed by the uniform syntax category of _expressions_. +Each kind of expression can typically _nest_ within each other kind of expression, and rules for evaluation of expressions involve specifying both the value produced by the expression and the order in which its sub-expressions are themselves evaluated. -In contrast, statements serve _mostly_ to contain and explicitly -sequence expression evaluation. +In contrast, statements serve _mostly_ to contain and explicitly sequence expression evaluation.