-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Fix precedence of '..' range notation and some grammar inconsistencies. #20958
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Fixes rust-lang#20811 and rust-lang#20241. Note: this changes the semantics of parse_more_binops() to parse binops with precedence >= min_prec. Previously, it would parse binops with precedence > min_prec.
false | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this ensures that [a]..[b]
is still treated as ([a])..([b])
rather than ([a]..)[b]
, which is good. It's unlikely to break, but it might be worth putting a test in for that case anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I definitely think we want tests for a few such cases.
Sorry for taking a while on this. I wanted to carve out some time to get my head into the right space. |
An immediate thought is that I would like to see some tests of the traditional ambiguities, e.g.: let x = 3;
if ..x == ..x { ... } Also struct Foo { x: uint }
if ..Foo { x: 3 } == ..Foo { x: 3} { ... } I expect the latter to fail parsing however. |
Why exactly do we want |
@@ -2856,7 +2856,7 @@ impl<'a> Parser<'a> { | |||
} | |||
|
|||
// Otherwise, we use the unique pointer default. | |||
let subexpression = self.parse_prefix_expr(); | |||
let subexpression = self.parse_prefix_expr(prefix_prec); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this means that box ..5
does not parse, which I consider a bug. I'm not really clear on why we change from min_prec
to prefix_prec
here.
OK, I left my initial round of comments on dgrunwald@a128662. By and large this seems very nice; I much prefer the I'd like to ponder the |
On
With |
On Thu, Jan 15, 2015 at 11:01:39AM -0800, Daniel Grunwald wrote:
I think the root of my concern is that I think that the precedence of
Even if we assume the first parse is correct (contra #21192), I think what is confusing me a bit is that
I understand the motivation, but it seems to be achieved by |
There are two unary
The grammar is ambiguous with this choice of operator precedence for If anything, this is an argument that the choice of precedence for Then again, we already have some other disambiguation decisions that are pretty specific to a recursive-descent parser implementation (for example, treating the I should maybe separate this pull request into two PRs - one for fixing the grammar inconsistencies while keeping the current precedence (same as assignment operator), and another that increases the precedence to the level suggested here. |
Note that I'd like to keep
|
I guess I don't particularly expect |
What I meant by arbitrary is that the rule kind of picks and chooses what expressions work and which don't, rather than just saying 'a .. XXX' always parses XXX as an expression if it can. However, it occurs to me that there is a forwards compatibility risk we should be aware of here, similar to macros. If we added new unary operators it might cause a problem. |
#21374 is an alternative to this PR. It fixes the same grammar inconsistencies, but keeps the operator precedence of |
This PR is intended as alternative to #20958. It fixes the same grammar inconsistencies, but does not increase the operator precedence of `..`, leaving it at the same level as the assignment operator. For previous discussion, see #20811 and #20958. Grammar changes: * allow `for _ in 1..i {}` (fixes #20241) * allow `for _ in 1.. {}` as infinite loop * prevent use of range notation in contexts where only operators of high precedence are expected (fixes #20811) Parser code cleanup: * remove `RESTRICTION_NO_DOTS` * make `AS_PREC` const and follow naming convention * make `min_prec` inclusive r? nikomatsakis
Fixes #20811 and #20241.
..
precedence changed to between comparison operators and bit or; using the formal grammar:r == 1.. && condition
),&&
and||
are parsed as binary operators, other tokens are parsed as prefix operators.for i in 1.. {}
is parsed asfor i in (1..) {}
Implementation note: this changes the semantics of
parse_more_binops()
to parse binops withprecedence >= min_prec
.Previously, it would parse binops with
precedence > min_prec
.