This is a tracking issue for the eRFC "if- and while-let-chains, take 2" (rust-lang/rfcs#2497).
For the tracking issue for the immediate edition changes, see #53668.
Steps:
Unresolved questions:
if let
s inside match
arms](https://github.com/rust-lang/rfcs/blob/master/text/2497-if-let-chains.md#chained-if-lets-inside-match-arms)Collected issues:
Implementation history:
I'm working on implementing this in a 3+ PR step fashion based on discussions with @oli-obk.
for the record, the discussed step list is
if
from HIR
and make lowering emit a match
if let
from AST
and instead have a let
expressionI can't imagine 3 would be a particularly large step (enough to merit splitting), but 3 steps sounds fair enough.
@Centril I'm really jazzed about this feature, lmk if there is any work I can help with.
@estk :) The work is pretty non-parallelizable at the moment; However, once https://github.com/rust-lang/rust/pull/60861 lands you may want to take a look at https://github.com/rust-lang/rust/issues/60336.
Question worth discussing: This introduces let
as something _like_ an expression in the AST.
Do we plan to make it a true expression? As in, will $e:expr
match let Pat(..) = foo
in macros? This does not mean that it will _work_ everywhere (as @centril correctly points out, $t:ty
matches impl Trait
, but it's only allowed in certain positions in the AST), it just means that macros will be able to match on it. They may error further down the pipeline if it gets used outside of an if
.
This is technically a breaking behavior change; a macro with a fallthrough to let $p:pat = $e:expr
will suddenly start behaving differently.
@Manishearth I thought that you can't probe whether something parses as an AST fragment in macro_rules
macros, only tokens (this includes $i:ident
, $l:lit
, etc.).
That is, I expected the first expr
/pat
/stmt
/block
/item
/etc. that is reached to be final.
But I'm wrong, and this is either behavior introduced in the past couple years, or I was just confused.
this is either behavior introduced in the past couple years
This is https://github.com/rust-lang/rust/pull/42913 if I'm not mistaken, almost 2 years ago.
One token lookahead is used to reject alternatives that "obviously don't fit".
(not sure this is the right place for this, but I don't think we have anything else opened for "pattern matching expressions" discussion).
I've just noticed that Java is getting pattern matching along the lines proposed in https://github.com/rust-lang/rfcs/issues/929#issuecomment-285602496. That is, control-flow sensitive scoping and patterns on the right are now almost Java-level proven and trusted language design choices.
any actual syntax for this in nightly rust? just cannot type it to work.
! Compiling of exercises/conversions/from_into.rs failed! Please try again. Here's the output:
error: `let` expressions are not supported here
--> exercises/conversions/from_into.rs:44:33
|
44 | if (parts.len() == 2 && let Some(n) = name && let Some(Ok(a))= age) {
| ^^^^^^^^^^^^^^^^^^
|
= note: only supported directly in conditions of `if`- and `while`-expressions
= note: as well as when nested within `&&` and parenthesis in those conditions
not nice
if parts.len() == 2 { if let Some(n) = name { if let Some(Ok(a)) = age {
return Person{name: n.to_owned().to_string(), age : a,};
}}}
Any progress updates? Although I love rust this is by far the jankiest part of the language
I am trying to tackle this feature one bit at a time in my spare time. No promises for a concrete release date though
Most helpful comment
(not sure this is the right place for this, but I don't think we have anything else opened for "pattern matching expressions" discussion).
I've just noticed that Java is getting pattern matching along the lines proposed in https://github.com/rust-lang/rfcs/issues/929#issuecomment-285602496. That is, control-flow sensitive scoping and patterns on the right are now almost Java-level proven and trusted language design choices.