The big one for me: boolean checks are forgetful. If you have a block of code behind validator logic, you've only proven a condition local to that branch, as opposed to encoding it into the type itself. You have to be careful about how you refactor trees of `if`/`else`, and may wind up performing redundant checks elsewhere in the code. With the `guard` examples you are carrying that proof outside the scope of the immediate function, and it's trivial to compose this further, or refactor to a different failure mode entirely.
More minor quibbles might be:
Pattern matching has completeness checks, while it's harder with `if`.
When your only tool is `if`, you wind up with nested and indented code that is more laborious to follow. Most "idiomatic" languages like Go/Python have zero respect for vertical real-estate. The hardest code to read is the one that doesn't fit on your screen.
--
If the outermost layer of your program invokes the literal keyword `if`, I don't think it's a big deal, as long as you are parsing that condition into a more complex type, and not just relying on context/passing bools around everywhere.