Skip to content
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

Allow use of pipe operator in patterns. #1882

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions text/0000-pipe-in-patterns.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
- Feature Name: pipe_in_patterns.
- Start Date: 2017-02-03
- RFC PR: (leave this empty)
- Rust Issue: (leave this empty)

## Summary
this RFC proposes allowing the `|` operator to be used within patterns to
allow for pattern matching with less boilerplate.

## Detailed Design
The current pattern matching is very powerful, however there is a lot of
boilerplate code needed to fully take advantage of it. Consider a
situation where you are building a state machine that is iterating through
`chars_indices`, and when you see `' '`, `'\n'`, `'\r'` or `'\f'`, you
want to change the state. Currently your match statement would look something
like the following example. There is no great way of reducing that boilerplate,
if anything that boilerplate only grows worse as you have more cases, and bigger
tuples. Conservatively this feature would be simple syntactic sugar that just
expands to the old syntax.

```rust
match iter.next() {
Some(_, ' ') | Some(_, '\n') | Some(_, '\r') | Some(_, '\u{21A1}') => {
// Change state
}
Some(index, ch) => {
// Look at char
}
None => return Err(Eof),
}
```

The solution to this would be to allow for `|` to be used within patterns. This
will significantly reduce how much boilerplate is required to have conditional
matches with tuples.

```rust
match iter.next() {
Some(_, ' ' | '\n' | '\r' | '\u{21A1}') => {
// Change state
}
Some(index, ch) => {
// Look at char
}
None => return Err(Eof),
}
```
In terms of Rust's grammar `pats_or` would probably be changed to the following.
Which should allow for `Some(1 | 2 | 3, ' ' | '\n' | '\r')`.

```yacc
pats_or
: pat { $$ = mk_node("Pats", 1, $1); }
| pat '|' pat { $$ = ext_node($1, 1, $3); }
;
```

## How We Teach This
I think all that would be required is additional examples in sections on
pattern matching. The syntax is very intuitive.

## Drawbacks
None that I can think of.

## Alternatives
Keep syntax as is.

## Unresolved Questions
None at the moment.