- Feature Name: if_while_or_patterns
- Start Date: 2017-10-16
- RFC PR: rust-lang/rfcs#2175
- Rust Issue: rust-lang/rust#48215
Summary
Enables "or" patterns for if let
and while let
expressionslet
and for
statements.
Motivation
While nothing in this RFC is currently impossible in Rust, the changes the RFC proposes improves the ergonomics of controlenum
s (sum types) with three or more variants where the program should react in one way to a group of variants, and another way to another group of variants. Examples of when such sum types occur
The following snippet
must be written as:
or, using match
:
This way of using match
is seen multiplestd::iter
when dealing with the Chain
iterator adapter. An example of this is:
which could have been written as:
This version is both shorter and clearer.
With while let
, the ergonomics and in particular the readability
The following snippet
must currently be written as:
Another major motivation of the RFC is consistency with match
.
To keep let
and for
statementsif let
, and to enable the scenario exemplified by ParameterKind
in the motivation, these or-patterns are allowedlet
and for
statements.
In additionParameterKind
example, we can also considerslice.binary_search(&x)
. If we are only interested in the index
at where x
is or would be, without any regard for if it was there or not, we can now simply write:
and we will get back the index
in any case and continue on from there.
Guide-level explanation
RFC 2005, in describing|
in them as "or" patterns. This RFC adopts the same terminology.
While the "sum" of all patterns in match
must be irrefutable, or in other words: cover all cases, be exhaustive, this is not the case (currently) with if/while let
, which may have a refutable pattern. This RFC does not change this.
The RFC only extendsmatch
es to if let
and while let
expressionslet
and for
statements.
For examples, see motivation.
Reference-level explanation
Grammar文法
if let
The grammar
if_let_expr : "if" "let" pat '=' expr '{' block '}'
else_tail ? ;
to:
if_let_expr : "if" "let" '|'? pat [ '|' pat ] * '=' expr '{' block '}'
else_tail ? ;
while let
The grammar
while_let_expr : [ lifetime ':' ] ? "while" "let" pat '=' expr '{' block '}' ;
to:
while_let_expr : [ lifetime ':' ] ? "while" "let" '|'? pat [ '|' pat ] * '=' expr '{' block '}' ;
for
The expr_for
grammar
expr_for : maybe_label FOR pat IN expr_nostruct block ;
to:
expr_for : maybe_label FOR '|'? pat ('|' pat)* IN expr_nostruct block ;
let
statements文
The statementstmt
grammar
stmt ::= old_stmt_grammar
| let_stmt_many
;
let_stmt_many ::= "let" pat_two_plus "=" expr ";"
pat_two_plus ::= '|'? pat [ '|' pat ] + ;
Syntax文法 lowering下方の、小文字の
The changes proposed in this RFC with respect to if let
, while let
, and for
can be implementedif/while let
constructsmatch
and loop
+ match
expressions.
Meanwhile, let
statementsmatch
as described
Examples, if let
These examples are extensions on the if let
RFC. Therefore, the RFC avoids
Source:
Result:
Source:
Result:
Source:
Result:
Source
Result:
Examples, while let
The following example is an extension on the while let
RFC.
Source
Result:
Examples, for
Assuming that the semantics of for
is defined
into:
then the only thing that changes is that PAT
may include |
at the top level in the for
loop and the desugaring as per the section
Desugaring let
statements文 with |
in the top-level pattern
There continues to be an exhaustivity check in let
statements,
This is a possible desugaring that a Rust compiler may do. While such a compiler may elect to implement
Source:
Result
For example, the following code:
can be desugared to
It can also be desugared to:
(Both are equivalent)
Drawbacks
This adds more additions
Rationale and alternatives代わりのもの、選択肢
This could simply not be done. Consistency with match
is however on its own reason enough to do this.
It could be claimed that the if/while let
RFCs already mandate this RFC, this RFC does answer that question and instead simply mandates it now.
Another alternativeif/while let
expressionslet
and for
statements.
Unresolved questions
The exact syntax
There are no unresolved questions.