Summary
This is a proposal for the rust grammar to support a vert | at the
beginning of the pattern. Consider the following example:
use *;
// This is valid Rust
match foo
// This is an example of what this proposal should allow.
match foo
Motivation
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.
F# Context
In F#, enumerations (called unions) are declared in the following fashion where
all of these are equivalent:
// 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. Note that every | is aligned,
something which is not possible with current Rust:
match foo with
| I -> ""
| B -> ""
Maximizing | alignment
In Rust, about the best we can do is an inconsistent alignment with one of the following two options:
use *;
match foo
match foo
This proposal would allow the example to have the following form:
use *;
match foo
Flexibility in single line matches
It would allow these examples which are all equivalent:
use *;
// A preceding vert
match foo
// A match as is currently allowed
match foo
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
This benefits macros. Needs filling in.
Multiple branches
All of these matches are equivalent, each written in a different style:
use *;
match foo
match foo
match foo
match foo
Comparing misalignment
use *;
match foo
// ^ Following the style above, a `|` could be placed before the first
// element of every branch.
match value
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.
// Before
match_pat : pat [ '|' pat ] * [ "if" expr ] ? ;
// After
match_pat : '|' ? pat [ '|' pat ] * [ "if" expr ] ? ;
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.
use *;
Drawbacks
N/A
Alternatives
N/A
Unresolved questions
N/A