lang (patterns | exhaustiveness | control-flow)
Currently when using an if let statement and an irrefutable pattern (read always match) is used the compiler complains with an E0162: irrefutable if-let pattern.
The current state breaks macros who want to accept patterns generically and this RFC proposes changing this error to an error-by-default lint which is allowed to be disabled by such macros.
The use cases for this is in the creation of macros where patterns are allowed because to support the _ patterns the code has to be rewritten to be both much larger and include an [#allow] statement for a lint that does not seem to be related to the problem.
The expected outcome is for irrefutable patterns to be compiled to a tautology and have the if block accept it as if it was if true { }.
To support this, currently you must do something roughly the following, which seems to counteract the benefit of having if-let and while-let in the spec.
#[allow(unreachable_patterns)]
match $val {
$p => { $b; },
_ => ()
}
The following cannot be used, so the previous must be. An #[allow(irrefutable_let_pattern)] is used so that the error-by-default lint does not appear to the user.
if let $p = $val {
$b
}
irrefutable if-let-pattern and similar patterns to an error-by-default lint that can be disabled by an #[allow] statementirrefutable_let_patternCode Example (explicit):
#[allow(irrefutable_let_pattern)]
if let _ = 'a' {
println!("Hello World");
}
Code Example (implicit):
macro_rules! check_five {
($p:pat) => {{
#[allow(irrefutable_let_pattern)]
if let $p = 5 {
println!("Pattern matches five");
}
}};
}
This can be taught by changing the second version of The Book to not explicitly say that it is not allowed. Adding that it is a lint that can be disabled.
It allows programmers to manually write the line if let _ = expr { } else { } which is generally obfuscating and not desirable. However, this will only be allowed with an explicit #[allow(irrefutable_let_pattern)].