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

RFC: .. in patterns #1492

Merged
merged 2 commits into from
May 13, 2016
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
129 changes: 129 additions & 0 deletions text/0000-dotdot-in-patterns.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
- Feature Name: dotdot_in_patterns
- Start Date: 2016-02-06
- RFC PR: (leave this empty)
- Rust Issue: (leave this empty)

# Summary
[summary]: #summary

Permit the `..` pattern fragment in more contexts.

# Motivation
[motivation]: #motivation

The pattern fragment `..` can be used in some patterns to denote several elements in list contexts.
However, it doesn't always compiles when used in such contexts.
One can expect the ability to match tuple variants like `V(u8, u8, u8)` with patterns like
`V(x, ..)` or `V(.., z)`, but the compiler rejects such patterns currently despite accepting
very similar `V(..)`.

This RFC is intended to "complete" the feature and make it work in all possible list contexts,
making the language a bit more convenient and consistent.

# Detailed design
[design]: #detailed-design

Let's list all the patterns currently existing in the language, that contain lists of subpatterns:

```
// Struct patterns.
S { field1, field2, ..., fieldN }

// Tuple struct patterns.
S(field1, field2, ..., fieldN)

// Tuple patterns.
(field1, field2, ..., fieldN)

// Slice patterns.
[elem1, elem2, ..., elemN]
```
In all the patterns above, except for struct patterns, field/element positions are significant.

Now list all the contexts that currently permit the `..` pattern fragment:
```
// Struct patterns, the last position.
S { subpat1, subpat2, .. }

// Tuple struct patterns, the last and the only position, no extra subpatterns allowed.
S(..)

// Slice patterns, the last position.
[subpat1, subpat2, ..]
// Slice patterns, the first position.
[.., subpatN-1, subpatN]
// Slice patterns, any other position.
[subpat1, .., subpatN]
// Slice patterns, any of the above with a subslice binding.
// (The binding is not actually a binding, but one more pattern bound to the sublist, but this is
// not important for our discussion.)
[subpat1, binding.., subpatN]
```
Something is obviously missing, let's fill in the missing parts.

```
// Struct patterns, the last position.
S { subpat1, subpat2, .. }
// **NOT PROPOSED**: Struct patterns, any position.
// Since named struct fields are not positional, there's essentially no sense in placing the `..`
// anywhere except for one conventionally chosen position (the last one) or in sublist bindings,
// so we don't propose extensions to struct patterns.
S { subpat1, .., subpatN }
S { subpat1, binding.., subpatN }

// Tuple struct patterns, the last and the only position, no extra subpatterns allowed.
S(..)
// **NEW**: Tuple struct patterns, any position.
S(subpat1, subpat2, ..)
S(.., subpatN-1, subpatN)
S(subpat1, .., subpatN)
// **NEW**: Tuple struct patterns, any position with a sublist binding.
// The binding has a tuple type.
// By ref bindings are not allowed, because layouts of S(A, B, C, D) and (B, C) are not necessarily
// compatible (e.g. field reordering is possible).
S(subpat1, binding.., subpatN)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are somewhat problematic. Afaik there's no guarantee that (B, C) has the same memory layout as the last two parts of (A, B, C), so taking a slice into a tuple might not be so trivial.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this is an interesting observation.
It means that at least by ref bindings have to be restricted.
I'll update the RFC.


// **NEW**: Tuple patterns, any position.
(subpat1, subpat2, ..)
(.., subpatN-1, subpatN)
(subpat1, .., subpatN)
// **NEW**: Tuple patterns, any position with a sublist binding.
// The binding has a tuple type.
// By ref bindings are not allowed, because layouts of (A, B, C, D) and (B, C) are not necessarily
// compatible (e.g. field reordering is possible).
(subpat1, binding.., subpatN)

// Slice patterns, the last position.
[subpat1, subpat2, ..]
// Slice patterns, the first position.
[.., subpatN-1, subpatN]
// Slice patterns, any other position.
[subpat1, .., subpatN]
// Slice patterns, any of the above with a subslice binding.
// By ref bindings are allowed, slices and subslices always have compatible layouts.
[subpat1, binding.., subpatN]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this binding mean? This feels like it overlaps with slice patterns, which (I think) still require some further RFC to "complete"? I can't remember if we postponed that work or not. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this binding mean?

A subslice pattern, see above - "The binding is not actually a binding, but one more pattern ..."

```

Trailing comma is not allowed after `..` in the last position by analogy with existing slice and
struct patterns.

This RFC is not critically important and can be rolled out in parts, for example, bare `..` first,
`..` with a sublist binding eventually.

# Drawbacks
[drawbacks]: #drawbacks

None.

# Alternatives
[alternatives]: #alternatives

Do not permit sublist bindings in tuples and tuple structs at all.

# Unresolved questions
[unresolved]: #unresolved-questions

Sublist binding syntax conflicts with possible exclusive range patterns
`begin .. end`/`begin..`/`..end`. This problem already exists for slice patterns and has to be
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slice patterns are unstable (and buggy), and thus can easily be changed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extensions proposed in this RFC are going to be unstable too and are supposed to be changed together with slice patterns if changed at all.

solved independently from extensions to `..`.
This RFC simply selects the same syntax that slice patterns already have.