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

Mini-RFC: Make .. a pattern syntactically #2707

Merged
merged 2 commits into from
Jun 30, 2019
Merged
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
96 changes: 96 additions & 0 deletions text/2707-dotdot-patterns.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
- Feature Name: `dotdot_patterns`
- Start Date: 2019-06-01
- RFC PR: [rust-lang/rfcs#2707](https://github.com/rust-lang/rfcs/pull/2707)
- Rust Issue: [rust-lang/rust#62254](https://github.com/rust-lang/rust/issues/62254)

# Summary
[summary]: #summary

Make `..` a pattern rather than a syntactic fragment of some other patterns.

# Motivation
[motivation]: #motivation

The change simplifies pattern grammar and simplifies use of `..` in macros.
In particular, the `pat` macro matcher will now accept `..` and `IDENT @ ..`.

# Guide-level explanation
[guide-level-explanation]: #guide-level-explanation

`..` becomes a pattern syntacticaly.
The notable consequences of this are listed below.

- `pat` macro matcher will now accept `..` and more complex pattern containing `..`,
for example `ref x @ ..`.

- A trailing comma is accepted after `..` in tuple struct, tuple or slice pattern.
```rust
Variant(a, b, ..,) // OK
```

- Some nonsensical code can now be accepted under `cfg(FALSE)`.
```rust
#[cfg(FALSE)]
Tuple(.., a, ..) // OK
```

`..` in "inappropriate" positions is still rejected semantically.
```rust
let .. = 10; // Semantic error, `..` is not a part of a "list" pattern
let Option(.., ..) = 11; // Semantic error, multiple `..`s in a single "list" pattern
```

# Reference-level explanation
[reference-level-explanation]: #reference-level-explanation

Pattern grammar is extended with a new production
```
PAT = ..
```
Special productions allowing `..` in tuple struct, tuple and slice patterns are subsumed by this
new production and removed.

Semantically, the `..` pattern is accepted
- Immediately inside a tuple struct/variant pattern `Tuple(PAT, .., PAT)`
- Immediately inside a tuple pattern `(PAT, .., PAT)`
- Immediately inside a slice pattern `[PAT, .., PAT]`.
- Immediately inside a binding pattern inside a slice pattern `[PAT, BINDING @ .., PAT]`.

An error is produced if this pattern is used in any other position.

An error is produced if more that one `..` or `BINDING @ ..` pattern is used inside its containing
tuple struct / tuple / slice pattern.

`(..)` is still a tuple pattern and not a parenthesized `..` pattern for backward compatibility.

Note that `..` in struct patterns
```rust
Struct { field1: PAT, field2, .. }
```
is still not a pattern, but a fragment of a struct pattern syntax.

# Drawbacks
[drawbacks]: #drawbacks

More meaningless code may be accepted under `cfg(FALSE)` where semantic checks are not performed.

# Rationale and alternatives
[rationale-and-alternatives]: #rationale-and-alternatives

See "Motivation" for the rationale.
Status quo is always an alternative.

# Prior art
[prior-art]: #prior-art

This RFC is a follow up to https://github.com/rust-lang/rfcs/pull/2359.

# Unresolved questions
[unresolved-questions]: #unresolved-questions

None so far.

# Future possibilities
[future-possibilities]: #future-possibilities

Accept `BINDING @ ..` in tuple patterns, `(head, tail @ ..)`.