Description
According to section 8.2 Expressions, AsyncBlockExpressions are classified as ExpressionWithBlock while rustc
parses them as if they were an ExpressionWithoutBlock.
If AsyncBlockExpression was an ExpressionWithBlock, the following code would be syntactically malformed. In reality however, rustc
successfully parses it!
fn main() {
#[cfg(FALSE)]
match () { () => async { () }[..] }
}
You can experiment with the code above by replacing async
with unsafe
/ loop
(true ExpressionWithBlocks) or an empty string (making it a BlockExpression which is also a true ExpressionWithBlock) and observing that the compiler rightfully reports a syntax error.
Explanation of the test snippet:
For an ExpressionWithBlock, the block ends the expression and the comma at the end of a match arm is optional. Meaning if there isn't one, we immediately expect a pattern (in this case we find [..]
– a slice pattern) followed by =>
(here we find }
and emit a syntax error). For an ExpressionWithoutBlock on the other hand, we continue to parse an expression after the end of the block, interpret the [..]
as being part of an IndexExpression and succeed.
The reference and the (reference) compiler are in disagreement here. I am not sure who is right. I couldn't find any mention of this in RFC 2394. Should I instead / additionally create an issue at the rust-lang/rust repo?
This issue was first discovered on Zulip when investigating the same issue for the experimental inline consts (ConstBlockExpressions). For the latter, the issue was acknowledged but no straightforward answer could be found and a note was added to its tracking issue.
@rustbot label Bug A-async A-grammar
(hmm, labeling does not work despite the existence of triagebot.toml
in the root folder and the rule set relabel.allow-unauthenticated
within it)