Skip to content

Commit 63a9bd5

Browse files
committed
Fix precedence for ranges.
Technically this is a [breaking-change] but it probably shouldn't affect your code. Closes #20256
1 parent e15f043 commit 63a9bd5

File tree

2 files changed

+75
-18
lines changed

2 files changed

+75
-18
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2536,7 +2536,7 @@ impl<'a> Parser<'a> {
25362536
}
25372537

25382538
// expr[...]
2539-
// An index expression.
2539+
// Could be either an index expression or a slicing expression.
25402540
token::OpenDelim(token::Bracket) => {
25412541
let bracket_pos = self.span.lo;
25422542
self.bump();
@@ -2576,22 +2576,6 @@ impl<'a> Parser<'a> {
25762576
"use `&expr[]` to construct a slice of the whole of expr");
25772577
}
25782578
}
2579-
2580-
// A range expression, either `expr..expr` or `expr..`.
2581-
token::DotDot if !self.restrictions.contains(RESTRICTION_NO_DOTS) => {
2582-
self.bump();
2583-
2584-
let opt_end = if self.token.can_begin_expr() {
2585-
let end = self.parse_expr_res(RESTRICTION_NO_DOTS);
2586-
Some(end)
2587-
} else {
2588-
None
2589-
};
2590-
2591-
let hi = self.span.hi;
2592-
let range = self.mk_range(Some(e), opt_end);
2593-
return self.mk_expr(lo, hi, range);
2594-
}
25952579
_ => return e
25962580
}
25972581
}
@@ -2834,7 +2818,7 @@ impl<'a> Parser<'a> {
28342818
token::DotDot if !self.restrictions.contains(RESTRICTION_NO_DOTS) => {
28352819
// A range, closed above: `..expr`.
28362820
self.bump();
2837-
let e = self.parse_prefix_expr();
2821+
let e = self.parse_expr();
28382822
hi = e.span.hi;
28392823
ex = self.mk_range(None, Some(e));
28402824
}
@@ -2901,6 +2885,7 @@ impl<'a> Parser<'a> {
29012885
self.restrictions.contains(RESTRICTION_NO_BAR_OP) {
29022886
return lhs;
29032887
}
2888+
29042889
self.expected_tokens.push(TokenType::Operator);
29052890

29062891
let cur_opt = self.token.to_binop();
@@ -2909,6 +2894,7 @@ impl<'a> Parser<'a> {
29092894
let cur_prec = operator_prec(cur_op);
29102895
if cur_prec > min_prec {
29112896
self.bump();
2897+
// TODO
29122898
let expr = self.parse_prefix_expr();
29132899
let rhs = self.parse_more_binops(expr, cur_prec);
29142900
let lhs_span = lhs.span;
@@ -2970,6 +2956,25 @@ impl<'a> Parser<'a> {
29702956
let assign_op = self.mk_assign_op(aop, lhs, rhs);
29712957
self.mk_expr(span.lo, rhs_span.hi, assign_op)
29722958
}
2959+
// TODO
2960+
// A range expression, either `expr..expr` or `expr..`.
2961+
token::DotDot if !self.restrictions.contains(RESTRICTION_NO_DOTS) => {
2962+
self.bump();
2963+
2964+
let opt_end = if self.token.can_begin_expr() {
2965+
// TODO only use of RES...DOT
2966+
let end = self.parse_expr_res(RESTRICTION_NO_DOTS);
2967+
Some(end)
2968+
} else {
2969+
None
2970+
};
2971+
2972+
let lo = lhs.span.lo;
2973+
let hi = self.span.hi;
2974+
let range = self.mk_range(Some(lhs), opt_end);
2975+
return self.mk_expr(lo, hi, range);
2976+
}
2977+
29732978
_ => {
29742979
lhs
29752980
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that the precedence of ranges is correct
12+
13+
#![feature(slicing_syntax)]
14+
15+
struct Foo {
16+
foo: uint,
17+
}
18+
19+
impl Foo {
20+
fn bar(&self) -> uint { 5 }
21+
}
22+
23+
fn main() {
24+
let x = 1+3..4+5;
25+
assert!(x == (4..9));
26+
27+
let x = 1..4+5;
28+
assert!(x == (1..9));
29+
30+
let x = 1+3..4;
31+
assert!(x == (4..4));
32+
33+
let a = Foo { foo: 3 };
34+
let x = a.foo..a.bar();
35+
assert!(x == (3..5));
36+
37+
let x = 1+3..;
38+
assert!(x == (4..));
39+
let x = ..1+3;
40+
assert!(x == (..4));
41+
42+
let a = &[0i32, 1, 2, 3, 4, 5, 6];
43+
let x = &a[1+1..2+2];
44+
assert!(x == &a[2..4]);
45+
let x = &a[..1+2];
46+
assert!(x == &a[..3]);
47+
let x = &a[1+2..];
48+
assert!(x == &a[3..]);
49+
50+
for _i in 2+4..10-3 {}
51+
}
52+

0 commit comments

Comments
 (0)