-
Notifications
You must be signed in to change notification settings - Fork 553
if let
guards documentation
#1823
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -9,15 +9,25 @@ MatchExpression -> | |||||
MatchArms? | ||||||
`}` | ||||||
|
||||||
Scrutinee -> Expression _except [StructExpression]_ | ||||||
Scrutinee -> | ||||||
Expression _except_ [StructExpression] | ||||||
|
||||||
MatchArms -> | ||||||
( MatchArm `=>` ( ExpressionWithoutBlock `,` | ExpressionWithBlock `,`? ) )* | ||||||
MatchArm `=>` Expression `,`? | ||||||
|
||||||
MatchArm -> OuterAttribute* Pattern MatchArmGuard? | ||||||
MatchArm -> | ||||||
OuterAttribute* Pattern MatchArmGuard? | ||||||
|
||||||
MatchArmGuard -> `if` Expression | ||||||
MatchArmGuard -> | ||||||
`if` MatchConditions | ||||||
|
||||||
MatchConditions -> | ||||||
MatchCondition ( `&&` MatchCondition )* | ||||||
|
||||||
MatchCondition -> | ||||||
OuterAttribute* `let` Pattern `=` Scrutinee | ||||||
| Expression | ||||||
``` | ||||||
<!-- TODO: The exception above isn't accurate, see https://github.com/rust-lang/reference/issues/569 --> | ||||||
|
||||||
|
@@ -150,6 +160,93 @@ This allows shared borrows to be used inside guards without moving out of the sc | |||||
r[expr.match.guard.no-mutation] | ||||||
Moreover, by holding a shared reference while evaluating the guard, mutation inside guards is also prevented. | ||||||
|
||||||
r[expr.match.if.let.guard] | ||||||
## If Let Guards | ||||||
Match arms can include `if let` guards to allow conditional pattern matching within the guard clause. | ||||||
|
||||||
r[expr.match.if.let.guard.syntax] | ||||||
```rust,ignore | ||||||
match expression { | ||||||
pattern if let subpattern = guard_expr => arm_body, | ||||||
... | ||||||
} | ||||||
``` | ||||||
|
||||||
Here, `guard_expr` is evaluated and matched against `subpattern`. If the `if let` expression in the guard matches successfully, the arm's body is executed. Otherwise, pattern matching continues to the next arm. | ||||||
|
||||||
r[expr.match.if.let.guard.behavior] | ||||||
When the pattern matches successfully, the `if let` expression in the guard is evaluated: | ||||||
* The guard proceeds if the inner pattern (`subpattern`) matches the result of `guard_expr`. | ||||||
* Otherwise, the next arm is tested. | ||||||
|
||||||
```rust,ignore | ||||||
let value = Some(10); | ||||||
|
||||||
let msg = match value { | ||||||
Some(x) if let Some(y) = Some(x - 1) => format!("Matched inner value: {}", y), | ||||||
_ => "No match".to_string(), | ||||||
}; | ||||||
``` | ||||||
|
||||||
r[expr.match.if.let.guard.scope] | ||||||
* The `if let` guard may refer to variables bound by the outer match pattern. | ||||||
* New variables bound inside the `if let` guard (e.g., `y` in the example above) are available within the body of the match arm where the guard evaluates to `true`, but are not accessible in other arms or outside the match expression. | ||||||
|
||||||
|
||||||
```rust,ignore | ||||||
|
```rust,ignore | |
```rust |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
> ```rust,ignore | |
> ```rust |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be missing some things.
Similar to
if
expressions, this will need two separate rules. Something likeExpression | MatchConditions
because without alet
it is allowed to have LazyBooleanExpression. Then,MatchConditions
will need to exclude LazyBooleanExpression.I don't think this should use Scrutinee, because that rejects StructExpression, but that is allowed here.
This will also need similar precedence restrictions as
if let
has with restrictingLazyBooleanExpression | RangeExpr | RangeFromExpr | RangeInclusiveExpr | AssignmentExpression | CompoundAssignmentExpression
.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess, something simple like this should work right? I just not sure if I can reuse LetChain like this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, because LetChain excludes StructExpression, but we don't want to exclude that here.
We also don't want MatchConditions to exclude StructExpression.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, it's little bit hard to write a working syntax to cover all cases, let's try something like this as a start
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there needs to be a separate case for a chain vs not-chain.
For example:
so I think what it needs is something like:
right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, yeah, separate
MatchGuardScrutinee
is a good idea