diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 91f343b8d..ee825b2c4 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -63,7 +63,7 @@ - [Closure expressions](expressions/closure-expr.md) - [Loop expressions](expressions/loop-expr.md) - [Range expressions](expressions/range-expr.md) - - [If and if let expressions](expressions/if-expr.md) + - [If expressions](expressions/if-expr.md) - [Match expressions](expressions/match-expr.md) - [Return expressions](expressions/return-expr.md) - [Await expressions](expressions/await-expr.md) diff --git a/src/attributes/type_system.md b/src/attributes/type_system.md index 88044a717..fed0deef3 100644 --- a/src/attributes/type_system.md +++ b/src/attributes/type_system.md @@ -210,7 +210,6 @@ Non-exhaustive types are always considered inhabited in downstream crates. [_StructExpression_]: ../expressions/struct-expr.md [_StructPattern_]: ../patterns.md#struct-patterns [_TupleStructPattern_]: ../patterns.md#tuple-struct-patterns -[`if let`]: ../expressions/if-expr.md#if-let-expressions [`match`]: ../expressions/match-expr.md [attributes]: ../attributes.md [enum]: ../items/enumerations.md diff --git a/src/const_eval.md b/src/const_eval.md index 61e0f62f8..e6adc0b96 100644 --- a/src/const_eval.md +++ b/src/const_eval.md @@ -102,10 +102,12 @@ r[const-eval.const-expr.const-fn] * Calls of [const functions] and const methods. r[const-eval.const-expr.loop] -* [loop], [while] and [`while let`] expressions. +* [loop] and [while] expressions. r[const-eval.const-expr.if-match] -* [if], [`if let`] and [match] expressions. +* [if] and [match] expressions. + +expressions.") ## Const context [const context]: #const-context @@ -186,7 +188,6 @@ of whether you are building on a `64` bit or a `32` bit system. [grouped]: expressions/grouped-expr.md [interior mutability]: interior-mutability.md [if]: expressions/if-expr.md#if-expressions -[`if let`]: expressions/if-expr.md#if-let-expressions [lazy boolean]: expressions/operator-expr.md#lazy-boolean-operators [let statements]: statements.md#let-statements [literals]: expressions/literal-expr.md @@ -203,4 +204,3 @@ of whether you are building on a `64` bit or a `32` bit system. [struct]: expressions/struct-expr.md [tuple expressions]: expressions/tuple-expr.md [while]: expressions/loop-expr.md#predicate-loops -[`while let`]: expressions/loop-expr.md#predicate-pattern-loops diff --git a/src/destructors.md b/src/destructors.md index 7ec6d6fe1..3b2097503 100644 --- a/src/destructors.md +++ b/src/destructors.md @@ -67,8 +67,9 @@ leaves a drop scope all variables associated to that scope are dropped in reverse order of declaration (for variables) or creation (for temporaries). r[destructors.scope.desugaring] -Drop scopes are determined after replacing [`for`], [`if let`], and -[`while let`] expressions with the equivalent expressions using [`match`]. +Drop scopes can be determined by replacing [`for`], [`if`], and [`while`] +expressions with equivalent expressions using [`match`], [`loop`] and +`break`. r[destructors.scope.operators] Overloaded operators are not distinguished from built-in operators and [binding @@ -204,11 +205,11 @@ smallest scope that contains the expression and is one of the following: * A statement. * The body of an [`if`], [`while`] or [`loop`] expression. * The `else` block of an `if` expression. -* The condition expression of an `if` or `while` expression, or a `match` - guard. +* The non-pattern matching condition expression of an `if` or `while` expression, + or a `match` guard. * The body expression for a match arm. * Each operand of a [lazy boolean expression]. -* The pattern-matching condition and consequent body of [`if let`] ([destructors.scope.temporary.edition2024]). +* The pattern-matching condition(s) and consequent body of [`if`] ([destructors.scope.temporary.edition2024]). * The entirety of the tail expression of a block ([destructors.scope.temporary.edition2024]). > **Notes**: @@ -473,10 +474,10 @@ variable or field from being dropped automatically. [tuple indexing expression]: expressions/tuple-expr.md#tuple-indexing-expressions [`for`]: expressions/loop-expr.md#iterator-loops -[`if let`]: expressions/if-expr.md#if-let-expressions +[`if let`]: expressions/if-expr.md#if-let-patterns [`if`]: expressions/if-expr.md#if-expressions [`let` statement]: statements.md#let-statements [`loop`]: expressions/loop-expr.md#infinite-loops [`match`]: expressions/match-expr.md -[`while let`]: expressions/loop-expr.md#predicate-pattern-loops +[`while let`]: expressions/loop-expr.md#while-let-patterns [`while`]: expressions/loop-expr.md#predicate-loops diff --git a/src/expressions.md b/src/expressions.md index 6de08086d..78e7d3ef5 100644 --- a/src/expressions.md +++ b/src/expressions.md @@ -41,7 +41,6 @@ r[expr.syntax] >       | [_UnsafeBlockExpression_]\ >       | [_LoopExpression_]\ >       | [_IfExpression_]\ ->       | [_IfLetExpression_]\ >       | [_MatchExpression_]\ >    ) @@ -309,13 +308,13 @@ They are never allowed before: [call expressions]: expressions/call-expr.md [field]: expressions/field-expr.md [functional update]: expressions/struct-expr.md#functional-update-syntax -[`if let`]: expressions/if-expr.md#if-let-expressions +[`if let`]: expressions/if-expr.md#if-let-patterns [match]: expressions/match-expr.md [method-call]: expressions/method-call-expr.md [paths]: expressions/path-expr.md [struct]: expressions/struct-expr.md [tuple expressions]: expressions/tuple-expr.md -[`while let`]: expressions/loop-expr.md#predicate-pattern-loops +[`while let`]: expressions/loop-expr.md#while-let-patterns [array expressions]: expressions/array-expr.md [array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions @@ -362,7 +361,6 @@ They are never allowed before: [_FieldExpression_]: expressions/field-expr.md [_GroupedExpression_]: expressions/grouped-expr.md [_IfExpression_]: expressions/if-expr.md#if-expressions -[_IfLetExpression_]: expressions/if-expr.md#if-let-expressions [_IndexExpression_]: expressions/array-expr.md#array-and-slice-indexing-expressions [_LazyBooleanExpression_]: expressions/operator-expr.md#lazy-boolean-operators [_LiteralExpression_]: expressions/literal-expr.md diff --git a/src/expressions/block-expr.md b/src/expressions/block-expr.md index 3afebefe5..ad9ed1737 100644 --- a/src/expressions/block-expr.md +++ b/src/expressions/block-expr.md @@ -251,7 +251,7 @@ r[expr.block.attributes.inner-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`]). +* Loop bodies ([`loop`], [`while`], and [`for`]). * Block expressions used as a [statement]. * Block expressions as elements of [array expressions], [tuple expressions], [call expressions], and tuple-style [struct] expressions. @@ -278,7 +278,6 @@ fn is_unix_platform() -> bool { [`for`]: loop-expr.md#iterator-loops [`loop`]: loop-expr.md#infinite-loops [`unsafe` blocks]: ../unsafe-keyword.md#unsafe-blocks-unsafe- -[`while let`]: loop-expr.md#predicate-pattern-loops [`while`]: loop-expr.md#predicate-loops [array expressions]: array-expr.md [call expressions]: call-expr.md diff --git a/src/expressions/if-expr.md b/src/expressions/if-expr.md index e2fbf3a9a..ccf354846 100644 --- a/src/expressions/if-expr.md +++ b/src/expressions/if-expr.md @@ -1,35 +1,43 @@ r[expr.if] -# `if` and `if let` expressions - -## `if` expressions +# `if` expressions r[expr.if.syntax] +## Syntax + > **Syntax**\ > _IfExpression_ :\ ->    `if` [_Expression_]_except struct expression_ [_BlockExpression_]\ ->    (`else` ( -> [_BlockExpression_] -> | _IfExpression_ -> | _IfLetExpression_ ) )\? +>    `if` _IfConditions_ [_BlockExpression_]\ +>    (`else` ( [_BlockExpression_] | _IfExpression_ ) )\? +> +> _IfConditions_ :\ +>    _IfCondition_ ( && _IfCondition_ )*[^if-condition-2024] +> +> _IfCondition_ :\ +>       [_Expression_]_except struct expression or lazy boolean expression_\ +>    | `let` [_Pattern_] `=` [_Scrutinee_]_except struct expression or lazy boolean expression_ +> +> [^if-condition-2024]: Editions before 2024 only allow a single _IfCondition_. r[expr.if.intro] -An `if` expression is a conditional branch in program control. -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. +The syntax of an `if` expression is a sequence of one or more condition operands separated by `&&`, +followed by a consequent block, any number of `else if` conditions and blocks, and an optional trailing `else` block. -r[expr.if.condition-bool] -The condition operands must have the [boolean type]. +r[expr.if.condition] +Condition operands must be either an [_Expression_] with a [boolean type] or a conditional `let` match. r[expr.if.condition-true] -If a condition operand evaluates to `true`, the consequent block is executed and any subsequent `else if` or `else` block is skipped. +If all of the condition operands evaluate to `true` and all of the `let` patterns successfully match their [scrutinee]s, +the consequent block is executed and any subsequent `else if` or `else` block is skipped. r[expr.if.else-if] -If a condition operand evaluates to `false`, the consequent block is skipped and any subsequent `else if` condition is evaluated. +If any condition operand evaluates to `false` or any `let` pattern does not match its scrutinee, +the consequent block is skipped and any subsequent `else if` condition is evaluated. r[expr.if.else] If all `if` and `else if` conditions evaluate to `false` then any `else` block is executed. r[expr.if.result] -An if expression evaluates to the same value as the executed block, or `()` if no block is evaluated. +An `if` expression evaluates to the same value as the executed block, or `()` if no block is evaluated. r[expr.if.type] An `if` expression must have the same type in all situations. @@ -44,6 +52,7 @@ if x == 4 { println!("x is something else"); } +// `if` can be used as an expression. let y = if 12 * 15 > 150 { "Bigger" } else { @@ -53,34 +62,17 @@ assert_eq!(y, "Bigger"); ``` r[expr.if.let] -## `if let` expressions - -r[expr.if.let.syntax] -> **Syntax**\ -> _IfLetExpression_ :\ ->    `if` `let` [_Pattern_] `=` [_Scrutinee_]_except lazy boolean operator expression_ -> [_BlockExpression_]\ ->    (`else` ( -> [_BlockExpression_] -> | _IfExpression_ -> | _IfLetExpression_ ) )\? +## `if let` patterns r[expr.if.let.intro] -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. - -r[expr.if.let.pattern] -If the value of the scrutinee matches the pattern, the corresponding block will execute. +`let` patterns in an `if` condition allow binding new variables into scope when the pattern matches successfully. -r[expr.if.let.else] -Otherwise, flow proceeds to the following `else` block if it exists. - -r[expr.if.let.result] -Like `if` expressions, `if let` expressions have a value determined by the block that is evaluated. +The following examples illustrate bindings using `let` patterns: ```rust let dish = ("Ham", "Eggs"); -// this body will be skipped because the pattern is refuted +// This body will be skipped because the pattern is refuted. if let ("Bacon", b) = dish { println!("Bacon is served with {}", b); } else { @@ -88,7 +80,7 @@ if let ("Bacon", b) = dish { println!("No bacon will be served"); } -// this body will execute +// This body will execute. if let ("Ham", b) = dish { println!("Ham is served with {}", b); } @@ -98,47 +90,9 @@ if let _ = 5 { } ``` -r[expr.if.let.else-if] -`if` and `if let` expressions can be intermixed: - -```rust -let x = Some(3); -let a = if let Some(1) = x { - 1 -} else if x == Some(2) { - 2 -} else if let Some(y) = x { - y -} else { - -1 -}; -assert_eq!(a, 3); -``` - -r[expr.if.let.desugaring] -An `if let` expression is equivalent to a [`match` expression] as follows: - - -```rust,ignore -if let PATS = EXPR { - /* body */ -} else { - /*else */ -} -``` - -is equivalent to - - -```rust,ignore -match EXPR { - PATS => { /* body */ }, - _ => { /* else */ }, // () if there is no else -} -``` - r[expr.if.let.or-pattern] -Multiple patterns may be specified with the `|` operator. This has the same semantics as with `|` in `match` expressions: +Multiple patterns may be specified with the `|` operator. +This has the same semantics as with `|` in [`match` expressions]: ```rust enum E { @@ -152,32 +106,70 @@ if let E::X(n) | E::Y(n) = v { } ``` -r[expr.if.let.lazy-bool] -The expression cannot be a [lazy boolean operator expression][_LazyBooleanOperatorExpression_]. -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_]). -When lazy boolean operator expression is desired, this can be achieved by using parenthesis as below: +r[expr.if.chains] +## Chains of conditions + +r[expr.if.chains.intro] +Multiple condition operands can be separated with `&&`. - -```rust,ignore -// Before... -if let PAT = EXPR && EXPR { .. } +r[expr.if.chains.order] +Similar to a `&&` [_LazyBooleanOperatorExpression_], each operand is evaluated from left-to-right until an operand evaluates as `false` or a `let` match fails, +in which case the subsequent operands are not evaluated. -// After... -if let PAT = ( EXPR && EXPR ) { .. } +r[expr.if.chains.bindings] +The bindings of each pattern are put into scope to be available for the next condition operand and the consequent block. -// Before... -if let PAT = EXPR || EXPR { .. } +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: -// After... -if let PAT = ( EXPR || EXPR ) { .. } +```rust +fn single() { + let outer_opt = Some(Some(1i32)); + + if let Some(inner_opt) = outer_opt + && let Some(number) = inner_opt + && number == 1 + { + println!("Peek a boo"); + } +} ``` +The above is equivalent to the following without using chains of conditions: + +```rust +fn nested() { + let outer_opt = Some(Some(1i32)); + + if let Some(inner_opt) = outer_opt { + if let Some(number) = inner_opt { + if number == 1 { + println!("Peek a boo"); + } + } + } +} +``` + +r[expr.if.chains.or] +If any condition operand is a `let` pattern, then none of the condition operands can be a `||` [lazy boolean operator expression][_LazyBooleanOperatorExpression_] due to ambiguity and precedence with the `let` scrutinee. +If a `||` expression is needed, then parentheses can be used. For example: + +```rust +# let foo = Some(123); +# let condition1 = true; +# let condition2 = false; +// Parentheses are required here. +if let Some(x) = foo && (condition1 || condition2) { /*...*/ } +``` + +r[expr.if.edition2024] +> **Edition differences**: Before the 2024 edition, let chains are not supported and only a single _IfCondition_ is allowed in an `if` expression. + [_BlockExpression_]: block-expr.md [_Expression_]: ../expressions.md [_LazyBooleanOperatorExpression_]: operator-expr.md#lazy-boolean-operators [_Pattern_]: ../patterns.md [_Scrutinee_]: match-expr.md -[_eRFCIfLetChain_]: https://github.com/rust-lang/rfcs/blob/master/text/2497-if-let-chains.md#rollout-plan-and-transitioning-to-rust-2018 -[`match` expression]: match-expr.md +[`match` expressions]: match-expr.md [boolean type]: ../types/boolean.md [scrutinee]: ../glossary.md#scrutinee diff --git a/src/expressions/loop-expr.md b/src/expressions/loop-expr.md index c60453143..cfcf44949 100644 --- a/src/expressions/loop-expr.md +++ b/src/expressions/loop-expr.md @@ -7,7 +7,6 @@ r[expr.loop.syntax] >    [_LoopLabel_]? (\ >          [_InfiniteLoopExpression_]\ >       | [_PredicateLoopExpression_]\ ->       | [_PredicatePatternLoopExpression_]\ >       | [_IteratorLoopExpression_]\ >       | [_LabelBlockExpression_]\ >    ) @@ -15,21 +14,19 @@ r[expr.loop.syntax] [_LoopLabel_]: #loop-labels [_InfiniteLoopExpression_]: #infinite-loops [_PredicateLoopExpression_]: #predicate-loops -[_PredicatePatternLoopExpression_]: #predicate-pattern-loops [_IteratorLoopExpression_]: #iterator-loops [_LabelBlockExpression_]: #labelled-block-expressions r[expr.loop.intro] -Rust supports five loop expressions: +Rust supports four loop expressions: * A [`loop` expression](#infinite-loops) denotes an infinite loop. * A [`while` expression](#predicate-loops) loops until a predicate is false. -* A [`while let` expression](#predicate-pattern-loops) tests a pattern. * A [`for` expression](#iterator-loops) extracts values from an iterator, looping until the iterator is empty. * A [labelled block expression](#labelled-block-expressions) runs a loop exactly once, but allows exiting the loop early with `break`. r[expr.loop.break-label] -All five types of loop support [`break` expressions](#break-expressions), and [labels](#loop-labels). +All four types of loop support [`break` expressions](#break-expressions), and [labels](#loop-labels). r[expr.loop.continue-label] All except labelled block expressions support [`continue` expressions](#continue-expressions). @@ -58,17 +55,38 @@ A `loop` expression containing associated [`break` expression(s)](#break-express r[expr.loop.while] ## Predicate loops -r[expr.loop.while.syntax] > **Syntax**\ -> _PredicateLoopExpression_ :\ ->    `while` [_Expression_]_except struct expression_ [_BlockExpression_] +> [_PredicateLoopExpression_] :\ +>    `while` _WhileConditions_ [_BlockExpression_] +> +> _WhileConditions_ :\ +>    _WhileCondition_ ( && _WhileCondition_ )* +> +> _WhileCondition_ :\ +>       [_Expression_]_except struct expression_\ +>    | `let` [_Pattern_] `=` [_Scrutinee_] r[expr.loop.while.intro] -A `while` loop begins by evaluating the [boolean] loop conditional operand. +A `while` loop expression allows repeating the evaluation of a block while a set of conditions remain true. + +r[expr.loop.while.syntax] +The syntax of a `while` expression is a sequence of one or more condition operands separated by `&&`, +followed by a [_BlockExpression_]. r[expr.loop.while.condition] -If the loop conditional operand evaluates to `true`, the loop body block executes, then control returns to the loop conditional operand. -If the loop conditional expression evaluates to `false`, the `while` expression completes. +Condition operands must be either an [_Expression_] with a [boolean type] or a conditional `let` match. +If all of the condition operands evaluate to `true` and all of the `let` patterns successfully match their [scrutinee]s, +then the loop body block executes. + +r[expr.loop.while.repeat] +After the loop body successfully executes, the condition operands are re-evaluated to determine if the body should be executed again. + +r[expr.loop.while.exit] +If any condition operand evaluates to `false` or any `let` pattern does not match its scrutinee, +the body is not executed and execution continues after the `while` expression. + +r[expr.loop.while.eval] +A `while` expression evaluates to `()`. An example: @@ -82,20 +100,11 @@ while i < 10 { ``` r[expr.loop.while.let] -## Predicate pattern loops - -r[expr.loop.while.let.syntax] -> **Syntax**\ -> [_PredicatePatternLoopExpression_] :\ ->    `while` `let` [_Pattern_] `=` [_Scrutinee_]_except lazy boolean operator expression_ -> [_BlockExpression_] +### `while let` patterns r[expr.loop.while.let.intro] -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. - -r[expr.loop.while.let.condition] -If the value of the scrutinee matches the pattern, the loop body block executes then control returns to the pattern matching statement. -Otherwise, the while expression completes. +`let` patterns in a `while` condition allow binding new variables into scope when the pattern matches successfully. +The following examples illustrate bindings using `let` patterns: ```rust let mut x = vec![1, 2, 3]; @@ -144,8 +153,28 @@ while let Some(v @ 1) | Some(v @ 2) = vals.pop() { } ``` -r[expr.loop.while.let.lazy-bool] -As is the case in [`if let` expressions], the scrutinee cannot be a [lazy boolean operator expression][_LazyBooleanOperatorExpression_]. +r[expr.loop.while.chains] +### `while` condition chains + +r[expr.loop.while.chains.intro] +Multiple condition operands can be separated with `&&`. +These have the same semantics and restrictions as [`if` condition chains]. + +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: + +```rust +fn main() { + let outer_opt = Some(Some(1i32)); + + while let Some(inner_opt) = outer_opt + && let Some(number) = inner_opt + && number == 1 + { + println!("Peek a boo"); + break; + } +} +``` r[expr.loop.for] ## Iterator loops @@ -336,7 +365,7 @@ r[expr.loop.continue.intro] When `continue` is encountered, the current iteration of the associated loop body is immediately terminated, returning control to the loop *head*. r[expr.loop.continue.while] -In the case of a `while` loop, the head is the conditional expression controlling the loop. +In the case of a `while` loop, the head is the conditional operands controlling the loop. r[expr.loop.continue.for] In the case of a `for` loop, the head is the call-expression controlling the loop. @@ -375,11 +404,12 @@ In the case a `loop` has an associated `break`, it is not considered diverging, [LIFETIME_OR_LABEL]: ../tokens.md#lifetimes-and-loop-labels [_BlockExpression_]: block-expr.md [_Expression_]: ../expressions.md +[_LazyBooleanOperatorExpression_]: operator-expr.md#lazy-boolean-operators [_Pattern_]: ../patterns.md [_Scrutinee_]: match-expr.md +[`if` condition chains]: if-expr.md#chains-of-conditions +[`if` expressions]: if-expr.md [`match` expression]: match-expr.md -[boolean]: ../types/boolean.md +[boolean type]: ../types/boolean.md [scrutinee]: ../glossary.md#scrutinee [temporary values]: ../expressions.md#temporaries -[_LazyBooleanOperatorExpression_]: operator-expr.md#lazy-boolean-operators -[`if let` expressions]: if-expr.md#if-let-expressions diff --git a/src/expressions/struct-expr.md b/src/expressions/struct-expr.md index cffadef57..d4ac0c2d6 100644 --- a/src/expressions/struct-expr.md +++ b/src/expressions/struct-expr.md @@ -149,7 +149,7 @@ let b = Gamma{}; // Exact same value as `a`. [_PathInExpression_]: ../paths.md#paths-in-expressions [call expression]: call-expr.md [enum variant]: ../items/enumerations.md -[if let]: if-expr.md#if-let-expressions +[if let]: if-expr.md#if-let-patterns [if]: if-expr.md#if-expressions [loop]: loop-expr.md [match]: match-expr.md diff --git a/src/names.md b/src/names.md index 92d2cd82c..b9af0e535 100644 --- a/src/names.md +++ b/src/names.md @@ -135,13 +135,13 @@ to with certain [path qualifiers] or aliases. [*visibility*]: visibility-and-privacy.md [`'static`]: keywords.md#weak-keywords [`for`]: expressions/loop-expr.md#iterator-loops -[`if let`]: expressions/if-expr.md#if-let-expressions +[`if let`]: expressions/if-expr.md#if-let-patterns [`let` statement]: statements.md#let-statements [`macro_export` attribute]: macros-by-example.md#path-based-scope [`macro_rules` declarations]: macros-by-example.md [`macro_use` attribute]: macros-by-example.md#the-macro_use-attribute [`match`]: expressions/match-expr.md -[`while let`]: expressions/loop-expr.md#predicate-pattern-loops +[`while let`]: expressions/loop-expr.md#while-let-patterns [associated items]: items/associated-items.md [attributes]: attributes.md [Boolean type]: types/boolean.md diff --git a/src/names/namespaces.md b/src/names/namespaces.md index afe48a2e5..feb0e9771 100644 --- a/src/names/namespaces.md +++ b/src/names/namespaces.md @@ -123,14 +123,14 @@ It is still an error for a [`use` import] to shadow another macro, regardless of [`cfg` attribute]: ../conditional-compilation.md#the-cfg-attribute [`cfg` macro]: ../conditional-compilation.md#the-cfg-macro [`for`]: ../expressions/loop-expr.md#iterator-loops -[`if let`]: ../expressions/if-expr.md#if-let-expressions +[`if let`]: ../expressions/if-expr.md#if-let-patterns [`let`]: ../statements.md#let-statements [`macro_rules` declarations]: ../macros-by-example.md [`match`]: ../expressions/match-expr.md [`Self` constructors]: ../paths.md#self-1 [`Self` type]: ../paths.md#self-1 [`use` import]: ../items/use-declarations.md -[`while let`]: ../expressions/loop-expr.md#predicate-pattern-loops +[`while let`]: ../expressions/loop-expr.md#while-let-patterns [Associated const declarations]: ../items/associated-items.md#associated-constants [Associated function declarations]: ../items/associated-items.md#associated-functions-and-methods [Associated type declarations]: ../items/associated-items.md#associated-types diff --git a/src/patterns.md b/src/patterns.md index dcb8f33fe..9f7d263fc 100644 --- a/src/patterns.md +++ b/src/patterns.md @@ -79,7 +79,7 @@ r[patterns.if-let] * [`if let` expressions](expressions/if-expr.md) r[patterns.while-let] -* [`while let` expressions](expressions/loop-expr.md#predicate-pattern-loops) +* [`while let` expressions](expressions/loop-expr.md#while-let-patterns) r[patterns.for] * [`for` expressions](expressions/loop-expr.md#iterator-loops) diff --git a/src/tokens.md b/src/tokens.md index 317a437ce..f678998c8 100644 --- a/src/tokens.md +++ b/src/tokens.md @@ -942,7 +942,7 @@ r[lex.token.reserved-guards.edition2024] [functions]: items/functions.md [generics]: items/generics.md [identifier]: identifiers.md -[if let]: expressions/if-expr.md#if-let-expressions +[if let]: expressions/if-expr.md#if-let-patterns [Integer literal expressions]: expressions/literal-expr.md#integer-literal-expressions [keywords]: keywords.md [lazy-bool]: expressions/operator-expr.md#lazy-boolean-operators @@ -973,4 +973,4 @@ r[lex.token.reserved-guards.edition2024] [unary minus operator]: expressions/operator-expr.md#negation-operators [use declarations]: items/use-declarations.md [use wildcards]: items/use-declarations.md -[while let]: expressions/loop-expr.md#predicate-pattern-loops +[while let]: expressions/loop-expr.md#while-let-patterns