Using `if let` to check for equality

Then it is no different from matches!(opt, Some(_)) (aside syntax)...

1 Like

It wouldn't be the first time a language feature deprecated a library macro.


IIRC the other times a language feature replaced a macro (? and async/await being the ones I'm familiar with), there were at least some corner cases that the language feature handled better than any macro ever could, especially at scale when several uses of the feature were nested across several crates.

But is and matches! would be exactly identical in behavior, if I understand the current proposals correctly, so adding an is keyword for this seems like a wash to me.


Sounds like it'd be nice to have a clippy lint that proposes to use matches! instead of if let <pat> = <expr> if the pattern has no bindings... at least I feel like that will always strictly improve readability. let is very deeply connected with the idea of binding a name, at least in my brain. I always startle when I see things like if let <const> = <expr>.


It's a Rusty Yoda condition! :slightly_smiling_face:


Yoda must have hit his head, though. if let 42 = x {} "if let forty-two equals x"


Although it's kind of silly, you can even match on values in function arguments, if the values are irrefutable:

enum Foo {

fn foo(Foo::TheOnlyVariant: Foo, (): ()) {}
1 Like

It's not silly at all, but useful. For example, consider fn foo(Wrap(x): ...) or fn foo((Ok(x) | Err(x): ...).


Yeah, so Rust managed to avoid the usual pitfall of if x = 42, so it shouldn't need Yoda conditions... and yet we still have them. I don't think that's good.

It would probably make sense to continue allowing it for code generation purposes. Suddenly failing to compile Yoda patterns would probably introduce a non-uniformity that would in turn require many macro authors to come up with special cases.

Oh, I didn't suggest we disallow it. We also allow if 42 == x, after all.

I just really dislike it being idiomatic for hand-written code.


I didn't mean the Yoda condition is good -- I was just amused to make the connection. Overall it's a natural edge case for pattern matching though. You can also write a constant let when it's irrefutable, like let () = println!(...);, which is only useful to statically assert the fact that it is constant.

I'm with this guy

I see a lot of questions about more complex syntax and determining scope and whatnot. What if we started by implementing only the minimum-viable syntax (if $expr is $pat {}) and disallow anything more complex at first? This simple form has obvious semantics and would satisfy the 90% use-case right away, and we can worry about how/whether to extend it later.

This was the same approach taken for if let $pat = $expr {}—we deferred dealing with && and other more complex syntax until later

Because that has no significant advantage over matches!().

Note that at this point the thread is very much repeating itself:

So someone with more free time than I currently have (sorry! :sob: ) should probably put up an RFC that spells out the argument: "let's stabilize matches!() since everyone wants it, and no one's been able to come up with a compelling variable bindings story, or any other reason to provide this functionality via a new is keyword". Never mind, I completely missed that this is being stabilized.

1 Like

matches! is already stable in 1.42-beta.


It has no significant advantage in the same way as for-loop has no significant advantage over an explicit loop over an iterator. In other words: yes, it's a sugar construct, but which is significantly easier to type, read and perceive over matches!() ("natural to read" property is quite a nice one). Considering that it covers a sufficient fraction of use-cases, I believe at the very least it's a proposal worth consideration.

Personally I wouldn't be against it, but on my list of "nice to have" features it's quite low.


Bindings are a significant improvement. To put it into code, with is you can do this:

if opt is Some(x) {
    println!("We got ourselves a {}", x);

Correct me if I'm wrong, but that's not possible with matches!(). That is the shortcoming we're talking about.

But that can be done with if let


Yes, but now we're back to yoda conditionals.

if let 42 = x {}

I guess this really is going in circles :smile: I'll abstain.


So just use if let with binders and matches! without binders, then?

That seems like a reasonable approach to me, anyway.

1 Like