reference icon indicating copy to clipboard operation
reference copied to clipboard

Document let else statements

Open est31 opened this issue 3 years ago • 7 comments

For the stabilization of let else statements.

Tracking issue: https://github.com/rust-lang/rust/issues/87335

est31 avatar Feb 03 '22 18:02 est31

Consider that you can already match against irrefutable pattern in let, and this is essentially just an extension to let in practice.

Originally I tried to extend the let section as you suggest. There are commonalities, but there are also a lot of differences. For let, the pattern must be irrefutable, for let else it must be refutable. For let, the = expr is optional, for let else it isn't. Explaining those differences would have made it harder to explain/comprehend how the thing works in the first place.

est31 avatar Feb 03 '22 21:02 est31

for let else it must be refutable.

No, by default it is only a warning to have an irrefutable binding in there.

warning: irrefutable `let...else` pattern
 --> src/main.rs:4:5
  |
4 | /     let x = 5 else {
5 | |         return;
6 | |     };
  | |______^
  |
  = note: `#[warn(irrefutable_let_patterns)]` on by default
  = note: this pattern will always match, so the `else` clause is useless
  = help: consider removing the `else` clause

cormacrelf avatar Feb 04 '22 03:02 cormacrelf

Good point, it's only a warning. Should I change the text of the reference to extend it to all patterns?

est31 avatar Feb 04 '22 09:02 est31

Yes. But refutable patterns deserve a mention, something along the lines of

If the pattern is a refutable pattern, then the else block will be executed when the pattern is not matched. The else block must escape [/return/whatever we call it] ...

I haven't read much of the reference before so not sure whether it's appropriate to mention that refutable patterns are the whole point of it.

cormacrelf avatar Feb 04 '22 12:02 cormacrelf

With let else stable, this is ready for review!

est31 avatar Sep 18 '22 08:09 est31

I think I too would prefer to see this defined as a single statement. I understand it can be a little awkward since it changes the semantics quite a bit, but I think it shouldn't be too difficult to describe. As it is, it looks like there is a lot of duplication.

To make it fit in the original let statements section, I think it should be sufficient to:

  • Remove the word "irrefutable".
  • Add a paragraph describing the else block behavior. Here's a rough draft, but feel free to adjust:

When an else block follows the initializer, then the pattern may be a refutable pattern. When the pattern does not match, the else block is executed. The type of the else block must be the never type. If there is no else block, then the pattern must be irrefutable.

  • The grammar for Expression in the initializer needs to reject forbidden expressions. I would probably just add a dagger (†) that links to a sentence in the grammar section that explains it. Like:

Syntax
… [Expression]

† When an else block is specified, the Expression must not be a LazyBooleanExpression or end with a }.

I'm also a bit surprised this is how it works, as this adds unprecedented complexity to the grammar and I think would be quite difficult for many parsers.

  • Add a note about irrefutability:

Note: rustc will emit a warning when using an irrefutable pattern with an else block since that makes it impossible for the else block to execute.

  • Add an example. Illustrate both a basic let binding, and one with an else block.

ehuss avatar Sep 20 '22 01:09 ehuss

@ehuss okay I gave up, I refactored the section so that it is unified with let. My second attempt of unifying feels less complicated than what I remember of my first attempt, so this was a good idea already, and I'm quite open towards this approach now.

est31 avatar Sep 20 '22 03:09 est31

r? @ehuss

est31 avatar Sep 24 '22 01:09 est31

@Havvy good catch! I've updated that sentence in the last commit.

est31 avatar Sep 26 '22 07:09 est31

No problem! It is great that consistency is important to you.

est31 avatar Oct 05 '22 14:10 est31