8000 eRFC: if- and while-let-chains, take 2 by Centril · Pull Request #2497 · rust-lang/rfcs · GitHub
[go: up one dir, main page]

Skip to content

eRFC: if- and while-let-chains, take 2 #2497

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

Merged
merged 15 commits into from
Aug 24, 2018
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
rfc, let_chains_2: be more clear in reference.
  • Loading branch information
Centril committed Jul 13, 2018
commit d9b2cef9b3e44698faeef6acee63c8666b222f0d
65 changes: 58 additions & 7 deletions text/0000-if-let-chains.md
Original file line number Diff line number Diff line change
Expand Up @@ -574,24 +574,75 @@ There exists an ambiguity in this new grammar in how to parse:
if let PAT = EXPR && EXPR { .. }
```

It can either be parsed as:
It can either be parsed as (1):

```rust
if let PAT = (EXPR && EXPR) { .. }
```

or instead as:
or instead as (2):

```rust
if (let PAT = EXPR) && EXPR { .. }
```

In the interest of succinctness, we do not encode a grammar here that
resolves this ambiguity. Nonetheless, the second interpretation is *always*
chosen. This means that the operator `&&` has the lowest precedence at the
top level of `if STUFF { .. }`. If the user wants to disambiguate,
they can write `(EXPR && EXPR)` or `{ EXPR && EXPR }` explicitly.
The same applies to `while` expressions.
resolves this ambiguity. Nonetheless, interpretation (2) is *always*
chosen.

[expression operator precedence]: https://github.com/rust-lang-nursery/reference/blob/master/src/expressions.md#expression-precedence

As specified in the reference in the section on [expression operator precedence],
the following operators all have a lower precedence than `&&`:

+ `||`
+ `..` and `..=`
+ `=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `|=`, `^=`, `<<=`, `>>=`
+ `return`, `break`

To be precise, the changes in this RFC entail that `||` has the lowest
precedence at the top level of `if STUFF { .. }`. The operator `&&`
has then the 2nd lowest precedence and binds more tightly than `||`.
If the user wants to disambiguate, they can write `(EXPR && EXPR)` or
`{ EXPR && EXPR }` explicitly. The same applies to `while` expressions.

#### A few more examples

Given:

```rust
if let Range { start: _, end: _ } = true..true && false { ... }

if let PAT = break true && false { ... }

if let PAT = F..|| false { ... }

if let PAT = t..&&false { ... }
```

it is currently interpreted as:

```rust
if let Range { start: _, end: _ } = true..(true && false) { ... }

if let PAT = break (true && false) { ... }

if let PAT = F..(|| false) { ... }

if let PAT = t..(&&false) { ... }
```

but will be interpreted as:

```rust
if (let Range { start: _, end: _ } = true..true) && false { ... }

if (let PAT = break true && false) { ... }

if (let PAT = F..) || false { ... }

if (let PAT = t..) && false { ... }
```

### Rollout Plan and Transitioning to Rust 2018

Expand Down
0