Should the following code compile? (playground) I'm trying to determine whether a GitHub issue is appropriate for this case and if so whether this is more of a diagnostics issue (i.e. this shouldn't compile) or a bug (i.e. this should compile).
I ran into this earlier and was a bit confused both by the diagnostics rustc emits as well as the fact this doesn't get compiled at all. When I put () around the whole expression that foo returns, it compiles just fine. When I assign the expression (without parens) to a variable and just put the variable's name on the last line, it works just fine — it's just when the match (or an if statement) is a subexpression of the final operand that rustc doesn't compile the block. Is there something about mixing match / if with other operators specifically in the final operand context that messes things up?
Because the match is in "statement position", it's interpreted as a statement rather than an expression. This is what allows you to not always require a ; after a block-like expression (e.g. match, if, or even regular blocks).
How the syntax is interpreted is decided long before types are available. Though it'd actually be much worse if blocks were conditionally statements or expressions depending on their type, as then parsing would become undecidable.
As such, this is a diagnostics issue. You get much better results from + than &, so there's maybe some hope at least... although, the + error is a syntax error and not a type error.
error: leading `+` is not supported
--> src/main.rs:5:7
|
5 | } + 0b00110000
| ^ unexpected `+`
|
help: parentheses are required to parse this as an expression
|
2 ~ (match input {
3 | true => 0b01 << 4,
4 | false => 0b00 << 4,
5 ~ }) + 0b00110000
|
This usually trips up context-free grammars (context-free because you cannot depend on the context to parse, the context here being the type returned by the match) when there is ambiguity with regards to the following token (in this case, & can mean take-reference or bitwise and).
When the parser sees match (or if for this matter), it has to decide whether to parse it as an expression or a statement.
Here it seems to prefer statement, and I can guess why: it is much more common for the & operator to actually be the following statement instead of a bit-wise operator.
I would say the following is probably quite common in code, and users will scream if it constantly gets parsed as a bitwise &...
Your example is different because it's not about semicolon elision but rather about comma elision in a match.
I couldn't find anything in the reference that the ambiguity is resolved in favor of always adding a comma there, but it looks like it is in practice, so either it needs to be documented, or it's a bug.