@@ -54,17 +54,38 @@ fn outer() {
5454> ** <sup >Syntax</sup >** \
5555> _ LetStatement_ :\
5656>   ;  ; [ _ OuterAttribute_ ] <sup >\* </sup > ` let ` [ _ PatternNoTopAlt_ ]
57- > ( ` : ` [ _ Type_ ] )<sup >?</sup > (` = ` [ _ Expression_ ] )<sup >?</sup > ` ; `
58-
59- A * ` let ` statement* introduces a new set of [ variables] , given by an
60- irrefutable [ pattern] . The pattern is followed optionally by a type
61- annotation and then optionally by an initializer expression. When no
62- type annotation is given, the compiler will infer the type, or signal
57+ > ( ` : ` [ _ Type_ ] )<sup >?</sup > (` = ` [ _ Expression_ ] [ †] ( #let-else-restriction )
58+ > ( ` else ` [ _ BlockExpression_ ] ) <sup >?</sup > ) <sup >?</sup > ` ; `
59+ >
60+ > <span id =" let-else-restriction " >† When an ` else ` block is specified, the
61+ > _ Expression_ must not be a [ _ LazyBooleanExpression_ ] , or end with a ` } ` .</span >
62+
63+ A * ` let ` statement* introduces a new set of [ variables] , given by a [ pattern] .
64+ The pattern is followed optionally by a type annotation and then either ends,
65+ or is followed by an initializer expression plus an optional ` else ` block.
66+ When no type annotation is given, the compiler will infer the type, or signal
6367an error if insufficient type information is available for definite
6468inference. Any variables introduced by a variable declaration are visible
6569from the point of declaration until the end of the enclosing block scope,
6670except when they are shadowed by another variable declaration.
6771
72+ If an ` else ` block is not present, the pattern must be irrefutable.
73+ If an ` else ` block is present, the pattern may be refutable.
74+ If the pattern does not match (this requires it to be refutable), the ` else `
75+ block is executed.
76+ The ` else ` block must always diverge (evaluate to the [ never type] ).
77+
78+ ``` rust
79+ let (mut v , w ) = (vec! [1 , 2 , 3 ], 42 ); // The bindings may be mut or const
80+ let Some (t ) = v . pop () else { // Refutable patterns require an else block
81+ panic! (); // The else block must diverge
82+ };
83+ let [u , v ] = [v [0 ], v [1 ]] else { // This pattern is irrefutable, so the compiler
84+ // will lint as the else block is redundant.
85+ panic! ();
86+ };
87+ ```
88+
6889## Expression statements
6990
7091> ** <sup >Syntax</sup >** \
@@ -121,16 +142,19 @@ statement are [`cfg`], and [the lint check attributes].
121142[ function ] : items/functions.md
122143[ item ] : items.md
123144[ module ] : items/modules.md
145+ [ never type ] : types/never.md
124146[ canonical path ] : paths.md#canonical-paths
125147[ implementations ] : items/implementations.md
126148[ variables ] : variables.md
127149[ outer attributes ] : attributes.md
128150[ `cfg` ] : conditional-compilation.md
129151[ the lint check attributes ] : attributes/diagnostics.md#lint-check-attributes
130152[ pattern ] : patterns.md
153+ [ _BlockExpression_ ] : expressions/block-expr.md
131154[ _ExpressionStatement_ ] : #expression-statements
132155[ _Expression_ ] : expressions.md
133156[ _Item_ ] : items.md
157+ [ _LazyBooleanExpression_ ] : expressions/operator-expr.md#lazy-boolean-operators
134158[ _LetStatement_ ] : #let-statements
135159[ _MacroInvocationSemi_ ] : macros.md#macro-invocation
136160[ _OuterAttribute_ ] : attributes.md
0 commit comments