Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upWrapping expr in curly braces changes the operator precedence #28777
Comments
rprichard
referenced this issue
Sep 30, 2015
Open
Field access of block: discrepancy between parser-lalr and rustc #28379
rprichard
changed the title
Operator precedence problem with `nonblock_expr`
Wrapping expr in curly braces changes the operator precedence
Oct 1, 2015
steveklabnik
added
the
A-lang
label
Oct 4, 2015
This comment has been minimized.
This comment has been minimized.
|
/cc @rust-lang/lang , I'm assuming this is not intended behavior. |
This comment has been minimized.
This comment has been minimized.
|
Um, I agree. triage: P-medium |
rust-highfive
added
the
P-medium
label
Oct 6, 2015
nikomatsakis
added
T-compiler
A-parser
labels
Oct 6, 2015
This comment has been minimized.
This comment has been minimized.
|
In looking at this issue, the incorrect parse (the initializer for v1 in the example, though this occurs in an assignment as well) stems from the path to parse_assoc_expr_with from parse_block_expr (passing through, of note, parse_stmt_). In parse_stmt_, parse_expr_res is invoked with RESTRICTION_STMT_EXPR. This ultimately results in the expr_is_complete check (in parse_assoc_expr_with) succeeding for '{2}' which prevents matching the '*' token and, thus, building the expected right subtree. I am new to this codebase (and, for the most part, this language), so I am sill looking into the 'expr_is_complete' aspect of this portion of the parser. |
This comment has been minimized.
This comment has been minimized.
|
uh wow; I was going to ask if this is related to #15300 , but this seems much worse than that to my eye... |
This comment has been minimized.
This comment has been minimized.
|
As the comment in parser.rs alludes to in regards to semi-statements, this issue is related to #29071. The outermost braces trigger a flag to check for expressions that do not require a semicolon to in order to be considered statements (e.g., if). If such an expression is found, then the parsing of associative expressions is terminated before consuming the next operator. This occurs in the original examples after the '{2}' because the block does not require a semicolon to be considered a statement. For instance, the following illustrates the same parsing issue as the original example.
Removing the addition operator in the first expression results in a parse but with a typing error (to an extent further illustrating that the semi-statement is being considered a statement here; the same is true of the original binding for v1, but falling out of the recursion grabs the '* {3}').
I see that this all really goes back to #28379 (from which this issue was split) wherein @nikomatsakis states that a statement expression cannot start a binary expression when in statement position. The restriction flag makes it such that in '{ 1 + {2} * 3 }' it looks like '{2}' is in statement position for the subexpression '{2} * 3' (but it would not be considered as such if the original expression were '{ 1 + {2} + 3 }' because it appears as the right-operand of the first + instead of the left-operand of the *). If the intent is that the start of a binary expression cannot be a statement-expression, but subsequent subexpressions can be, then it may be sufficient to remove the restriction when parsing the rhs (i.e., after an operator is accepted). Doing so in the original example given corrects the parsing (precedence) issue. The tests are still running to check for introduced failures. |
This comment has been minimized.
This comment has been minimized.
|
The proposed change results in parse-fail/assoc-oddities-3.rs successfully parsing. It is unclear to me why it shouldn't. Back to looking through the intended grammar.
|
aaronkeen
added a commit
to aaronkeen/rust
that referenced
this issue
Dec 14, 2015
This comment has been minimized.
This comment has been minimized.
|
parse-fail/assoc-oddities-3.rs is successfully parsed by grammar/parser-lalr as well, so the proposed modification is consistent in this regard. |
rprichard commentedSep 30, 2015
This program prints different values depending upon whether the
v1orv2initializer is surrounded by curly braces:I think it should print
7for both lines.parser-lalr -vaccepts this program and consistently parses 1 + (2 * 3) for both lines.