I think we should open an RFC for let expression which replaces matches!
macro. From macro example in docs:
let foo = 'f';
assert!(matches!(foo, 'A'..='Z' | 'a'..='z'));
assert!(let 'A'..='Z' | 'a'..='z' = foo);
let bar = Some(4);
assert!(matches!(bar, Some(x) if x > 2));
assert!((let Some(x) = bar) && x > 2);
If you find matches!
more natural and that syntax strange, look at above examples inside if which is part of current language:
if let 'A'..='Z' | 'a'..='z' = foo {
// it will works currently
}
if (let Some(x) = bar) && x > 2 {
// this is special case of if chain proposal
}
I believe this is already implemented in the way of implementing if chain
(At least simple form without &&). Just we need to see how it will play in wild which a RFC can show it.
Binding rules
It can be similar to &&
chain proposal. If a binder expression (combination of let expressions with &&
, ||
, !
and ()
) consumed in a function call or in another operator or in return site of a block, all of its variables will be discarded (and unused variable lints can prevent confusion). If it consumed in a if
or while
statement, variables can be accessed inside of body of if
or while
. And if is consumed as an statement, it should be always evaluate to true (compile error otherwise) and then variables are available in next lines. It means (let x = 2) && (let y = 5);
would be accepted for language consistency (can be linted away because it is useless, but it equivalent ||
one can be very useful: (let Some(x) = foo) || let x = default;
. But this is for future)
To see how it can be extended to ||
and !
see this full algebra but this will be reversed for future.
Difference between ()
and {}
in this context should be noted. {}
will discard variables but ()
won't and will play well with logic operators. So those will be different:
assert!((let Some(x) = bar) && x > 2); // ok
assert!({ let Some(x) = bar } && x > 2); // compile error, x is local in the block
Is it the right next step?
Some one can say implementing ||
chains and !let
is better at first but I don't think so. This case (alternative to matches!
) has way more usage than ||
chains, and if we land it first it will create natural demand for those improvements. I think it can even landed before the approved &&
if chains.
So are we ready for creating this RFC?
cc @Centril