From 2cd24ce2565e5490b3e38e247130640e3ffe750e Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 6 Feb 2016 22:10:28 +0300 Subject: [PATCH 1/2] RFC: `..` in patterns --- text/0000-dotdot-in-patterns.md | 124 ++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 text/0000-dotdot-in-patterns.md diff --git a/text/0000-dotdot-in-patterns.md b/text/0000-dotdot-in-patterns.md new file mode 100644 index 00000000000..c6ae4bc9fa4 --- /dev/null +++ b/text/0000-dotdot-in-patterns.md @@ -0,0 +1,124 @@ +- 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. +S(subpat1, binding.., subpatN) + +// **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. +(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. +[subpat1, binding.., subpatN] +``` + +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 + +None. + +# 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 +solved independently from extensions to `..`. +This RFC simply selects the same syntax that slice patterns already have. From 4e9e8433bdf05927f24870f69216eed640707306 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 8 Feb 2016 21:06:40 +0300 Subject: [PATCH 2/2] Restrict sublist bindings in tuple and tuple struct patterns --- text/0000-dotdot-in-patterns.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/text/0000-dotdot-in-patterns.md b/text/0000-dotdot-in-patterns.md index c6ae4bc9fa4..954698d81a3 100644 --- a/text/0000-dotdot-in-patterns.md +++ b/text/0000-dotdot-in-patterns.md @@ -79,6 +79,8 @@ 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) // **NEW**: Tuple patterns, any position. @@ -87,6 +89,8 @@ S(subpat1, binding.., 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. @@ -96,6 +100,7 @@ S(subpat1, binding.., 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] ``` @@ -113,7 +118,7 @@ None. # Alternatives [alternatives]: #alternatives -None. +Do not permit sublist bindings in tuples and tuple structs at all. # Unresolved questions [unresolved]: #unresolved-questions