@@ -4645,7 +4645,38 @@ Match Expressions
46454645 OuterAttributeOrDoc* Pattern MatchArmGuard?
46464646
46474647 MatchArmGuard ::=
4648- $$if$$ Operand
4648+ $$if$$ MatchArmGuardConditions
4649+
4650+ MatchArmGuardConditions ::=
4651+ MatchArmGuardChain
4652+ | MatchArmGuardOperand
4653+
4654+ MatchArmGuardChain ::=
4655+ MatchArmGuardCondition ($$&&$$ MatchArmGuardCondition)*
4656+
4657+ MatchArmGuardCondition ::=
4658+ MatchArmGuardConditionOperand
4659+ | MatchArmGuardLetPattern
4660+
4661+ MatchArmGuardLetPattern ::=
4662+ $$let$$ Pattern $$=$$ MatchArmGuardScrutinee
4663+
4664+ MatchArmGuardOperand ::=
4665+ Operand
4666+
4667+ :dp: `fls_3TGpt9OGydQi `
4668+ A :ds: `MatchArmGuardConditionOperand ` is any expression in category
4669+ :s: `Expression `, except expressions in categories :s: `AssignmentExpression `,
4670+ :s: `CompoundAssignmentExpression `, :s: `LazyBooleanExpression `,
4671+ :s: `RangeFromExpression `, :s: `RangeFromToExpression `, and
4672+ :s: `RangeInclusiveExpression `.
4673+
4674+ :dp: `fls_7OkU5RVrAyev `
4675+ A :ds: `MatchArmGuardScrutinee ` is any expression in category
4676+ :s: `Expression `, except expressions in categories :s: `AssignmentExpression `,
4677+ :s: `CompoundAssignmentExpression `, :s: `LazyBooleanExpression `,
4678+ :s: `RangeFromExpression `, :s: `RangeFromToExpression `, and
4679+ :s: `RangeInclusiveExpression `.
46494680
46504681.. rubric :: Legality Rules
46514682
@@ -4679,6 +4710,31 @@ A :t:`match arm body` is the :t:`operand` of a :t:`match arm`.
46794710A :t: `match arm guard ` is a :t: `construct ` that provides additional filtering to
46804711a :t: `match arm matcher `.
46814712
4713+ :dp: `fls_Uv7QsP2nKcDx `
4714+ A :t: `match arm guard operand ` is the :t: `operand ` of a :t: `match arm guard `
4715+ that does not have a :t: `match arm guard chain `.
4716+
4717+ :dp: `fls_DT4N2rr6wpvZ `
4718+ A :t: `match arm guard chain ` is a sequence of one or more
4719+ :t: `[match arm guard condition]s `, separated by ``&& ``.
4720+
4721+ :dp: `fls_gNQBzI92IAir `
4722+ A :t: `match arm guard ` that contains a :t: `match arm guard let pattern ` has a
4723+ :t: `match arm guard chain `; otherwise it has a :t: `match arm guard operand `.
4724+
4725+ :dp: `fls_Er5TmL9bXwVq `
4726+ A :t: `match arm guard condition operand ` is a :t: `match arm guard condition `
4727+ that consists of an :t: `expression `.
4728+
4729+ :dp: `fls_AAuyKfxLgJ43 `
4730+ A :t: `match arm guard let pattern ` is a :t: `match arm guard condition ` that
4731+ consists of a :t: `pattern ` and a :t: `match arm guard scrutinee `.
4732+
4733+ :dp: `fls_Yq4NhC8sRpJm `
4734+ A :t: `match arm guard scrutinee ` is the :t: `expression ` of a
4735+ :t: `match arm guard let pattern ` whose :t: `value ` is matched against the
4736+ :t: `pattern ` of that :t: `match arm guard let pattern `.
4737+
46824738:dp: `fls_RPMOAaZ6lflI `
46834739:t: `[Binding]s ` introduced in the :t: `pattern ` of a :t: `match arm matcher ` are
46844740:t: `immutable ` in the :t: `match arm guard `.
@@ -4688,9 +4744,17 @@ The :t:`type` of the :t:`subject expression` and the :t:`[type]s` of all
46884744:t: `[pattern]s ` of all :t: `[match arm matcher]s ` shall be :t: `unifiable `.
46894745
46904746:dp: `fls_bzhz5wjd90ii `
4691- The :t: `type ` of the :t: `operand ` of a :t: `match arm guard ` shall be :t: `type `
4747+ The :t: `type ` of a :t: `match arm guard operand ` shall be :t: `type ` :c: `bool `.
4748+
4749+ :dp: `fls_kM6dZv3PaNqT `
4750+ The :t: `type ` of a :t: `match arm guard condition operand ` shall be :t: `type `
46924751:c: `bool `.
46934752
4753+ :dp: `fls_Lc8EwS5rYpBn `
4754+ The :t: `expected type ` of the :t: `pattern ` of a
4755+ :t: `match arm guard let pattern ` is the :t: `type ` of its
4756+ :t: `match arm guard scrutinee `.
4757+
46944758:dp: `fls_17ag0wzdbxv6 `
46954759The :t: `[type]s ` of all :t: `match arm bodies <match arm body> ` shall be
46964760:t: `unifiable `.
@@ -4708,8 +4772,9 @@ A :t:`match arm` is selected when its :t:`pattern` matches the
47084772:t: `Match arm ` selection happens in declarative order.
47094773
47104774:dp: `fls_e02um1gb89d0 `
4711- The :t: `[pattern]s ` of all :t: `[match arm]s ` taken together shall exhaustively
4712- match the :t: `[subject expression]'s ` :t: `type `.
4775+ The :t: `[pattern]s ` of all :t: `[match arm]s ` without a
4776+ :t: `match arm guard ` taken together shall exhaustively match the
4777+ :t: `[subject expression]'s ` :t: `type `.
47134778
47144779:dp: `fls_4sh2yrslszvb `
47154780The :t: `value ` of a :t: `match expression ` is the :t: `value ` of the :t: `operand `
@@ -4742,35 +4807,133 @@ The :t:`evaluation` of a :t:`match expression` proceeds as follows:
47424807 Otherwise control proceeds with the :t: `evaluation ` of the next
47434808 :t: `match arm `.
47444809
4810+ :dp: `fls_Nc6JvS9rFaLm `
4811+ When the :t: `pattern ` of a :t: `match arm matcher ` is an :t: `or-pattern `, each
4812+ :t: `pattern-without-alternation ` of the :t: `or-pattern ` is considered in source
4813+ order during :t: `evaluation ` of the :t: `match arm matcher `. Otherwise, the
4814+ :t: `pattern ` itself is considered.
4815+
47454816:dp: `fls_4dv7x9nh2h4e `
47464817The :t: `evaluation ` of a :t: `match arm matcher ` proceeds as follows:
47474818
4748- #. :dp: `fls_k7kliy101m0f `
4749- The :t: `pattern ` of the :t: `match arm matcher ` is evaluated.
4819+ #. :dp: `fls_Qr3TcH8vNpKs `
4820+ Each :t: `pattern ` determined by :p: `fls_Nc6JvS9rFaLm ` is considered in
4821+ source order as follows:
4822+
4823+ #. :dp: `fls_Lm5WqZ2dJvYp `
4824+ If :t: `pattern matching ` with the :t: `pattern ` and the :t: `value ` of the
4825+ :t: `subject expression ` fails, then evaluation continues with the next
4826+ :t: `pattern `, if any.
47504827
4751- #. :dp: `fls_k68zkb6jv0vz `
4752- If the :t: `pattern ` succeeds, then
4828+ #. :dp: `fls_Bx8KsV4nQdRt `
4829+ If :t: ` pattern matching ` with the :t: `pattern ` succeeds, then:
47534830
4754- #. :dp: `fls_gbb6wbmher5z `
4755- If the :t: `match arm matcher ` has a :t: `match arm guard `, then
4831+ #. :dp: `fls_Mv2YpG7sLcHw `
4832+ If the :t: `match arm matcher ` has no :t: `match arm guard `, then the
4833+ :t: `match arm matcher ` succeeds and its :t: `evaluation ` is complete.
47564834
4757- #. :dp: `fls_jl4av757yx8j `
4758- The :t: `match arm guard ` is evaluated.
4835+ #. :dp: `fls_Xd4LqN9vTrPm `
4836+ If the :t: `match arm matcher ` has a :t: `match arm guard `, then the
4837+ :t: `match arm guard ` is evaluated.
47594838
4760- #. :dp: `fls_wkh5wztauwhu `
4839+ #. :dp: `fls_Hw6CkR3mVzQn `
47614840 If the :t: `match arm guard ` evaluates to ``true ``, then the
4762- :t: `match arm matcher ` succeeds.
4841+ :t: `match arm matcher ` succeeds and its :t: ` evaluation ` is complete .
47634842
4764- #. :dp: `fls_f5f0x8jstp1g `
4765- Otherwise the :t: `match arm matcher ` fails.
4843+ #. :dp: `fls_gfD9XwVj5hab `
4844+ If the :t: `match arm guard ` evaluates to ``false ``, then the
4845+ :t: `drop scope ` of the related :t: `match arm ` is left, and evaluation
4846+ continues with the next :t: `pattern `, including subsequent
4847+ :t: `[pattern-without-alternation]s ` of the same :t: `or-pattern `.
47664848
4767- #. :dp: `fls_yk8l9zjh7i0d `
4768- Otherwise the :t: `match arm matcher ` fails.
4849+ #. :dp: `fls_Zm9VxF5pQwLd `
4850+ If no considered :t: `pattern ` causes the :t: `match arm matcher ` to succeed,
4851+ then the :t: `match arm matcher ` fails.
47694852
47704853:dp: `fls_sbtx1l6n2tp2 `
4771- The :t: `evaluation ` of a :t: `match arm guard ` evaluates its :t: `operand `. A
4772- :t: `match arm guard ` evaluates to ``true `` when its :t: `operand ` evaluates to
4773- ``true ``, otherwise it evaluates to ``false ``.
4854+ The :t: `evaluation ` of a :t: `match arm guard ` proceeds as follows:
4855+
4856+ #. :dp: `fls_Dp8aJr2LqYwS `
4857+ If the :t: `match arm guard ` has a :t: `match arm guard operand `, then:
4858+
4859+ #. :dp: `fls_Wm4QvN7xTcRb `
4860+ The :t: `match arm guard operand ` is evaluated.
4861+
4862+ #. :dp: `fls_Ks9FdL3pVxQa `
4863+ If the :t: `match arm guard operand ` evaluates to ``false ``, then the
4864+ :t: `match arm guard ` evaluates to ``false `` and its :t: `evaluation ` is
4865+ complete.
4866+
4867+ #. :dp: `fls_Rt5XcG8nMbPw `
4868+ If the :t: `match arm guard operand ` evaluates to ``true ``, then the
4869+ :t: `match arm guard ` evaluates to ``true `` and its :t: `evaluation ` is
4870+ complete.
4871+
4872+ #. :dp: `fls_Yh2NqT6vLsCk `
4873+ Otherwise, the :t: `match arm guard ` has a :t: `match arm guard chain `, and:
4874+
4875+ #. :dp: `fls_Cw2RsH7pVnQx `
4876+ Each :t: `match arm guard condition ` of the chain is evaluated in source
4877+ order as follows:
4878+
4879+ #. :dp: `fls_Pb7MzD4wQkXe `
4880+ If the :t: `match arm guard condition ` is a
4881+ :t: `match arm guard condition operand `, then:
4882+
4883+ #. :dp: `fls_Fj8QpM3dLsVt `
4884+ The :t: `match arm guard condition operand ` is evaluated.
4885+
4886+ #. :dp: `fls_Qf4VnH8sMxRa `
4887+ If the :t: `match arm guard condition operand ` evaluates to
4888+ ``false ``, then the :t: `match arm guard ` evaluates to ``false `` and
4889+ no subsequent :t: `[match arm guard condition]s ` are evaluated.
4890+
4891+ #. :dp: `fls_Kz7NvR2xYpWm `
4892+ If the :t: `match arm guard condition operand ` evaluates to
4893+ ``true ``, then evaluation continues with the next
4894+ :t: `match arm guard condition `, if any.
4895+
4896+ #. :dp: `fls_Zc6TbK2wLpNd `
4897+ If the :t: `match arm guard condition ` is a
4898+ :t: `match arm guard let pattern `, then:
4899+
4900+ #. :dp: `fls_Bd9TmL4qVcNs `
4901+ The :t: `match arm guard scrutinee ` is evaluated.
4902+
4903+ #. :dp: `fls_Rp5HxK8wJqYd `
4904+ :t: `Pattern matching ` is performed with the :t: `pattern ` of the
4905+ :t: `match arm guard let pattern ` against the resulting :t: `value `.
4906+
4907+ #. :dp: `fls_Vr9MqJ5xNsYd `
4908+ If the :t: `pattern matching ` fails, then the
4909+ :t: `match arm guard ` evaluates to ``false `` and no subsequent
4910+ :t: `[match arm guard condition]s ` are evaluated.
4911+
4912+ #. :dp: `fls_Nt6QmC3sLpXz `
4913+ If the :t: `pattern matching ` succeeds, then any :t: `[binding]s `
4914+ introduced by the :t: `pattern ` are bound to the matched
4915+ :t: `[value]s ` as described in :p: `fls_t34oqarwcusu `, and evaluation
4916+ continues with the next :t: `match arm guard condition `, if any.
4917+
4918+ #. :dp: `fls_Av4JyT9nMkRp `
4919+ If every :t: `match arm guard condition ` of the chain has been evaluated
4920+ without the :t: `match arm guard ` evaluating to ``false ``, then the
4921+ :t: `match arm guard ` evaluates to ``true ``.
4922+
4923+ :dp: `fls_Gc5RpT8nYvQm `
4924+ During the :t: `evaluation ` of a :t: `match arm guard `, each :t: `binding `
4925+ introduced by the :t: `pattern ` of the related :t: `match arm matcher ` is
4926+ accessed through a :t: `shared reference ` to the matched part of the
4927+ :t: `subject expression `'s :t: `value `.
4928+
4929+ :dp: `fls_Nw2KxL7qVmRs `
4930+ If the :t: `binding mode ` of such a :t: `binding ` is :t: `by value `, then the copy
4931+ or move described by :p: `fls_pxvtqxke1enp ` is performed only if the related
4932+ :t: `match arm guard ` evaluates to ``true ``.
4933+
4934+ :dp: `fls_Rh9TsD4vQpLm `
4935+ If the related :t: `match arm guard ` evaluates to ``false ``, then no copy or
4936+ move into such a :t: `binding ` is performed.
47744937
47754938.. rubric :: Examples
47764939
@@ -4785,6 +4948,22 @@ The :t:`evaluation` of a :t:`match arm guard` evaluates its :t:`operand`. A
47854948 }
47864949 }
47874950
4951+ :dp: `fls_8Vrz9SNfjSh7 `
4952+ A match arm guard chain consisting of a match arm guard let pattern followed by
4953+ a match arm guard condition operand.
4954+
4955+ .. code-block :: rust
4956+
4957+ fn categorize(input: Option<&str>) -> &'static str {
4958+ match input {
4959+ Some(text)
4960+ if let Ok(number) = text.parse::<i32>()
4961+ && number > 9 => "big number",
4962+ Some(_) => "other text",
4963+ None => "no text"
4964+ }
4965+ }
4966+
47884967 .. _fls_8l74abhlxzdl :
47894968
47904969Return Expressions
0 commit comments