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

Add let else statements #165

Closed
wants to merge 2 commits into from
Closed
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
55 changes: 55 additions & 0 deletions guide/statements.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,58 @@ fn bar() {
foo();
}
```

### Let else statements

The keyword `else` should either appear one space after the initializer expression, or on a subsequent line with indentation matching the keyword `let`. There should always be a space between `else` and `{`.

If the `else` block contains only a single expression (e.g. `return x` or `continue` or `break x`), the entire statement should appear on one line if it fits.

```rust
let Some(1) = opt else { return };
```

If the line needs to be broken, prefer to break after the opening brace of the `else` block first, before inserting any line breaks into the initializer or pattern:

```rust
let Some(1) = opt else {
return
};
```

If the `else` and opening brace do not fit on the same line as the initializer,
break before `else`. If a line begins with `else`, it should be indented at the same level as `let`,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
break before `else`. If a line begins with `else`, it should be indented at the same level as `let`,
break before `else`. If a line begins with `else` (potentially preceded by closing braces or parentheses or similar), it should be indented at the same level as the matching `let`,

Copy link
Author

Choose a reason for hiding this comment

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

I think "line begins with else" and "preceded by..." are mutually exclusive. Perhaps another paragraph is needed for that case.

and the block should be on the same line if it fits.
Copy link
Member

@joshtriplett joshtriplett Oct 5, 2021

Choose a reason for hiding this comment

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

Suggested change
and the block should be on the same line if it fits.
and there should always be a newline after the opening brace so that the block always appears on a subsequent line. This calls attention to the `else` block attached to the `let`, making it easy to visually distinguish a `let`-`else` from a plain `let`.

Additional justification: this only applies when the else { doesn't fit on the line with the initializer.

Copy link
Author

Choose a reason for hiding this comment

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

This calls attention to the else block

The style guide does not need to say "why" right?

I think what you are suggesting here should not be a dependent clause of "if a line begins with else". How about this?

If the else is not on the same line as let, the else block should not be written in one line.

I'm assuming that we can lean on the "blocks" section of the guide and so "not written in one line" is specific enough.

Regardless of how it's worded, I agree, this is more consistent with if/else.


```rust
let MyStruct { foo } = ({
statement;
fun()
}) else { return };
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
}) else { return };
}) else {
return
};


let Some(1) = opt
else { return };
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
else { return };
else {
return
};


let Some(1) = opt
else {
println!("nope");
return;
};
```

If the last line of the initializer expression is indented past `let`,
the `else` should be broken to the next line.

```rust
let Foo { bar } = foo
.method()
else {
return
};

let MyStruct { foo: Some(1) } =
some_variable
else {
return
};
```