If we want to maintain that patterns are a dual of expressions, then pat?
is the wrong syntax; it's probably try pat
instead, such that matches!(try { 1 }, try 1)
.
I know there's some work open on readjusting how default binding modes function for edition2024. With that work, deref patterns, and the desire for try/await functionality in pattern position, we could choose to admit patterns are imperfect duals and extend the pattern syntax however is most convenient.
But while "rebinding modes" would certainly be convenient, I do still question the choice to make them an "infallible" pattern with a side effect. Modifying example 2 from the OP:
match serde_json::from_str(s) {
try Value::Bool(true) => println!("it is true"),
_ => println!("it isn't true"),
}
That this returns on errors and doesn't handle them via fallthrough to the next pattern is imho quite unclear. If it's limited like explicit binding modes are to being applied on name bindings only, it's a bit easier to digest, but still suffers the same issue.
Even await
patterns, which aren't inherently fallible, immediately run into the same issue if they decorate a fallible pattern. Consider:
match stream.next() {
await Value::Bool(true) => handle_true(),
other => handle_other(other),
}
The first pattern already awaited the scrutinee here, so what does attempting to bind the scrutinee to other
even do, rewind the future?
If we implement any "rebinding modes," they should be restricted at least to only decorating infallible patterns to avoid the obvious problem cases. A more general solution for fallible patterns that I used when discussing deref patterns' semantics is to extend if
guards to match
guards, meaning something like
match serde_json::from_str(s) {
Some(_tmp0) match _tmp0? {
Value::Bool(true) => println!("it is true"),
},
_ => println!("it isn't true"),
}
where the inner match doesn't need to be exhaustive, and any uncovered fallthrough of the inner match continues on to testing the outer match's following arms. The catch is that creating the inner scrutinee needs to work by-ref on the outer scrutinee if pattern matching is going to continue if the inner match fails, illustrating more directly the issue with "rebinding modes" that can fail.