The best way to write an if statement

I just stumbled upon this oddity allowed by the if let syntax:

if let true = (a == b) { /**/ }

Now that I have seen it, it makes perfect sense...

By the way, clippy does not warn you for

if let true = true { /**/ }

Then you should know patterns first to be less surprised by refutability.


Update: to answer the question of the title, I guess you're confused by if and if let expressions.

if expressions
Syntax
IfExpression :
if Expressionexcept struct expression BlockExpression
(else ( BlockExpression | IfExpression | IfLetExpression ) )?

if let expressions
Syntax
IfLetExpression :
if let Pattern = Scrutineeexcept lazy boolean operator expression BlockExpression
(else ( BlockExpression | IfExpression | IfLetExpression ) )?

1 Like

As I said,

Now that I have seen it, it makes perfect sense...

I usually don't think of true as a refutable pattern (even in haskell, you would use if then else for boolean values), that's why it surprised me

I know people really don't like reading the documentations carefully. But please do read them.

refutable when it has the possibility of not being matched by the value it is being matched against

So it's refutable when true/false is matched, as a boolean value, against two possibilities.

match boolean {
    true => ...,
    false => ...,
}
3 Likes

Well, you can do the following, actually:

match :: Bool -> Integer
match False = 0
match True = 42

Note: if you write irrefutable pattern in if-let, the compiler indeed warns.

The if let and while let expressions accept refutable and irrefutable patterns, but the compiler warns against irrefutable patterns because by definition they’re intended to handle possible failure: the functionality of a conditional is in its ability to perform differently depending on success or failure.
src: Refutability: Whether a Pattern Might Fail to Match - The Rust Programming Language

fn main() {
    // refutable pattern in if-let
    if let false = true {
        println!("refutable: may fail to match agianst")
    }
    // same as
    match true {
        true => (),
        false => println!("refutable: may fail to match agianst"),
    }
    
    // irrefutable pattern in if-let: but the compiler warns
    if let irrefutable = true {
        println!("irrefutable: must match")
    }
    // same as
    match true {
        irrefutable => println!("irrefutable: must match"),
    }
}

warning: irrefutable `if let` pattern
  --> src/main.rs:14:8
   |
14 |     if let irrefutable = true {
   |        ^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this pattern will always match, so the `if let` is useless
   = help: consider replacing the `if let` with a `let`
   = note: `#[warn(irrefutable_let_patterns)]` on by default
1 Like

I treat the = in the if let statement not as assignment but as a test for equality which will assign if true or branch if not.

Consider the more recent inverse, the let ... else:

let false = (a == b) else { /**/ };
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.