# Pre-Pre-RFC: \`let else match\` statement

**URL:** <https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691>\
**Category:** language design\
**Created:** [November 5, 2022, 7:49pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691 "2022-11-05T19:49:40Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![HarrisonMc555](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/harrisonmc555/32/7066_2.png) [@HarrisonMc555](https://internals.rust-lang.org/u/HarrisonMc555)\
**Post date:** [November 5, 2022, 7:49pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/1 "2022-11-05T19:49:41Z")

</div>

# Background

Rust 1.65.0 stabilized [`let-else` statements](https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html#let-else-statements). In the [discussion](https://www.reddit.com/r/rust/comments/yl3x62/announcing_rust_1650/) on r/rust, [u/intersecting\_cubes](https://www.reddit.com/user/intersecting_cubes) made the [following observation](https://www.reddit.com/r/rust/comments/yl3x62/comment/iuzpnek/?context=3):

> let-else is useful, but only in limited cases where you don't want to inspect the other branches. Most of the time, I _do_ want to inspect them, though. For example, if I'm unpacking a Result, I probably want to log the error instead of just returning or breaking. This requires binding the Err branch, which let-else won't do.

The more I thought about it, the more I agreed with this point. It seems like it would be quite common to want to use values in a failed pattern before diverging. This would still retain all of the benefits of `let-else` statements (reduced repetition, etc.), but you would have a more powerful `else` branch.

# Proposal

My (very early, only moderately considered) proposal is to add a `let-else-match` statement. The `match` statement would need to cover all patterns that weren't covered by the `let` binding.

I imagine something like the following:

```rust
let Ok(x) = foo() else match {
    Err(e) => {
        println!("Error: {:?}", e);
        return;
    },
};
println!("Got: {}", x);

```

If our call to `println!` was a constant, then we could have used the new `let-else` statement. However, if we want to use the `Err` value, we need to match on it. As of today, the best option is to revert back to a normal `match` statement, with all the duplication that entails.

```rust
let x = match foo() {
    Ok(x) => x,
    Err(e) => {
        println!("Error: {:?}", e);
        return;
    },
};
println!("Got: {}", x);

```

# Another Example

```rust
let (Some(x), Some(y)) = (foo(), bar()) else match {
    (Some(x), None) => {
        println!("We need both, not just {}", x);
        return;
    },
    _ => return,
};
println!("We have {} and {}", x, y);

```

As of today, this would need to be written as:

```rust
let (x, y) = match (foo(), bar()) {
    (Some(x), Some(y)) => (x, y),
    (Some(x), None) => {
        println!("We need both, not just {}", x);
        return;
    },
    _ => return,
};
println!("We have {} and {}", x, y);

```

This is adequate but repetitive.

# Possible Concerns

## Does this lead to ambiguous syntax?

I don't think there's a possibility for ambiguous syntax since a normal `else` statement has to 1) come after an `if` statement, and 2) has to be followed by `{`, not the `match` keyword.

## Is this actually a common use case?

This is the part that I'm least confident in. I don't know how often this will come up. Since `let-else` was just barely stabilized, I haven't even used that yet. If anybody wants to go through a small crate and see how many places could take advantage of this that could be helpful.

## Does this make the language more complicated?

Yes. Is it worth it? I think it adds a nice feature without making the language more complex, and I think the behavior is fairly intuitive. If I saw this code in the wild and hadn't been closely following Rust for a while, I suspect that I would shrug my shoulders, think "I didn't know you could do that", and expect it to work as I have described. I think that my interpretation of the behavior would be the most common interpretation by far.

The only alternative interpretation of the semantics I can think of is thinking that the `match` lived inside an implicit `else` block. However, Rust has a pretty consistent history of _not_ letting blocks be implicit, so that interpretation would be assuming a significant deviation from that pattern.

## Do we really need to do this?

This is simply syntactic sugar and doesn't allow us to write any code that was impossible to write before. It does seem like a natural extension of the `let-else` statement.

## What alternatives are there?

```rust
let Ok(x) = match foo() else {
    ...
};

```

^ This seems weirder to me than my proposal, but I guess it could work.

```rust
let Ok(x) = foo() match else {
    ...
};

```

^ This doesn't flow as well for my English brain. I also think that the `match` keyword should be closer to the patterns it is matching against than the `else` keyword.

```rust
let Ok(x) = foo() else {
    Err(e) => {
        println!("Error: {:?}", e);
        return;
    },
};

```

^ I believe this would make both programmatic parsing and human reading much more difficult. You don't know whether it's a "normal" `let-else` statement or a `let-else-match` statement until you see if there are arrows or not. This also might subject to more serious ambiguities; I haven't thought about it for very long.

# Conclusion

After thinking about this for about a day, it seems like it could be a helpful addition to the Rust language. I've tried to come up with reasons why it wouldn't work/would be too costly/aren't a good fit for the Rust language and haven't come up with anything.

I look forward to hearing your feedback! If there's an obvious (or subtle) reason why this isn't a good idea, please feel free to point it out! 😄

---

<div class="post-metadata">

**Author:** ![semicoleon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/semicoleon/32/7397_2.png) [@semicoleon](https://internals.rust-lang.org/u/semicoleon)\
**Post date:** [November 5, 2022, 8:18pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/2 "2022-11-05T20:18:10Z")

</div>

I think it would be fairly strange to have a second `match` construct which is almost the same as the standard one but is missing a branch. Especially since `match` can be nested in weird places already, I don't think this different behavior would be clear unless you were already aware of it.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [November 5, 2022, 8:29pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/3 "2022-11-05T20:29:33Z")

</div>

`match` still requires being exhaustive, so that's not necessarily an issue; if the `match` is in valid code you know it covers all cases.

Additionally, the unstable never type feature allows writing `match`es which don't mention any enum variants which are uninhabitable.

---

<div class="post-metadata">

**Author:** ![Nemo157](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nemo157/32/11585_2.png) [@Nemo157](https://internals.rust-lang.org/u/Nemo157)\
**Post date:** [November 5, 2022, 9:06pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/4 "2022-11-05T21:06:04Z")

</div>

The original usecase I feel is already handled well by combining let-else and `Result`-combinators:

```rust
let Ok(x) = foo().map_err(|e| println!("Error: {:?}", e)) else { return };

```

(and if you commonly have such a structure, you could define your own `Result` extension methods for logging).

The tuple example is a much stronger one, but it would be more interesting to see snippets of real code that can use this construct. The original let-else RFC and PR thread had a few real examples that were a good motivator.

Also of note, this [is a future possibility in the let-else RFC](https://rust-lang.github.io/rfcs/3137-let-else.html#let-else-match).

---

<div class="post-metadata">

**Author:** ![chrefr](https://avatars.discourse-cdn.com/v4/letter/c/e480ec/32.png) [@chrefr](https://internals.rust-lang.org/u/chrefr)\
**Post date:** [November 5, 2022, 11:13pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/5 "2022-11-05T23:13:39Z")

</div>

About the syntax, I feel like `match` is introducing a new indentation level and is almost no better than `let x = match foo() { Ok(x) => x, Err(e) => { ... } };`. But maybe:

```rust
let Ok(k) = foo() else Err(e) => {
    println!("Error:? {e:?}");
    return;
}

```

Since I think the common case is handling one variant, or all other variants in the same way.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [November 6, 2022, 1:46am UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/6 "2022-11-06T01:46:37Z")

</div>

Previous discussions about `let`-`else`-`match`:

- [https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/let.20.2E.2E.2E.20else/near/229224443](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/let.20.2E.2E.2E.20else/near/229224443)

> Scott goes off on a wild tangent idea: `let v = foo?;` is
> 
> ```rust
> let Ok(v) = foo
> else match {
> Err(e) => yeet e,
> }
> 
> ```
> 
> (Basically lean into how this is all sugar for a `match` anyway. This doesn't trip my usual "I don't want `else match`" because it's all one construct, so the match can work without needing typestate.)

> I'm picturing that as one big construct which would desugar to
> 
> ```rust
> let (v,) = match foo {
> Ok(v) => (v,)
> Err(e) => yeet e,
> }
> 
> ```

- [https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/.60let.20pattern.20.3D.20expr.20else.20.7B.20.2E.2E.2E.20.7D.60.20statements/near/234905737](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/.60let.20pattern.20.3D.20expr.20else.20.7B.20.2E.2E.2E.20.7D.60.20statements/near/234905737)
- [https://github.com/rust-lang/rfcs/pull/3137#issuecomment-860883577](https://github.com/rust-lang/rfcs/pull/3137#issuecomment-860883577)

---

<div class="post-metadata">

**Author:** ![HarrisonMc555](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/harrisonmc555/32/7066_2.png) [@HarrisonMc555](https://internals.rust-lang.org/u/HarrisonMc555)\
**Post date:** [November 6, 2022, 3:33am UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/7 "2022-11-06T03:33:35Z")

</div>

This is sufficient when you're using the `Result` (or `Option`) type. However, it fails when using custom types—especially enums with more than two variants. Imagine this case:

```rust
for time in get_times() {
    let Now(timestamp) = time else match {
        Past(history) => return Error::TooLate(history),
        Future => continue,
    };
    // Use timestamp...
}

```

You can't use `map_err` (or any similar) method for this use case. Once again, you would need to revert back to a complete `match` expression.

```rust
for time in get_times() {
    let timestamp = match time {
        Now(timestamp) => timestamp,
        Past(history) => return Error::TooLate(history),
        Future => continue,
    };
    // Use timestamp...
}

```

---

<div class="post-metadata">

**Author:** ![HarrisonMc555](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/harrisonmc555/32/7066_2.png) [@HarrisonMc555](https://internals.rust-lang.org/u/HarrisonMc555)\
**Post date:** [November 6, 2022, 3:44am UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/8 "2022-11-06T03:44:51Z")

</div>

This is probably the line of thinking I'm most sympathetic to. I do believe that the fact that this would have an `else` keyword immediately preceding the `match` helps a lot in differentiating them.

However, if I'm not mistaken, this would be legal:

```rust
let Ok(x) = foo() else match match bar() { Some(y) => y, None => Ok(default_x), } {
    Err(e) => {
        println!("{}", e);
        return;
    },
}

```

I'm guessing we don't normally worry about optimizing for `weird-exprs.rs`, but it is something to keep in mind.

---

<div class="post-metadata">

**Author:** ![HarrisonMc555](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/harrisonmc555/32/7066_2.png) [@HarrisonMc555](https://internals.rust-lang.org/u/HarrisonMc555)\
**Post date:** [November 6, 2022, 3:48am UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/9 "2022-11-06T03:48:36Z")

</div>

Two things I forgot to reply to:

> The tuple example is a much stronger one, but it would be more interesting to see snippets of real code that can use this construct. The original let-else RFC and PR thread had a few real examples that were a good motivator.

This is a good point. I don't have good motivators to point to. If others have good motivators hopefully they can raise them here 😄

> Also of note, this [is a future possibility in the let-else RFC](https://rust-lang.github.io/rfcs/3137-let-else.html#let-else-match).

I totally missed this. Good to know that someone else brought this up! I tried looking around but didn't find it.

---

<div class="post-metadata">

**Author:** ![danjl1100](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/danjl1100/32/6466_2.png) [@danjl1100](https://internals.rust-lang.org/u/danjl1100)\
**Post date:** [November 6, 2022, 12:58pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/10 "2022-11-06T12:58:21Z")

</div>

> [@HarrisonMc555](#):
>
> would be legal:
> 
> ```rust
> let Ok(x) = foo() else match match bar() { Some(y) => y, None => Ok(default_x), } {
> Err(e) => {
> println!("{}", e);
> 
> ```

I think the key is that the proposed `else match { ... }` does not accept any argument after the `match`, instead implicitly using the preceding expression.

**EDIT** : Disregard, I didn't realize you were most likely alluding to the existing case that

> [@semicoleon](#):
>
> `match` can be nested in weird places already,

---

<div class="post-metadata">

**Author:** ![rsalmei](https://avatars.discourse-cdn.com/v4/letter/r/c67d28/32.png) [@rsalmei](https://internals.rust-lang.org/u/rsalmei)\
**Post date:** [December 1, 2022, 3:53pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/11 "2022-12-01T15:53:43Z")

</div>

I'd love to have this!

> [@chrefr](#):
>
> ```rust
> let Ok(k) = foo() else Err(e) => {
> println!("Error:? {e:?}");
> return
> 
> ```

If one had anything with more than two variants, we could just get the value:

```rust
let Now(ts) = foo() else x => {
    // x is either Past or Future here.
    return
}

```

---

<div class="post-metadata">

**Author:** ![jjpe](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jjpe/32/9779_2.png) [@jjpe](https://internals.rust-lang.org/u/jjpe)\
**Post date:** [December 1, 2022, 5:05pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/12 "2022-12-01T17:05:01Z")

</div>

I think this entire branch of rust development has kind of snowballed out of control and needs to be reigned in, badly.

Just because we _can_ add more control structures doesn't mean it's a good idea. And I think Rust's complexity budget is (in danger of) being overspent.

Say we add this. What's next? Where does it end? When do we say "no further"? And no, those are not rhetorical questions.

And then there's the content itself. This proposal is just a `match` with a nonobvious and asymmetric ordering of cases. I think that's a spectacularly bad idea. Keep in mind, _no_ new abilities are being added, just new ways to write what's already perfectly possible.

---

<div class="post-metadata">

**Author:** ![zackw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/zackw/32/2071_2.png) [@zackw](https://internals.rust-lang.org/u/zackw)\
**Post date:** [December 1, 2022, 6:02pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/13 "2022-12-01T18:02:47Z")

</div>

> [@jjpe](#):
>
> This proposal is just a `match` with a nonobvious and asymmetric ordering of cases

That's slightly unfair. The value of `let else match` is that it creates a binding beyond the substatement for _exactly one_ of the match arms.

```rust
let Ok(val) = foo() else match {
   Err(e) => { report_error(e); return; }
}
// val is usable here

```

You _can_ express this with a plain match but the control flow goes down and back up again and it's not, IMNSHO, nearly as obvious that all but one of the match arms diverges.

```rust
let val = match foo() {
  Ok(val) => val,
  Err(e) => { report_error(e); return; }
}

```

I have written code that does nasty low-level networking things that had a construct like this, but with three match arms, each containing nontrivial code (gotta handle EINPROGRESS specially) and it was painful to reason about, and I couldn't find any better way to write it.

I don't exactly _disagree_ with your position that this is an unnecessary new feature, but I think you're strawmanning the case for it.

---

<div class="post-metadata">

**Author:** ![jjpe](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jjpe/32/9779_2.png) [@jjpe](https://internals.rust-lang.org/u/jjpe)\
**Post date:** [December 1, 2022, 6:32pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/14 "2022-12-01T18:32:24Z")

</div>

> [@zackw](#):
>
> and it's not, IMNSHO, nearly as **obvious** that all but one of the match arms diverges.

This touches the heart of the matter: obviousness is entirely subjective here. I know that because to me a `match` expr is the far more obvious construct to deal with, precisely because of its regularity. I've written my own fair share of nested `match`es, and even then I'll take those any day. Because their meaning is _obvious_.

And as you indicated, `match` can already do today what `let else match` is meant for. Another way to phrase that is: that use case is already being catered to.

You know, this reminds me of the `unless` [macro](http://clhs.lisp.se/Body/m_when_.htm) in common lisp. Even though it's always available, I never used that either for much the same reason: it's not obvious enough to be worth it, simply because I always have to invert the predicate first.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [December 1, 2022, 7:10pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/15 "2022-12-01T19:10:57Z")

</div>

> [@jjpe](#):
>
> And as you indicated, `match` can already do today what `let else match` is meant for. Another way to phrase that is: that use case is already being catered to.

I don't think it's that simple. "`match` can do what `let else match` is meant for" is true, but so is "`match` can do what `let else` is meant for". But `let`-`else` was deemed worth having, so it's _possible_ that `let`-`else`-`match` might be worth having too.

(Remember that `match` can also do everything that `if` can do too, and arguably does so better than `match` does `let`-`else`. But we still have `if`!)

> [@jjpe](#):
>
> simply because I always have to invert the predicate first

I agree that an `unless` that _just_ inverts the predicate isn't worth it. But if the body is required to diverge, then there's a reason to use it.

After all, we write `assert!` with an "inverted" predicate too. So a "here's something that must hold afterwards" condition is a useful thing, and I could imagine writing loop body invariants as `unless x > 0 { continue }` or similar as a useful thing, especially to avoid mental DeMorgan gymnastics.

(I'm not actually proposing it for Rust, though. It might have made sense to spell `let`-`else` as `unless let`, but that ship has now sailed.)

---

<div class="post-metadata">

**Author:** ![afetisov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/afetisov/32/8508_2.png) [@afetisov](https://internals.rust-lang.org/u/afetisov)\
**Post date:** [December 1, 2022, 7:20pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/16 "2022-12-01T19:20:49Z")

</div>

> [@scottmcm](#):
>
> But `let`-`else` was deemed worth having, so it's _possible_ that `let`-`else`-`match` might be worth having too.

That presupposes that everyone agrees that `let-else` was worth having, which isn't true. The current thread could just as much serve as evidence that `let-else` was a mistake: too weak to properly deal with the whole use case, just encouraging adding more syntax soup to plug more holes.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [December 1, 2022, 7:33pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/17 "2022-12-01T19:33:12Z")

</div>

> [@afetisov](#):
>
> That presupposes that everyone agrees that `let-else` was worth having, which isn't true.

There's nothing that _everyone_ agrees.

`let`-`else`'s acceptance is undeniably evidence for "things can be added to Rust even if it's already possible to do with `match`".

It may very well be that `let`-`else`-`match` doesn't pass the bar for acceptance -- generalizing sugar made for a common special case is often not something we'd do -- but if so it won't _just_ be because `match` can do it.

---

<div class="post-metadata">

**Author:** ![160R](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/160r/32/9502_2.png) [@160R](https://internals.rust-lang.org/u/160R)\
**Post date:** [December 1, 2022, 7:52pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/18 "2022-12-01T19:52:48Z")

</div>

I want to add the following syntax to the list of possible alternatives:

```rust
let (Some(x), Some(y)) = (foo(), bar()) {
    else (Some(x), None) => {
        println!("We need both, not just {}", x);
        return;
    },
    else _ => return,
};

println!("We have {} and {}", x, y);

```

* * *

```rust
for time in get_times() {
    let Now(timestamp) = time {
        else Past(history) => return Error::TooLate(history),
        else Future => continue,
    };
    // Use timestamp...
}

```

But for some reason I'm sure that it already has been considered somewhere.

---

<div class="post-metadata">

**Author:** ![jjpe](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jjpe/32/9779_2.png) [@jjpe](https://internals.rust-lang.org/u/jjpe)\
**Post date:** [December 1, 2022, 8:45pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/19 "2022-12-01T20:45:28Z")

</div>

> [@scottmcm](#):
>
> `let`-`else`'s acceptance is undeniably evidence for "things can be added to Rust even if it's already possible to do with `match`".
> 
> It may very well be that `let`-`else`-`match` doesn't pass the bar for acceptance -- generalizing sugar made for a common special case is often not something we'd do -- but if so it won't _just_ be because `match` can do it.

I never said or implied it was _just_ because match can do it. That argument was meant to show that there's nothing new under the sun here, in sharp contrast to features such as GATs or const generics. Those features obviously pull their weight, and yet there was a heavy discussion on whether GATs should have been included at all.

Meanwhile I distinctly don't get the sense that a similar level of scrutiny is being applied here, and whether this feature or `let-else` pull their weight is completely nonobvious to me.

Just to put things into perspective a little, I don't think either of these 2 `let` features is the end of the world. However, over the last couple of years I've read how some folks feel like Rust is careening in the direction of C++ - so humongusly huge that the language just buckles under its own weight and so each project simply decides on some subset of the language to keep things workable. Problem is, each project decides on a different subset. Initially I thought the notion of Rust becoming too large preposterous. But as time marches on, less and less so. Thing is, I think it works kind of like the event horizon of a black hole: you don't really notice¹ passing that threshold and so before you know it, it's too late.

¹ I'm making the pretty large but simplifying assumption that an observer would live long enough to actually reach the event horizon intact.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [December 1, 2022, 9:14pm UTC](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691/20 "2022-12-01T21:14:16Z")

</div>

> [@jjpe](#):
>
> Those features obviously pull their weight, and yet there was a heavy discussion on whether GATs should have been included at all.
> 
> Meanwhile I distinctly don't get the sense that a similar level of scrutiny is being applied here

Two things I'll add here:

1. Paradoxically, it's the "lets you do something fundamentally new" features that in a way need _more_ of that kind of scrutiny. Once GATs and const generics are in the type system, they're there forever. But if we decide in 2025 "you know, that `let`-`else` feature was a horrible mistake", we _could_ remove it from the 2027 and following editions. It needs to keep working in the older ones for the stability promise, but when things are _just_ sugar that's exactly the kind of thing that editions let us change or remove.

2. This is a "Pre-Pre-RFC" on IRLO, not even an RFC PR, let alone an FCP. We _should_ be discussing lots of things that won't get accepted in threads like this. Regardless of whether I think the feature is a _good_ idea, I still want to see the proposal reach its best form: the most rusty syntax, the most orthogonal behaviour, the most convincing motivation, etc. It's pretty rare that a proposal is an _immediate_ no. (Though there are some, like "switch from braces to significant whitespace".)

[Next page](https://internals.rust-lang.org/t/pre-pre-rfc-let-else-match-statement/17691.md?page=2)
