Skip to content

Commit db6fc4e

Browse files
Revert "Add let_chains references"
This reverts commit 4662059.
1 parent 4aff5be commit db6fc4e

File tree

2 files changed

+62
-108
lines changed

2 files changed

+62
-108
lines changed

Diff for: src/expressions/if-expr.md

+51-71
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
1-
# `if` expressions
1+
# `if` and `if let` expressions
22

3-
## Syntax
4-
5-
The same syntax is used by `if`, `if let` and chains of expressions.
3+
## `if` expressions
64

75
> **<sup>Syntax</sup>**\
86
> _IfExpression_ :\
9-
> &nbsp;&nbsp; `if` _IfLetList_ [_BlockExpression_]\
10-
> &nbsp;&nbsp; ( `else` _IfLetList_ [_BlockExpression_] )<sup>\?</sup>
11-
>
12-
> _IfLet_ :\
13-
> &nbsp;&nbsp; [_Expression_]<sub>_except struct expression_</sub>
14-
> | `let` [_Pattern_] `=` [_Expression_]<sub>_except struct expression_</sub>
15-
>
16-
> _IfLetList_ :\
17-
> &nbsp;&nbsp; _IfLet_ ( && _IfLet_ )*
18-
19-
## `if`
7+
> &nbsp;&nbsp; `if` [_Expression_]<sub>_except struct expression_</sub> [_BlockExpression_]\
8+
> &nbsp;&nbsp; (`else` (
9+
> [_BlockExpression_]
10+
> | _IfExpression_
11+
> | _IfLetExpression_ ) )<sup>\?</sup>
2012
2113
An `if` expression is a conditional branch in program control.
2214
The syntax of an `if` expression is a condition operand, followed by a consequent block, any number of `else if` conditions and blocks, and an optional trailing `else` block.
@@ -45,7 +37,16 @@ let y = if 12 * 15 > 150 {
4537
assert_eq!(y, "Bigger");
4638
```
4739

48-
## `if let`
40+
## `if let` expressions
41+
42+
> **<sup>Syntax</sup>**\
43+
> _IfLetExpression_ :\
44+
> &nbsp;&nbsp; `if` `let` [_Pattern_] `=` [_Scrutinee_]<sub>_except lazy boolean operator expression_</sub>
45+
> [_BlockExpression_]\
46+
> &nbsp;&nbsp; (`else` (
47+
> [_BlockExpression_]
48+
> | _IfExpression_
49+
> | _IfLetExpression_ ) )<sup>\?</sup>
4950
5051
An `if let` expression is semantically similar to an `if` expression but in place of a condition operand it expects the keyword `let` followed by a pattern, an `=` and a [scrutinee] operand.
5152
If the value of the scrutinee matches the pattern, the corresponding block will execute.
@@ -89,6 +90,27 @@ let a = if let Some(1) = x {
8990
assert_eq!(a, 3);
9091
```
9192

93+
An `if let` expression is equivalent to a [`match` expression] as follows:
94+
95+
<!-- ignore: expansion example -->
96+
```rust,ignore
97+
if let PATS = EXPR {
98+
/* body */
99+
} else {
100+
/*else */
101+
}
102+
```
103+
104+
is equivalent to
105+
106+
<!-- ignore: expansion example -->
107+
```rust,ignore
108+
match EXPR {
109+
PATS => { /* body */ },
110+
_ => { /* else */ }, // () if there is no else
111+
}
112+
```
113+
92114
Multiple patterns may be specified with the `|` operator. This has the same semantics as with `|` in `match` expressions:
93115

94116
```rust
@@ -104,72 +126,30 @@ if let E::X(n) | E::Y(n) = v {
104126
```
105127

106128
The expression cannot be a [lazy boolean operator expression][_LazyBooleanOperatorExpression_].
107-
Scrutinee expressions also cannot be a [lazy boolean operator expression][_LazyBooleanOperatorExpression_] due to ambiguity and precedence with [chains of expressions][_ChainsOfExpressions_].
108-
109-
## Chains of expressions
110-
111-
The following is an example of chaining multiple expressions, mixing `let` bindings and boolean expressions, and with expressions able to reference pattern bindings from previous expressions:
129+
Use of a lazy boolean operator is ambiguous with a planned feature change of the language (the implementation of if-let chains - see [eRFC 2947][_eRFCIfLetChain_]).
130+
When lazy boolean operator expression is desired, this can be achieved by using parenthesis as below:
112131

113-
```rust
114-
fn single() {
115-
let outer_opt = Some(Some(1i32));
116-
117-
if let Some(inner_opt) = outer_opt
118-
&& let Some(number) = inner_opt
119-
&& number == 1
120-
{
121-
println!("Peek a boo");
122-
}
123-
}
124-
125-
The above is equivalent to the following without using expression chains:
126-
127-
fn nested() {
128-
let outer_opt = Some(Some(1i32));
129-
130-
if let Some(inner_opt) = outer_opt {
131-
if let Some(number) = inner_opt {
132-
if number == 1 {
133-
println!("Peek a boo");
134-
}
135-
}
136-
}
137-
}
138-
```
139-
140-
In other words, chains are equivalent to nested [`if let` expressions]:
141-
142-
<!-- ignore: expansion example -->
132+
<!-- ignore: psuedo code -->
143133
```rust,ignore
144-
if let PAT0 = EXPR0 && let PAT1 = EXPR1 {
145-
/* body */
146-
} else {
147-
/* else */
148-
}
149-
```
134+
// Before...
135+
if let PAT = EXPR && EXPR { .. }
150136
151-
is equivalent to
137+
// After...
138+
if let PAT = ( EXPR && EXPR ) { .. }
152139
153-
<!-- ignore: expansion example -->
154-
```rust,ignore
155-
if let PAT0 = EXPR0 {
156-
if let PAT1 = EXPR1 {
157-
/* body */
158-
}
159-
else {
160-
/* else */
161-
}
162-
} else {
163-
/* else */
164-
}
140+
// Before...
141+
if let PAT = EXPR || EXPR { .. }
142+
143+
// After...
144+
if let PAT = ( EXPR || EXPR ) { .. }
165145
```
166146

167147
[_BlockExpression_]: block-expr.md
168-
[_ChainsOfExpressions_]: #chains-of-expressions
169148
[_Expression_]: ../expressions.md
170149
[_LazyBooleanOperatorExpression_]: operator-expr.md#lazy-boolean-operators
171150
[_Pattern_]: ../patterns.md
172151
[_Scrutinee_]: match-expr.md
152+
[_eRFCIfLetChain_]: https://github.com/rust-lang/rfcs/blob/master/text/2497-if-let-chains.md#rollout-plan-and-transitioning-to-rust-2018
173153
[`match` expression]: match-expr.md
174154
[boolean type]: ../types/boolean.md
175155
[scrutinee]: ../glossary.md#scrutinee

Diff for: src/expressions/loop-expr.md

+11-37
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
> &nbsp;&nbsp; [_LoopLabel_]<sup>?</sup> (\
66
> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [_InfiniteLoopExpression_]\
77
> &nbsp;&nbsp; &nbsp;&nbsp; | [_PredicateLoopExpression_]\
8+
> &nbsp;&nbsp; &nbsp;&nbsp; | [_PredicatePatternLoopExpression_]\
89
> &nbsp;&nbsp; &nbsp;&nbsp; | [_IteratorLoopExpression_]\
910
> &nbsp;&nbsp; )
1011
1112
[_LoopLabel_]: #loop-labels
1213
[_InfiniteLoopExpression_]: #infinite-loops
1314
[_PredicateLoopExpression_]: #predicate-loops
15+
[_PredicatePatternLoopExpression_]: #predicate-pattern-loops
1416
[_IteratorLoopExpression_]: #iterator-loops
1517

1618
Rust supports four loop expressions:
@@ -37,23 +39,9 @@ A `loop` expression containing associated [`break` expression(s)](#break-express
3739

3840
## Predicate loops
3941

40-
### Syntax
41-
42-
The same syntax is used by `while`, `while let` and chains of expressions.
43-
4442
> **<sup>Syntax</sup>**\
45-
> [_PredicateLoopExpression_] :\
46-
> _WhileExpression_ :\
47-
> &nbsp;&nbsp; `while` _WhileLetList_ [_BlockExpression_]
48-
>
49-
> _WhileLet_ :\
50-
> &nbsp;&nbsp; ( [_Expression_]<sub>_except struct expression_</sub>
51-
> | `let` [_Pattern_] `=` [_Expression_]<sub>_except struct expression_</sub> )
52-
>
53-
> _WhileLetList_ :\
54-
> &nbsp;&nbsp; _WhileLet_ ( && _WhileLet_ )*
55-
56-
### `while`
43+
> _PredicateLoopExpression_ :\
44+
> &nbsp;&nbsp; `while` [_Expression_]<sub>_except struct expression_</sub> [_BlockExpression_]
5745
5846
A `while` loop begins by evaluating the [boolean] loop conditional operand.
5947
If the loop conditional operand evaluates to `true`, the loop body block executes, then control returns to the loop conditional operand.
@@ -70,7 +58,13 @@ while i < 10 {
7058
}
7159
```
7260

73-
### `while let`
61+
## Predicate pattern loops
62+
63+
> **<sup>Syntax</sup>**\
64+
> [_PredicatePatternLoopExpression_] :\
65+
> &nbsp;&nbsp; `while` `let` [_Pattern_] `=` [_Scrutinee_]<sub>_except lazy boolean operator expression_</sub>
66+
> [_BlockExpression_]
67+
7468

7569
A `while let` loop is semantically similar to a `while` loop but in place of a condition expression it expects the keyword `let` followed by a pattern, an `=`, a [scrutinee] expression and a block expression.
7670
If the value of the scrutinee matches the pattern, the loop body block executes then control returns to the pattern matching statement.
@@ -123,26 +117,6 @@ while let Some(v @ 1) | Some(v @ 2) = vals.pop() {
123117

124118
As is the case in [`if let` expressions], the scrutinee cannot be a [lazy boolean operator expression][_LazyBooleanOperatorExpression_].
125119

126-
### Chains of expressions
127-
128-
The following is an example of chaining multiple expressions, mixing `let` bindings and boolean expressions, and with expressions able to reference pattern bindings from previous expressions:
129-
130-
```rust
131-
fn main() {
132-
let outer_opt = Some(Some(1i32));
133-
134-
while let Some(inner_opt) = outer_opt
135-
&& let Some(number) = inner_opt
136-
&& number == 1
137-
{
138-
println!("Peek a boo");
139-
break;
140-
}
141-
}
142-
```
143-
144-
The only remark is the fact that parenthesis (`while (let Some(a) = opt && (let Some(b) = a)) && b == 1`) and `||` operators (`while let A(x) = e1 || let B(x) = e2`) are not currently supported.
145-
146120
## Iterator loops
147121

148122
> **<sup>Syntax</sup>**\

0 commit comments

Comments
 (0)