-
Notifications
You must be signed in to change notification settings - Fork 41
document if let guards #693
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
base: main
Are you sure you want to change the base?
Changes from all commits
a9d2416
79c2910
695990c
9045712
d44f6c2
f2bef9f
eba5309
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 |
|---|---|---|
|
|
@@ -4645,7 +4645,35 @@ Match Expressions | |
| OuterAttributeOrDoc* Pattern MatchArmGuard? | ||
|
|
||
| MatchArmGuard ::= | ||
| $$if$$ Operand | ||
| $$if$$ (Operand | MatchArmGuardChain) | ||
|
|
||
| MatchArmGuardChain ::= | ||
| MatchArmGuardCondition ($$&&$$ MatchArmGuardCondition)* | ||
|
|
||
| MatchArmGuardCondition ::= | ||
| (MatchArmGuardExpression | OuterAttributeOrDoc* MatchArmGuardLetPattern) | ||
|
|
||
| MatchArmGuardLetPattern ::= | ||
| $$let$$ Pattern $$=$$ MatchArmGuardExpression | ||
|
|
||
| MatchArmGuardExpression ::= | ||
| Expression | ||
|
|
||
| :dp:`fls_UlxLrpyPlVmv` | ||
| A :dt:`match arm guard expression` is any :t:`expression` in category :s:`Expression`, except: | ||
|
|
||
| - :dp:`fls_XADcpJBUxSfv` | ||
| :s:`AssignmentExpression` | ||
| - :dp:`fls_gfHe2Cy6WXsK` | ||
| :s:`CompoundAssignmentExpression` | ||
| - :dp:`fls_QQep7FKA1EQX` | ||
| :s:`LazyBooleanExpression` | ||
| - :dp:`fls_Wepy5R7FZQPU` | ||
| :s:`RangeFromExpression` | ||
| - :dp:`fls_imEIc7PUUO1x` | ||
| :s:`RangeFromToExpression` | ||
| - :dp:`fls_fs4ZpXjt0Wqt` | ||
| :s:`RangeInclusiveExpression` | ||
|
|
||
| .. rubric:: Legality Rules | ||
|
|
||
|
|
@@ -4679,6 +4707,9 @@ A :t:`match arm body` is the :t:`operand` of a :t:`match arm`. | |
| A :t:`match arm guard` is a :t:`construct` that provides additional filtering to | ||
| a :t:`match arm matcher`. | ||
|
|
||
| :dp:`fls_DT4N2rr6wpvZ` | ||
| A :dt:`match arm guard chain` is a set of conditions that must each evaluate to ``true`` in the case of :t:`[match arm guard expression]s`, or must each produce a positive match in the case of a :t:`[match arm guard let pattern]s` for the :t:`match arm` to be selected. | ||
|
|
||
| :dp:`fls_RPMOAaZ6lflI` | ||
| :t:`[Binding]s` introduced in the :t:`pattern` of a :t:`match arm matcher` are | ||
| :t:`immutable` in the :t:`match arm guard`. | ||
|
|
@@ -4715,6 +4746,12 @@ match the :t:`[subject expression]'s` :t:`type`. | |
| The :t:`value` of a :t:`match expression` is the :t:`value` of the :t:`operand` | ||
| of the selected :t:`match arm`. | ||
|
|
||
| :dp:`fls_AAuyKfxLgJ43` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think FLS still needs an explicit guard-specific rule for when arm-pattern bindings become values. Today the shared pattern rules say by-value bindings move or copy during pattern matching ( Could we add the guard-specific rule from the Reference here (or in the shared pattern / guard text), and tie it back to the existing immutability rule for match-arm-guard bindings? That would also explain why mutation through those bindings is rejected while the guard runs. Support:
|
||
| A :dt:`match arm guard let pattern` is evaluated when its :t:`match arm guard expression` matches the specified :t:`pattern`. | ||
|
|
||
| :dp:`fls_uCDQMkWx5OMS` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this stabilization is still incomplete outside The new local rule says bindings introduced by a guard Upstream needed matching updates in Support:
|
||
| Each :t:`let binding` introduced in a :t:`match arm guard let pattern` is :t:`in scope` for the rest of the :t:`match arm guard` as well as the :t:`match arm body`. | ||
|
|
||
| .. rubric:: Dynamic Semantics | ||
|
|
||
| :dp:`fls_g551l8r8yh6d` | ||
|
|
@@ -4767,11 +4804,6 @@ The :t:`evaluation` of a :t:`match arm matcher` proceeds as follows: | |
| #. :dp:`fls_yk8l9zjh7i0d` | ||
| Otherwise the :t:`match arm matcher` fails. | ||
|
|
||
| :dp:`fls_sbtx1l6n2tp2` | ||
| The :t:`evaluation` of a :t:`match arm guard` evaluates its :t:`operand`. A | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, this paragraph is actually useful. In fact, there Dynamic Semantics section should be updated to account for match guard let patterns.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thought it was redundant since
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree the Dynamic Semantics section needs an explicit update here, not just a revised success criterion. As written, Could we make those parts explicit in Dynamic Semantics, perhaps by replacing the removed Support:
|
||
| :t:`match arm guard` evaluates to ``true`` when its :t:`operand` evaluates to | ||
| ``true``, otherwise it evaluates to ``false``. | ||
|
|
||
| .. rubric:: Examples | ||
|
|
||
| .. code-block:: rust | ||
|
|
||
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.
The new grammar now admits two different kinds of guard condition, but the old single-
boolrules are still in place.For
if let PAT = EXPR,EXPRis a scrutinee matched againstPAT;EXPRitself is not required to have typebool. Only expression-valued guard conditions arebool-typed. As written, that seems to conflict with both the existing legality rule insrc/expressions.rst(fls_bzhz5wjd90ii) and the stale inference rule insrc/types-and-traits.rst(fls_st9onPgDrc8y), which still infer all match-arm-guard operands with expected typebool.Could this be split the same way the Reference and the existing FLS already distinguish ordinary boolean conditions from
if let/while letscrutinees? One possible shape would be a distinct guard-scrutinee rule with the pattern's type as its expected type.Support:
MatchGuardConditionMatchGuardScrutineeexpr.match.guard.conditionsrc/expressions.rstfls_bzhz5wjd90iisrc/types-and-traits.rstfls_st9onPgDrc8ytests/ui/rfcs/rfc-2294-if-let-guard/type-inference.rstests/ui/rfcs/rfc-2294-if-let-guard/typeck.rsView changes since the review