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

Guide - match #97

Merged
merged 1 commit into from
Nov 13, 2017
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
164 changes: 162 additions & 2 deletions guide/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Do not put a comma after the last argument.
foo(x, y, z)
```

### Methods
### Method calls

Follow the function rules for calling.

Expand All @@ -84,4 +84,164 @@ Put spaces before and after `as`:

```rust
let cstr = "Hi\0" as *const str as *const [u8] as *const std::os::raw::c_char;
```
```


### Match

Prefer not to line-break inside the discriminant expression. There must always
be a line break after the opening brace and before the closing brace. The match
arms must be block indented once:

```rust
match foo {
// arms
}

let x = match foo.bar.baz() {
// arms
};
```

Use a trailing comma for a match arm if and only if not using a block.

Avoid splitting the left-hand side (before the `=>`) of a match arm where
possible. If the right-hand side of the match arm is kept on the same line,
never use a block (unless the block is empty).

If the right-hand side consists of multiple statements or has line comments or
the start of the line cannot be fit on the same line as the left-hand side, use
a block.

The body of a block arm should be block indented once.

Examples:

```rust
match foo {
foo => bar,
a_very_long_patten | another_pattern if an_expression() => {
no_room_for_this_expression()
}
foo => {
// A comment.
an_expression()
}
foo => {
let a = statement();
an_expression()
}
bar => {}
// Trailing comma on last item.
foo => bar,
}
```

If the body is a single expression with no line comments is a *combinable

Choose a reason for hiding this comment

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

Do we use block for if, for, while, loop and match?

Copy link
Member Author

Choose a reason for hiding this comment

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

That will be defined in the 'combinable expressions' section which I intend to write later.

expression* (see below for details), then it may be started on the same line as
the right-hand side. If not, then it must be in a block. Example,

```rust
match foo {
// A combinable expression.
foo => a_function_call(another_call(
argument1,
argument2,
)),
// A non-combinable expression
bar => {
a_function_call(
another_call(
argument1,
argument2,
),
another_argument,
)
}
}
```

#### Line-breaking

Where it is possible to use a block form on the right-hand side and avoid
breaking the left-hand side, do that. E.g.

```rust
// Assuming the following line does done fit in the max width
a_very_long_pattern | another_pattern => ALongStructName {
...
},
// Prefer this
a_very_long_pattern | another_pattern => {
ALongStructName {
...
}
}
// To splitting the pattern.
```

Never break after `=>` without using the block form of the body.

If the left-hand side must be split and there is an `if` clause, break before
the `if` and block indent. In this case, always use a block body and start the
body on a new line:

```rust
a_very_long_pattern | another_pattern
if expr =>
{
...
}
```

If required to break the pattern, put each clause of the pattern on its own
line, breaking before the `|`. If there is an `if` clause, then you must use the
above form:

```rust
a_very_long_pattern
| another_pattern
| yet_another_pattern
| a_forth_pattern => {
...
}
a_very_long_pattern
| another_pattern
| yet_another_pattern
| a_forth_pattern
if expr =>
{
...
}
```

If every clause in a pattern is *small*, but does not fit on one line, then the
pattern may be formatted across multiple lines with as many clauses per line as
possible. Again break before a `|`:

```rust
foo | bar | baz
| qux => {
...
}
```

We define a pattern clause to be *small* if it matches the following grammar:

```
[small, ntp]:
- single token
- `&[single-line, ntp]`

[small]:
- `[small, ntp]`
- unary tuple constructor `([small, ntp])`
- `&[small]`
```

E.g., `&&Some(foo)` matches, `Foo(4, Bar)` does not.


### Combinable expressions

TODO (#61)