If Statement transpilation

As mentioned at the start of the conditionals section in the basics chapter, if statements can be represented as match statements. This is especially advised when you have many if branched and more complicated branch conditions.

Internally, the compiler will convert if statements into match cases so that it has to do less work in the following stages of compilation.

In general, transpilation process can be represented as:

if <condition_1> {
     <block_1> 
} else if <condition_2> { 
    <block_2> 
} 
... 
} else {
    <block_n>
}

// will be converted to

match true {
    _ if <condition_1> => block_1;
    _ if <condition_2> => block_3;
    ...
    _ => block_n;
}

For example, the following if statement will be converted as follows:

#![allow(unused)]
fn main() {
if conditionA {
  print("conditionA")
} else if conditionB {
  print("conditionB")
} else {
  print("Neither")
}

// Internally, this becomes:

match true {
  _ if conditionA => { print("conditionA") };
  _ if conditionB => { print("conditionB") };
  _ => { print("Neither") };
}
}

However, this representation is not entirely accurate because the compiler will optimise out some components out of the transpiled version. Redundant statements such as match true { ... } will undergo constant folding to produce more optimal AST representations of the program.

Missing 'else' case

If the if statement lacks an else clause or a default case branch, the compiler will insert one automatically to avoid issues with pattern exhaustiveness. This behaviour is designed to mimic the control flow of classic if statements because the else branch will have an assigned empty expression block.

From the above example, but without the else branch:

#![allow(unused)]
fn main() {
if conditionA {
  print("conditionA")
} else if conditionB {
  print("conditionB")
}

// Internally, this becomes:

match true {
  _ if conditionA => { print("conditionA") };
  _ if conditionB => { print("conditionB") };
  _ => { };
}
}