Skip to content

Commit d11bfba

Browse files
committed
rollup merge of #20720: nick29581/assoc-ice-missing
2 parents 6621325 + 68a783a commit d11bfba

File tree

3 files changed

+105
-22
lines changed

3 files changed

+105
-22
lines changed

src/libcore/ops.rs

+33-4
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ use clone::Clone;
6565
use iter::{Step, Iterator,DoubleEndedIterator,ExactSizeIterator};
6666
use marker::Sized;
6767
use option::Option::{self, Some, None};
68+
use fmt;
6869

6970
/// The `Drop` trait is used to run some code when a value goes out of scope. This
7071
/// is sometimes called a 'destructor'.
@@ -847,13 +848,20 @@ pub trait IndexMut<Index: ?Sized> {
847848
}
848849

849850
/// An unbounded range.
850-
#[derive(Copy)]
851+
#[derive(Copy, PartialEq, Eq)]
851852
#[lang="full_range"]
852853
#[unstable = "API still in development"]
853854
pub struct FullRange;
854855

856+
#[unstable = "API still in development"]
857+
impl fmt::Show for FullRange {
858+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
859+
fmt::Show::fmt("..", fmt)
860+
}
861+
}
862+
855863
/// A (half-open) range which is bounded at both ends.
856-
#[derive(Copy)]
864+
#[derive(Copy, PartialEq, Eq)]
857865
#[lang="range"]
858866
#[unstable = "API still in development"]
859867
pub struct Range<Idx> {
@@ -904,8 +912,15 @@ impl<Idx: Clone + Step> DoubleEndedIterator for Range<Idx> {
904912
#[unstable = "API still in development"]
905913
impl<Idx: Clone + Step> ExactSizeIterator for Range<Idx> {}
906914

915+
#[unstable = "API still in development"]
916+
impl<Idx: fmt::Show> fmt::Show for Range<Idx> {
917+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
918+
write!(fmt, "{:?}..{:?}", self.start, self.end)
919+
}
920+
}
921+
907922
/// A range which is only bounded below.
908-
#[derive(Copy)]
923+
#[derive(Copy, PartialEq, Eq)]
909924
#[lang="range_from"]
910925
#[unstable = "API still in development"]
911926
pub struct RangeFrom<Idx> {
@@ -926,15 +941,29 @@ impl<Idx: Clone + Step> Iterator for RangeFrom<Idx> {
926941
}
927942
}
928943

944+
#[unstable = "API still in development"]
945+
impl<Idx: fmt::Show> fmt::Show for RangeFrom<Idx> {
946+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
947+
write!(fmt, "{:?}..", self.start)
948+
}
949+
}
950+
929951
/// A range which is only bounded above.
930-
#[derive(Copy)]
952+
#[derive(Copy, PartialEq, Eq)]
931953
#[lang="range_to"]
932954
#[unstable = "API still in development"]
933955
pub struct RangeTo<Idx> {
934956
/// The upper bound of the range (exclusive).
935957
pub end: Idx,
936958
}
937959

960+
#[unstable = "API still in development"]
961+
impl<Idx: fmt::Show> fmt::Show for RangeTo<Idx> {
962+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
963+
write!(fmt, "..{:?}", self.end)
964+
}
965+
}
966+
938967

939968
/// The `Deref` trait is used to specify the functionality of dereferencing
940969
/// operations like `*v`.

src/libsyntax/parse/parser.rs

+20-18
Original file line numberDiff line numberDiff line change
@@ -2535,7 +2535,7 @@ impl<'a> Parser<'a> {
25352535
}
25362536

25372537
// expr[...]
2538-
// An index expression.
2538+
// Could be either an index expression or a slicing expression.
25392539
token::OpenDelim(token::Bracket) => {
25402540
let bracket_pos = self.span.lo;
25412541
self.bump();
@@ -2575,22 +2575,6 @@ impl<'a> Parser<'a> {
25752575
"use `&expr[]` to construct a slice of the whole of expr");
25762576
}
25772577
}
2578-
2579-
// A range expression, either `expr..expr` or `expr..`.
2580-
token::DotDot if !self.restrictions.contains(RESTRICTION_NO_DOTS) => {
2581-
self.bump();
2582-
2583-
let opt_end = if self.token.can_begin_expr() {
2584-
let end = self.parse_expr_res(RESTRICTION_NO_DOTS);
2585-
Some(end)
2586-
} else {
2587-
None
2588-
};
2589-
2590-
let hi = self.span.hi;
2591-
let range = self.mk_range(Some(e), opt_end);
2592-
return self.mk_expr(lo, hi, range);
2593-
}
25942578
_ => return e
25952579
}
25962580
}
@@ -2833,7 +2817,7 @@ impl<'a> Parser<'a> {
28332817
token::DotDot if !self.restrictions.contains(RESTRICTION_NO_DOTS) => {
28342818
// A range, closed above: `..expr`.
28352819
self.bump();
2836-
let e = self.parse_prefix_expr();
2820+
let e = self.parse_expr();
28372821
hi = e.span.hi;
28382822
ex = self.mk_range(None, Some(e));
28392823
}
@@ -2900,6 +2884,7 @@ impl<'a> Parser<'a> {
29002884
self.restrictions.contains(RESTRICTION_NO_BAR_OP) {
29012885
return lhs;
29022886
}
2887+
29032888
self.expected_tokens.push(TokenType::Operator);
29042889

29052890
let cur_opt = self.token.to_binop();
@@ -2991,6 +2976,23 @@ impl<'a> Parser<'a> {
29912976
let assign_op = self.mk_assign_op(aop, lhs, rhs);
29922977
self.mk_expr(span.lo, rhs_span.hi, assign_op)
29932978
}
2979+
// A range expression, either `expr..expr` or `expr..`.
2980+
token::DotDot if !self.restrictions.contains(RESTRICTION_NO_DOTS) => {
2981+
self.bump();
2982+
2983+
let opt_end = if self.token.can_begin_expr() {
2984+
let end = self.parse_expr_res(RESTRICTION_NO_DOTS);
2985+
Some(end)
2986+
} else {
2987+
None
2988+
};
2989+
2990+
let lo = lhs.span.lo;
2991+
let hi = self.span.hi;
2992+
let range = self.mk_range(Some(lhs), opt_end);
2993+
return self.mk_expr(lo, hi, range);
2994+
}
2995+
29942996
_ => {
29952997
lhs
29962998
}
+52
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)