From eebfbf78e7307116b4cbd8ddcecc7ea8be3be6d8 Mon Sep 17 00:00:00 2001 From: mdinger Date: Thu, 23 Feb 2017 20:37:05 -0500 Subject: [PATCH 01/12] Allow an optional vert at the beginning of a match branch --- text/0000-optional-match-vert.md | 339 +++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 text/0000-optional-match-vert.md diff --git a/text/0000-optional-match-vert.md b/text/0000-optional-match-vert.md new file mode 100644 index 00000000000..312ead1091e --- /dev/null +++ b/text/0000-optional-match-vert.md @@ -0,0 +1,339 @@ +- Feature Name: `match_vert_prefix +- Start Date: 2017-02-23 +- RFC PR: (leave this empty) +- Rust Issue: (leave this empty) + +# Summary +[summary]: #summary + +See how in the following, all the `|` bars are mostly aligned except the last one: + +```rust + +use E::*; + +enum E { + A, + B, + C, + D, +} + +fn main() { + match A { + A | + B | + C | + D => (), + } +} +``` + +I'd propose it be allowed at the beginning of the pattern as well enabling something like this: + +```rust +use E::*; + +enum E { + A, + B, + C, + D, +} + +fn main() { + match A { + | A + | B + | C + | D => (), + } +} +``` + +# Motivation +[motivation]: #motivation + +This is taking a feature which is nice about `F#` and allowing it by a straightforward +extension of the current rust language. + +Also, this appears to be the official style for F# matches and it has grown on me a lot. +It highlights the matches and doesn't require as much deeper nesting. After getting used to the +F# style, the inability to do this is rust seems a bit limiting. + +## F# Context + +In `F#`, enumerations (called `unions`) are declared in the following fashion where +all of these are equivalent: + +```F# +// Normal union +type IntOrBool = I of int | B of bool +// For consistency, have all lines look the same +type IntOrBool = + | I of int + | B of bool +// Collapsing onto a single line is allowed +type IntOrBool = | I of int | B of bool +``` + +Their `match` statements adopt a similar style to this: + +```F# +match foo with +| I -> "" +| B -> "" +``` + +In Rust, these would look like this: + +```rust +enum IntOrBool { + I(i32), + B(bool), +} + +// Currently a preceding vert is disallowed +match foo { +| I => "", +| B => "", +} +``` +The appealing feature about this is that this style allows `match` semantics without +requiring the double nesting of a typical `match`. + +## Example A + +All of these matches are equivalent. + +```rust +enum E { + A, + B, + C, + D, +} + +fn main() { + match A { + A | B => println!("Give me A | B!"), + C | D => println!("Give me C | D!"), + } + + match A { + | A | B => println!("Give me A | B!"), + | C | D => println!("Give me C | D!"), + } + + match A { + | A + | B => println!("Give me A | B!"), + | C + | D => println!("Give me C | D!"), + } + + match A { + A | B => + println!("Give me A | B!"), + C | D => + println!("Give me C | D!"), + } +} +``` + +## Example B + +```rust +enum E { A, B, C } + +fn main() { + use E::*; + let value = A; + + match value { + | A + | B => {}, + C => {} +// ^ Could be interpreted as slightly inconsistent. Nevertheless, it doesn't +// seem like something to be concerned about. + } +} +``` + +## Example C + +A more thorough example is included below. Note how the bottom example how at most, +only tabs in twice from the start of the match. In contrast, the top tabs in four times. + +```rust +struct FavoriteBook { + author: &'static str, + title: &'static str, + date: u64 +} + +// Full name and surname. +enum Franks { Alice, Brenda, Charles, Dave, Steve } +enum Sawyer { Tom, Sid, May } + +enum Name { + Franks(Franks), + Sawyer(Sawyer), +} + +fn main() { + let name = Name::Sawyer(Sawyer::Tom); + + // Here is the first match in a typical rust style + match name { + Name::Franks(name) => + match name { + Franks::Alice | + Franks::Brenda | + Franks::Dave => FavoriteBook { + author: "alice berkley", + title: "Name of a popular book", + date: 1982, + }, + Franks::Charles | + Franks::Steve => FavoriteBook { + author: "fred marko", + title: "We'll use a different name here", + date: 1960, + }, + }, + Name::Sawyer(name) => + match name { + Sawyer::Tom => FavoriteBook { + author: "another name", + title: "Again we change it", + date: 1999, + }, + Sawyer::Sid | + Sawyer::May => FavoriteBook { + author: "again another name", + title: "here is a different title", + date: 1972, + }, + } + }; + + // An alternate rust style might look something like this: + match name { + | Name::Franks(name) => + match name { + | Franks::Alice + | Franks::Brenda + | Franks::Dave => FavoriteBook { + author: "alice berkley", + title: "Name of a popular book", + date: 1982 + }, + | Franks::Charles + | Franks::Steve => FavoriteBook { + author: "fred marko", + title: "We'll use a different name here", + date: 1960 + }, + } + | Name::Sawyer(name) => + match name { + | Sawyer::Tom => FavoriteBook { + author: "another name", + title: "Again we change it", + date: 1999 + }, + | Sawyer::Sid + | Sawyer::May => FavoriteBook { + author: "again another name", + title: "here is a different title", + date: 1972 + }, + } + }; +} +``` + + +# Detailed design +[design]: #detailed-design + +Unknown + +# How We Teach This +[how-we-teach-this]: #how-we-teach-this + +Adding examples for this are straightforward. You just include an example pointing out that +leading verts are allowed. That style could also be shown as well if desired. Simple +examples such as below should be easy to add to all different resources. + +```rust +enum Cat { + Burmese, + Munchkin, + Siamese, +} + +enum Dog { + Dachshund, + Poodle, + PitBull, +} + +fn main() { + let cat = Cat::MunchKin; + let dog = Dog::Poodle; + + match cat { + Cat::Burmese => "Burmese", + // Can do alternatives with a `|`. + Cat::MunchKin | Cat::Siamese => "Not burmese", + } + + match dog { + | Dog::Dachshund => "Dachshund", + // Leading `|` is allowed. + | Dog::Poodle + | Dog::PitBull => "Not a dachshund", + } +} +``` + +# Drawbacks +[drawbacks]: #drawbacks + +Nesting braces without nesting gets a little weird. This doesn't seem problematic but +stylistically, it might just seem quirky. `F#` doesn't have this problem because they use +whitespace for nesting I believe. + +```rust +struct S {msg: &'static str } +enum E { A, B, C } + +fn main() { + let e = E::A; + + match e { + | E::A => S { + msg: "A", + }, + | E::B => S { + msg: "B", + }, + | E::C => S { + msg: "C", + }, + } +// ^ Braces all hit the same level. +// This example may seem trivial but example c also showcased the exact same thing. +``` + +# Alternatives +[alternatives]: #alternatives + +N/A + +# Unresolved questions +[unresolved]: #unresolved-questions + +N/A From 17672dc0dcd24efcae52730a8c56bf5f29362822 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sat, 25 Feb 2017 22:24:50 -0500 Subject: [PATCH 02/12] Extend comments about example B slightly --- text/0000-optional-match-vert.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/text/0000-optional-match-vert.md b/text/0000-optional-match-vert.md index 312ead1091e..96a71ef76f4 100644 --- a/text/0000-optional-match-vert.md +++ b/text/0000-optional-match-vert.md @@ -150,12 +150,22 @@ fn main() { use E::*; let value = A; + + match value { + | A + | B => {}, + | C => {} +// ^ Following the style above, a `|` could be placed before the first +// element of every branch. + + match value { | A | B => {}, C => {} -// ^ Could be interpreted as slightly inconsistent. Nevertheless, it doesn't -// seem like something to be concerned about. +// ^ Including a `|` for the `A` but not for the `C` seems inconsistent +// but hardly invalid. Branches *always* follow the `=>`. Not something +// to be greatly concerned about. } } ``` From 95ae4041ef8302af85a3c7a4892a33773bc42f87 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sat, 25 Feb 2017 22:26:05 -0500 Subject: [PATCH 03/12] Add some information about how the grammar should be updated --- text/0000-optional-match-vert.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/text/0000-optional-match-vert.md b/text/0000-optional-match-vert.md index 96a71ef76f4..b3d7fe4cf8a 100644 --- a/text/0000-optional-match-vert.md +++ b/text/0000-optional-match-vert.md @@ -268,7 +268,16 @@ fn main() { # Detailed design [design]: #detailed-design -Unknown +I don't know about the implementation but the grammar could be updated so that +an optional `|` is allowed at the beginning. Nothing else in the grammar should +need updating. + +```text +// Before +match_pat : pat [ '|' pat ] * [ "if" expr ] ? ; +// After +match_pat : '|' ? pat [ '|' pat ] * [ "if" expr ] ? ; +``` # How We Teach This [how-we-teach-this]: #how-we-teach-this From 0bba3c0a4a9f117d556d99d3a17b9d23b946c229 Mon Sep 17 00:00:00 2001 From: mdinger Date: Sat, 25 Feb 2017 22:29:43 -0500 Subject: [PATCH 04/12] Trim whitespace --- text/0000-optional-match-vert.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/text/0000-optional-match-vert.md b/text/0000-optional-match-vert.md index b3d7fe4cf8a..85e7600e3e0 100644 --- a/text/0000-optional-match-vert.md +++ b/text/0000-optional-match-vert.md @@ -150,7 +150,6 @@ fn main() { use E::*; let value = A; - match value { | A | B => {}, @@ -158,7 +157,6 @@ fn main() { // ^ Following the style above, a `|` could be placed before the first // element of every branch. - match value { | A | B => {}, From 23957e9933e912b5589cab3806b8c89040e6bacc Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 17 Mar 2017 18:59:05 -0400 Subject: [PATCH 05/12] Rewrite to avoid styling topic --- text/0000-optional-match-vert.md | 354 ++++++++++++------------------- 1 file changed, 141 insertions(+), 213 deletions(-) diff --git a/text/0000-optional-match-vert.md b/text/0000-optional-match-vert.md index 85e7600e3e0..449f15437a2 100644 --- a/text/0000-optional-match-vert.md +++ b/text/0000-optional-match-vert.md @@ -6,47 +6,24 @@ # Summary [summary]: #summary -See how in the following, all the `|` bars are mostly aligned except the last one: +This is a proposal for the rust grammar to support verts `|` *both* +at the beginning of the pattern and at the end. Consider the following +example: ```rust - use E::*; -enum E { - A, - B, - C, - D, -} +enum E { A, B, C, D } fn main() { - match A { - A | - B | - C | - D => (), + // This is valid Rust + match foo { + A | B | C | D => (), } -} -``` - -I'd propose it be allowed at the beginning of the pattern as well enabling something like this: - -```rust -use E::*; -enum E { - A, - B, - C, - D, -} - -fn main() { - match A { - | A - | B - | C - | D => (), + // This is an example of what this proposal should allow. + match foo { + | A | B | C | D | => (), } } ``` @@ -54,14 +31,12 @@ fn main() { # Motivation [motivation]: #motivation -This is taking a feature which is nice about `F#` and allowing it by a straightforward -extension of the current rust language. +This is taking a feature which is nice about `F#` and allowing it by a +straightforward extension of the current rust language. After having used +this in `F#`, it seems limiting to not even support this at the language +level. -Also, this appears to be the official style for F# matches and it has grown on me a lot. -It highlights the matches and doesn't require as much deeper nesting. After getting used to the -F# style, the inability to do this is rust seems a bit limiting. - -## F# Context +## `F#` Context In `F#`, enumerations (called `unions`) are declared in the following fashion where all of these are equivalent: @@ -77,192 +52,169 @@ type IntOrBool = type IntOrBool = | I of int | B of bool ``` -Their `match` statements adopt a similar style to this: +Their `match` statements adopt a similar style to this. Note that every `|` is aligned, +something which is not possible with current Rust: ```F# match foo with -| I -> "" -| B -> "" + | I -> "" + | B -> "" ``` -In Rust, these would look like this: +## Maximizing `|` alignment + +In Rust, about the best we can do is align via the trailing edge: ```rust -enum IntOrBool { - I(i32), - B(bool), +use E::*; + +enum E { A, B, C, D } + +fn main() { + match foo { + A | + B | + C | + D => (), + // ^ Inconsistently missing a `|` + } } +``` + +Allowing this proposal would allow this example to take one of the following forms: + +```rust +use E::*; + +enum E { A, B, C, D } + +fn main() { + match foo { + A | + B | + C | + D | => (), + // ^ Gained consistency by having a vert. + } -// Currently a preceding vert is disallowed -match foo { -| I => "", -| B => "", + match foo { + | A + | B + | C + | D => (), + // ^ Gained *both* an alternative style and consistency. + } } ``` -The appealing feature about this is that this style allows `match` semantics without -requiring the double nesting of a typical `match`. -## Example A +## Flexibility in single line matches -All of these matches are equivalent. +It would allow these examples which are all equivalent: ```rust -enum E { - A, - B, - C, - D, -} +use E::*; + +enum E { A, B, C, D } fn main() { - match A { - A | B => println!("Give me A | B!"), - C | D => println!("Give me C | D!"), + // Only trailing `|`. + match foo { + A | B | C | D | => (), } - match A { - | A | B => println!("Give me A | B!"), - | C | D => println!("Give me C | D!"), + // Only preceding `|`. + match foo { + | A | B | C | D => (), } - match A { - | A - | B => println!("Give me A | B!"), - | C - | D => println!("Give me C | D!"), + // Both preceding and trailing `|`. + match foo { + | A | B | C | D | => (), } - match A { - A | B => - println!("Give me A | B!"), - C | D => - println!("Give me C | D!"), + // Neither preceding nor trailing `|`. + match foo { + A | B | C | D => (), } } ``` -## Example B +> There should be no ambiguity about what each of these mean. Preference +between these should just come down to a choice of style. + +## Benefits to macros + +This benefits macros. Needs filling in. + +## Multiple branches + +All of these matches are equivalent, each written in a different style: ```rust -enum E { A, B, C } +use E::*; + +enum E { A, B, C, D } fn main() { - use E::*; - let value = A; + match foo { + A | B => println!("Give me A | B!"), + C | D => println!("Give me C | D!"), + } - match value { - | A - | B => {}, - | C => {} -// ^ Following the style above, a `|` could be placed before the first -// element of every branch. + match foo { + | A | B => println!("Give me A | B!"), + | C | D => println!("Give me C | D!"), + } - match value { - | A - | B => {}, - C => {} -// ^ Including a `|` for the `A` but not for the `C` seems inconsistent -// but hardly invalid. Branches *always* follow the `=>`. Not something -// to be greatly concerned about. + match foo { + | A + | B => println!("Give me A | B!"), + | C + | D => println!("Give me C | D!"), + } + + match foo { + A | B => + println!("Give me A | B!"), + C | D => + println!("Give me C | D!"), + } + + match foo { + A | + B | => println!("Give me A | B!"), + C | + D | => println!("Give me C | D!"), } } ``` -## Example C - -A more thorough example is included below. Note how the bottom example how at most, -only tabs in twice from the start of the match. In contrast, the top tabs in four times. +## Comparing misalignment ```rust -struct FavoriteBook { - author: &'static str, - title: &'static str, - date: u64 -} - -// Full name and surname. -enum Franks { Alice, Brenda, Charles, Dave, Steve } -enum Sawyer { Tom, Sid, May } +use E::*; -enum Name { - Franks(Franks), - Sawyer(Sawyer), -} +enum E { A, B, C } fn main() { - let name = Name::Sawyer(Sawyer::Tom); - - // Here is the first match in a typical rust style - match name { - Name::Franks(name) => - match name { - Franks::Alice | - Franks::Brenda | - Franks::Dave => FavoriteBook { - author: "alice berkley", - title: "Name of a popular book", - date: 1982, - }, - Franks::Charles | - Franks::Steve => FavoriteBook { - author: "fred marko", - title: "We'll use a different name here", - date: 1960, - }, - }, - Name::Sawyer(name) => - match name { - Sawyer::Tom => FavoriteBook { - author: "another name", - title: "Again we change it", - date: 1999, - }, - Sawyer::Sid | - Sawyer::May => FavoriteBook { - author: "again another name", - title: "here is a different title", - date: 1972, - }, - } - }; - - // An alternate rust style might look something like this: - match name { - | Name::Franks(name) => - match name { - | Franks::Alice - | Franks::Brenda - | Franks::Dave => FavoriteBook { - author: "alice berkley", - title: "Name of a popular book", - date: 1982 - }, - | Franks::Charles - | Franks::Steve => FavoriteBook { - author: "fred marko", - title: "We'll use a different name here", - date: 1960 - }, - } - | Name::Sawyer(name) => - match name { - | Sawyer::Tom => FavoriteBook { - author: "another name", - title: "Again we change it", - date: 1999 - }, - | Sawyer::Sid - | Sawyer::May => FavoriteBook { - author: "again another name", - title: "here is a different title", - date: 1972 - }, - } - }; + match foo { + | A + | B => {}, + | C => {} + // ^ Following the style above, a `|` could be placed before the first + // element of every branch. + + match value { + | A + | B => {}, + C => {} + // ^ Including a `|` for the `A` but not for the `C` seems inconsistent + // but hardly invalid. Branches *always* follow the `=>`. Not something + // a *grammar* should be greatly concerned about. + } } ``` - # Detailed design [design]: #detailed-design @@ -280,9 +232,9 @@ match_pat : '|' ? pat [ '|' pat ] * [ "if" expr ] ? ; # How We Teach This [how-we-teach-this]: #how-we-teach-this -Adding examples for this are straightforward. You just include an example pointing out that -leading verts are allowed. That style could also be shown as well if desired. Simple -examples such as below should be easy to add to all different resources. +Adding examples for this are straightforward. You just include an example pointing +out that leading verts are allowed. Simple examples such as below should be easy to +add to all different resources. ```rust enum Cat { @@ -308,10 +260,10 @@ fn main() { } match dog { - | Dog::Dachshund => "Dachshund", - // Leading `|` is allowed. - | Dog::Poodle - | Dog::PitBull => "Not a dachshund", + | Dog::Dachshund => "Dachshund", + // Leading `|` is allowed. + | Dog::Poodle + | Dog::PitBull => "Not a dachshund", } } ``` @@ -319,31 +271,7 @@ fn main() { # Drawbacks [drawbacks]: #drawbacks -Nesting braces without nesting gets a little weird. This doesn't seem problematic but -stylistically, it might just seem quirky. `F#` doesn't have this problem because they use -whitespace for nesting I believe. - -```rust -struct S {msg: &'static str } -enum E { A, B, C } - -fn main() { - let e = E::A; - - match e { - | E::A => S { - msg: "A", - }, - | E::B => S { - msg: "B", - }, - | E::C => S { - msg: "C", - }, - } -// ^ Braces all hit the same level. -// This example may seem trivial but example c also showcased the exact same thing. -``` +N/A # Alternatives [alternatives]: #alternatives From 548f6ef09ddedeff6b1936d342aa5b6bb22da670 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 17 Mar 2017 19:10:00 -0400 Subject: [PATCH 06/12] Remove extraneous mains. Add the trailing vert to the grammar --- text/0000-optional-match-vert.md | 174 ++++++++++++++----------------- 1 file changed, 81 insertions(+), 93 deletions(-) diff --git a/text/0000-optional-match-vert.md b/text/0000-optional-match-vert.md index 449f15437a2..0d9048f8c5a 100644 --- a/text/0000-optional-match-vert.md +++ b/text/0000-optional-match-vert.md @@ -15,16 +15,14 @@ use E::*; enum E { A, B, C, D } -fn main() { - // This is valid Rust - match foo { - A | B | C | D => (), - } +// This is valid Rust +match foo { + A | B | C | D => (), +} - // This is an example of what this proposal should allow. - match foo { - | A | B | C | D | => (), - } +// This is an example of what this proposal should allow. +match foo { + | A | B | C | D | => (), } ``` @@ -70,14 +68,12 @@ use E::*; enum E { A, B, C, D } -fn main() { - match foo { - A | - B | - C | - D => (), - // ^ Inconsistently missing a `|` - } +match foo { + A | + B | + C | + D => (), +// ^ Inconsistently missing a `|` } ``` @@ -88,22 +84,20 @@ use E::*; enum E { A, B, C, D } -fn main() { - match foo { - A | - B | - C | - D | => (), - // ^ Gained consistency by having a vert. - } +match foo { + A | + B | + C | + D | => (), +// ^ Gained consistency by having a vert. +} - match foo { - | A - | B - | C - | D => (), - // ^ Gained *both* an alternative style and consistency. - } +match foo { + | A + | B + | C + | D => (), +// ^ Gained *both* an alternative style and consistency. } ``` @@ -116,26 +110,24 @@ use E::*; enum E { A, B, C, D } -fn main() { - // Only trailing `|`. - match foo { - A | B | C | D | => (), - } +// Only trailing `|`. +match foo { + A | B | C | D | => (), +} - // Only preceding `|`. - match foo { - | A | B | C | D => (), - } +// Only preceding `|`. +match foo { + | A | B | C | D => (), +} - // Both preceding and trailing `|`. - match foo { - | A | B | C | D | => (), - } +// Both preceding and trailing `|`. +match foo { + | A | B | C | D | => (), +} - // Neither preceding nor trailing `|`. - match foo { - A | B | C | D => (), - } +// Neither preceding nor trailing `|`. +match foo { + A | B | C | D => (), } ``` @@ -155,37 +147,35 @@ use E::*; enum E { A, B, C, D } -fn main() { - match foo { - A | B => println!("Give me A | B!"), - C | D => println!("Give me C | D!"), - } +match foo { + A | B => println!("Give me A | B!"), + C | D => println!("Give me C | D!"), +} - match foo { - | A | B => println!("Give me A | B!"), - | C | D => println!("Give me C | D!"), - } +match foo { + | A | B => println!("Give me A | B!"), + | C | D => println!("Give me C | D!"), +} - match foo { - | A - | B => println!("Give me A | B!"), - | C - | D => println!("Give me C | D!"), - } +match foo { + | A + | B => println!("Give me A | B!"), + | C + | D => println!("Give me C | D!"), +} - match foo { - A | B => - println!("Give me A | B!"), - C | D => - println!("Give me C | D!"), - } +match foo { + A | B => + println!("Give me A | B!"), + C | D => + println!("Give me C | D!"), +} - match foo { - A | - B | => println!("Give me A | B!"), - C | - D | => println!("Give me C | D!"), - } +match foo { + A | + B | => println!("Give me A | B!"), + C | + D | => println!("Give me C | D!"), } ``` @@ -196,22 +186,20 @@ use E::*; enum E { A, B, C } -fn main() { - match foo { - | A - | B => {}, - | C => {} - // ^ Following the style above, a `|` could be placed before the first - // element of every branch. - - match value { - | A - | B => {}, - C => {} - // ^ Including a `|` for the `A` but not for the `C` seems inconsistent - // but hardly invalid. Branches *always* follow the `=>`. Not something - // a *grammar* should be greatly concerned about. - } +match foo { + | A + | B => {}, + | C => {} +// ^ Following the style above, a `|` could be placed before the first +// element of every branch. + +match value { + | A + | B => {}, + C => {} +// ^ Including a `|` for the `A` but not for the `C` seems inconsistent +// but hardly invalid. Branches *always* follow the `=>`. Not something +// a *grammar* should be greatly concerned about. } ``` @@ -226,7 +214,7 @@ need updating. // Before match_pat : pat [ '|' pat ] * [ "if" expr ] ? ; // After -match_pat : '|' ? pat [ '|' pat ] * [ "if" expr ] ? ; +match_pat : '|' ? pat [ '|' pat ] * '|' ? [ "if" expr ] ? ; ``` # How We Teach This From 6a30871628543ceaafc64da8fb8ad3071f1e49a4 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 17 Mar 2017 19:17:53 -0400 Subject: [PATCH 07/12] Improve minor inconsistencies --- text/0000-optional-match-vert.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/text/0000-optional-match-vert.md b/text/0000-optional-match-vert.md index 0d9048f8c5a..255c04ae58d 100644 --- a/text/0000-optional-match-vert.md +++ b/text/0000-optional-match-vert.md @@ -61,7 +61,7 @@ match foo with ## Maximizing `|` alignment -In Rust, about the best we can do is align via the trailing edge: +In Rust, about the best we can do is an inconsistent alignment: ```rust use E::*; @@ -75,6 +75,15 @@ match foo { D => (), // ^ Inconsistently missing a `|` } + +match foo { +// | +// V Inconsistently missing a `|`. + A + | B + | C + | D => (), +} ``` Allowing this proposal would allow this example to take one of the following forms: @@ -97,7 +106,7 @@ match foo { | B | C | D => (), -// ^ Gained *both* an alternative style and consistency. +// ^ Also gained consistency. } ``` @@ -207,8 +216,8 @@ match value { [design]: #detailed-design I don't know about the implementation but the grammar could be updated so that -an optional `|` is allowed at the beginning. Nothing else in the grammar should -need updating. +an optional `|` is allowed at the beginning and the end. Nothing else in the +grammar should need updating. ```text // Before From ed12656391b2c9fb80de1344bd2098b01eb4b042 Mon Sep 17 00:00:00 2001 From: mdinger Date: Fri, 17 Mar 2017 19:27:22 -0400 Subject: [PATCH 08/12] Update the teaching example for trailing verts --- text/0000-optional-match-vert.md | 53 ++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/text/0000-optional-match-vert.md b/text/0000-optional-match-vert.md index 255c04ae58d..1e390970d3e 100644 --- a/text/0000-optional-match-vert.md +++ b/text/0000-optional-match-vert.md @@ -230,37 +230,50 @@ match_pat : '|' ? pat [ '|' pat ] * '|' ? [ "if" expr ] ? ; [how-we-teach-this]: #how-we-teach-this Adding examples for this are straightforward. You just include an example pointing -out that leading verts are allowed. Simple examples such as below should be easy to -add to all different resources. +out that leading and trailing verts are allowed. Simple examples such as below should +be easy to add to all different resources. ```rust -enum Cat { - Burmese, - Munchkin, - Siamese, -} +use Letter::*; -enum Dog { - Dachshund, - Poodle, - PitBull, +enum Letter { + A, + B, + C, + D, } fn main() { - let cat = Cat::MunchKin; - let dog = Dog::Poodle; + let a = Letter::A; + let b = Letter::B; + let c = Letter::C; + let d = Letter::D; - match cat { - Cat::Burmese => "Burmese", + match a { + A => "A", // Can do alternatives with a `|`. - Cat::MunchKin | Cat::Siamese => "Not burmese", + B | C | D => "B, C, or D", } - match dog { - | Dog::Dachshund => "Dachshund", + match b { + | A => "A", // Leading `|` is allowed. - | Dog::Poodle - | Dog::PitBull => "Not a dachshund", + | B + | C + | D => "B, C, or D", + } + + match c { + A | => "A", + // Trailing `|` is allowed. + B | + C | + D | => "B, C, or D", + } + + match d { + // Both are allowed. + | A | B | C | D | => "Got a letter", } } ``` From d75cf5e0ecd1ff94139567278777e6a8a2fb9adb Mon Sep 17 00:00:00 2001 From: Matthew Dinger Date: Thu, 15 Jun 2017 20:29:23 -0400 Subject: [PATCH 09/12] Remove trailing vert inclusion --- text/0000-optional-match-vert.md | 81 +++++++++----------------------- 1 file changed, 22 insertions(+), 59 deletions(-) diff --git a/text/0000-optional-match-vert.md b/text/0000-optional-match-vert.md index 1e390970d3e..bb89f939839 100644 --- a/text/0000-optional-match-vert.md +++ b/text/0000-optional-match-vert.md @@ -6,9 +6,8 @@ # Summary [summary]: #summary -This is a proposal for the rust grammar to support verts `|` *both* -at the beginning of the pattern and at the end. Consider the following -example: +This is a proposal for the rust grammar to support a vert `|` at the +beginning of the pattern. Consider the following example: ```rust use E::*; @@ -22,7 +21,7 @@ match foo { // This is an example of what this proposal should allow. match foo { - | A | B | C | D | => (), + | A | B | C | D => (), } ``` @@ -61,21 +60,14 @@ match foo with ## Maximizing `|` alignment -In Rust, about the best we can do is an inconsistent alignment: +In Rust, about the best we can do is an inconsistent alignment with one of the +following two options: ```rust use E::*; enum E { A, B, C, D } -match foo { - A | - B | - C | - D => (), -// ^ Inconsistently missing a `|` -} - match foo { // | // V Inconsistently missing a `|`. @@ -84,29 +76,30 @@ match foo { | C | D => (), } + +match foo { + A | + B | + C | + D => (), +// ^ Also inconsistent but since this is the last in the sequence, not having +// | a followup vert could be considered sensible given that no more follow. +} ``` -Allowing this proposal would allow this example to take one of the following forms: +This proposal would allow the example to have the following form: ```rust use E::*; enum E { A, B, C, D } -match foo { - A | - B | - C | - D | => (), -// ^ Gained consistency by having a vert. -} - match foo { | A | B | C | D => (), -// ^ Also gained consistency. +// ^ Gained consistency by having a matching vert. } ``` @@ -119,28 +112,18 @@ use E::*; enum E { A, B, C, D } -// Only trailing `|`. -match foo { - A | B | C | D | => (), -} - -// Only preceding `|`. +// A preceding vert match foo { | A | B | C | D => (), } -// Both preceding and trailing `|`. -match foo { - | A | B | C | D | => (), -} - -// Neither preceding nor trailing `|`. +// A match as is currently allowed match foo { A | B | C | D => (), } ``` -> There should be no ambiguity about what each of these mean. Preference +> There should be no ambiguity about what either of these means. Preference between these should just come down to a choice of style. ## Benefits to macros @@ -179,13 +162,6 @@ match foo { C | D => println!("Give me C | D!"), } - -match foo { - A | - B | => println!("Give me A | B!"), - C | - D | => println!("Give me C | D!"), -} ``` ## Comparing misalignment @@ -223,15 +199,15 @@ grammar should need updating. // Before match_pat : pat [ '|' pat ] * [ "if" expr ] ? ; // After -match_pat : '|' ? pat [ '|' pat ] * '|' ? [ "if" expr ] ? ; +match_pat : '|' ? pat [ '|' pat ] * [ "if" expr ] ? ; ``` # How We Teach This [how-we-teach-this]: #how-we-teach-this Adding examples for this are straightforward. You just include an example pointing -out that leading and trailing verts are allowed. Simple examples such as below should -be easy to add to all different resources. +out that leading verts are allowed. Simple examples such as below should be easy +to add to all different resources. ```rust use Letter::*; @@ -262,19 +238,6 @@ fn main() { | C | D => "B, C, or D", } - - match c { - A | => "A", - // Trailing `|` is allowed. - B | - C | - D | => "B, C, or D", - } - - match d { - // Both are allowed. - | A | B | C | D | => "Got a letter", - } } ``` From e3eda65ba26a1bfc9deab46bad126b86d45e838b Mon Sep 17 00:00:00 2001 From: Matthew Dinger Date: Fri, 16 Jun 2017 19:36:30 -0400 Subject: [PATCH 10/12] Trailing vert nit --- text/0000-optional-match-vert.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/0000-optional-match-vert.md b/text/0000-optional-match-vert.md index bb89f939839..fdfd7b303f4 100644 --- a/text/0000-optional-match-vert.md +++ b/text/0000-optional-match-vert.md @@ -192,8 +192,8 @@ match value { [design]: #detailed-design I don't know about the implementation but the grammar could be updated so that -an optional `|` is allowed at the beginning and the end. Nothing else in the -grammar should need updating. +an optional `|` is allowed at the beginning. Nothing else in the grammar should +need updating. ```text // Before From 3b052a6311cc52d2767790576a8d8ebe443ccd53 Mon Sep 17 00:00:00 2001 From: Matthew Dinger Date: Fri, 16 Jun 2017 19:37:30 -0400 Subject: [PATCH 11/12] Backtick nit --- text/0000-optional-match-vert.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-optional-match-vert.md b/text/0000-optional-match-vert.md index fdfd7b303f4..c766697e9ec 100644 --- a/text/0000-optional-match-vert.md +++ b/text/0000-optional-match-vert.md @@ -1,4 +1,4 @@ -- Feature Name: `match_vert_prefix +- Feature Name: `match_vert_prefix` - Start Date: 2017-02-23 - RFC PR: (leave this empty) - Rust Issue: (leave this empty) From e64560ced01ec78926cb8ed077e70cd042905be7 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Sat, 26 Aug 2017 11:25:20 -0700 Subject: [PATCH 12/12] RFC 1925: Allow an optional vert at the beginning of a match branch --- ...000-optional-match-vert.md => 1925-optional-match-vert.md} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename text/{0000-optional-match-vert.md => 1925-optional-match-vert.md} (97%) diff --git a/text/0000-optional-match-vert.md b/text/1925-optional-match-vert.md similarity index 97% rename from text/0000-optional-match-vert.md rename to text/1925-optional-match-vert.md index c766697e9ec..23946f96c60 100644 --- a/text/0000-optional-match-vert.md +++ b/text/1925-optional-match-vert.md @@ -1,7 +1,7 @@ - Feature Name: `match_vert_prefix` - Start Date: 2017-02-23 -- RFC PR: (leave this empty) -- Rust Issue: (leave this empty) +- RFC PR: https://github.com/rust-lang/rfcs/pull/1925 +- Rust Issue: https://github.com/rust-lang/rust/issues/44101 # Summary [summary]: #summary