rollup merge of #20720: nick29581/assoc-ice-missing
This commit is contained in:
commit
d11bfba71b
|
@ -65,6 +65,7 @@ use clone::Clone;
|
||||||
use iter::{Step, Iterator,DoubleEndedIterator,ExactSizeIterator};
|
use iter::{Step, Iterator,DoubleEndedIterator,ExactSizeIterator};
|
||||||
use marker::Sized;
|
use marker::Sized;
|
||||||
use option::Option::{self, Some, None};
|
use option::Option::{self, Some, None};
|
||||||
|
use fmt;
|
||||||
|
|
||||||
/// The `Drop` trait is used to run some code when a value goes out of scope. This
|
/// The `Drop` trait is used to run some code when a value goes out of scope. This
|
||||||
/// is sometimes called a 'destructor'.
|
/// is sometimes called a 'destructor'.
|
||||||
|
@ -847,13 +848,20 @@ pub trait IndexMut<Index: ?Sized> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An unbounded range.
|
/// An unbounded range.
|
||||||
#[derive(Copy)]
|
#[derive(Copy, PartialEq, Eq)]
|
||||||
#[lang="full_range"]
|
#[lang="full_range"]
|
||||||
#[unstable = "API still in development"]
|
#[unstable = "API still in development"]
|
||||||
pub struct FullRange;
|
pub struct FullRange;
|
||||||
|
|
||||||
|
#[unstable = "API still in development"]
|
||||||
|
impl fmt::Show for FullRange {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
fmt::Show::fmt("..", fmt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A (half-open) range which is bounded at both ends.
|
/// A (half-open) range which is bounded at both ends.
|
||||||
#[derive(Copy)]
|
#[derive(Copy, PartialEq, Eq)]
|
||||||
#[lang="range"]
|
#[lang="range"]
|
||||||
#[unstable = "API still in development"]
|
#[unstable = "API still in development"]
|
||||||
pub struct Range<Idx> {
|
pub struct Range<Idx> {
|
||||||
|
@ -904,8 +912,15 @@ impl<Idx: Clone + Step> DoubleEndedIterator for Range<Idx> {
|
||||||
#[unstable = "API still in development"]
|
#[unstable = "API still in development"]
|
||||||
impl<Idx: Clone + Step> ExactSizeIterator for Range<Idx> {}
|
impl<Idx: Clone + Step> ExactSizeIterator for Range<Idx> {}
|
||||||
|
|
||||||
|
#[unstable = "API still in development"]
|
||||||
|
impl<Idx: fmt::Show> fmt::Show for Range<Idx> {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(fmt, "{:?}..{:?}", self.start, self.end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A range which is only bounded below.
|
/// A range which is only bounded below.
|
||||||
#[derive(Copy)]
|
#[derive(Copy, PartialEq, Eq)]
|
||||||
#[lang="range_from"]
|
#[lang="range_from"]
|
||||||
#[unstable = "API still in development"]
|
#[unstable = "API still in development"]
|
||||||
pub struct RangeFrom<Idx> {
|
pub struct RangeFrom<Idx> {
|
||||||
|
@ -926,8 +941,15 @@ impl<Idx: Clone + Step> Iterator for RangeFrom<Idx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unstable = "API still in development"]
|
||||||
|
impl<Idx: fmt::Show> fmt::Show for RangeFrom<Idx> {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(fmt, "{:?}..", self.start)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A range which is only bounded above.
|
/// A range which is only bounded above.
|
||||||
#[derive(Copy)]
|
#[derive(Copy, PartialEq, Eq)]
|
||||||
#[lang="range_to"]
|
#[lang="range_to"]
|
||||||
#[unstable = "API still in development"]
|
#[unstable = "API still in development"]
|
||||||
pub struct RangeTo<Idx> {
|
pub struct RangeTo<Idx> {
|
||||||
|
@ -935,6 +957,13 @@ pub struct RangeTo<Idx> {
|
||||||
pub end: Idx,
|
pub end: Idx,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unstable = "API still in development"]
|
||||||
|
impl<Idx: fmt::Show> fmt::Show for RangeTo<Idx> {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(fmt, "..{:?}", self.end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// The `Deref` trait is used to specify the functionality of dereferencing
|
/// The `Deref` trait is used to specify the functionality of dereferencing
|
||||||
/// operations like `*v`.
|
/// operations like `*v`.
|
||||||
|
|
|
@ -2535,7 +2535,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// expr[...]
|
// expr[...]
|
||||||
// An index expression.
|
// Could be either an index expression or a slicing expression.
|
||||||
token::OpenDelim(token::Bracket) => {
|
token::OpenDelim(token::Bracket) => {
|
||||||
let bracket_pos = self.span.lo;
|
let bracket_pos = self.span.lo;
|
||||||
self.bump();
|
self.bump();
|
||||||
|
@ -2575,22 +2575,6 @@ impl<'a> Parser<'a> {
|
||||||
"use `&expr[]` to construct a slice of the whole of expr");
|
"use `&expr[]` to construct a slice of the whole of expr");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A range expression, either `expr..expr` or `expr..`.
|
|
||||||
token::DotDot if !self.restrictions.contains(RESTRICTION_NO_DOTS) => {
|
|
||||||
self.bump();
|
|
||||||
|
|
||||||
let opt_end = if self.token.can_begin_expr() {
|
|
||||||
let end = self.parse_expr_res(RESTRICTION_NO_DOTS);
|
|
||||||
Some(end)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let hi = self.span.hi;
|
|
||||||
let range = self.mk_range(Some(e), opt_end);
|
|
||||||
return self.mk_expr(lo, hi, range);
|
|
||||||
}
|
|
||||||
_ => return e
|
_ => return e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2833,7 +2817,7 @@ impl<'a> Parser<'a> {
|
||||||
token::DotDot if !self.restrictions.contains(RESTRICTION_NO_DOTS) => {
|
token::DotDot if !self.restrictions.contains(RESTRICTION_NO_DOTS) => {
|
||||||
// A range, closed above: `..expr`.
|
// A range, closed above: `..expr`.
|
||||||
self.bump();
|
self.bump();
|
||||||
let e = self.parse_prefix_expr();
|
let e = self.parse_expr();
|
||||||
hi = e.span.hi;
|
hi = e.span.hi;
|
||||||
ex = self.mk_range(None, Some(e));
|
ex = self.mk_range(None, Some(e));
|
||||||
}
|
}
|
||||||
|
@ -2900,6 +2884,7 @@ impl<'a> Parser<'a> {
|
||||||
self.restrictions.contains(RESTRICTION_NO_BAR_OP) {
|
self.restrictions.contains(RESTRICTION_NO_BAR_OP) {
|
||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.expected_tokens.push(TokenType::Operator);
|
self.expected_tokens.push(TokenType::Operator);
|
||||||
|
|
||||||
let cur_opt = self.token.to_binop();
|
let cur_opt = self.token.to_binop();
|
||||||
|
@ -2991,6 +2976,23 @@ impl<'a> Parser<'a> {
|
||||||
let assign_op = self.mk_assign_op(aop, lhs, rhs);
|
let assign_op = self.mk_assign_op(aop, lhs, rhs);
|
||||||
self.mk_expr(span.lo, rhs_span.hi, assign_op)
|
self.mk_expr(span.lo, rhs_span.hi, assign_op)
|
||||||
}
|
}
|
||||||
|
// A range expression, either `expr..expr` or `expr..`.
|
||||||
|
token::DotDot if !self.restrictions.contains(RESTRICTION_NO_DOTS) => {
|
||||||
|
self.bump();
|
||||||
|
|
||||||
|
let opt_end = if self.token.can_begin_expr() {
|
||||||
|
let end = self.parse_expr_res(RESTRICTION_NO_DOTS);
|
||||||
|
Some(end)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let lo = lhs.span.lo;
|
||||||
|
let hi = self.span.hi;
|
||||||
|
let range = self.mk_range(Some(lhs), opt_end);
|
||||||
|
return self.mk_expr(lo, hi, range);
|
||||||
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
lhs
|
lhs
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// Test that the precedence of ranges is correct
|
||||||
|
|
||||||
|
#![feature(slicing_syntax)]
|
||||||
|
|
||||||
|
struct Foo {
|
||||||
|
foo: uint,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
fn bar(&self) -> uint { 5 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = 1+3..4+5;
|
||||||
|
assert!(x == (4..9));
|
||||||
|
|
||||||
|
let x = 1..4+5;
|
||||||
|
assert!(x == (1..9));
|
||||||
|
|
||||||
|
let x = 1+3..4;
|
||||||
|
assert!(x == (4..4));
|
||||||
|
|
||||||
|
let a = Foo { foo: 3 };
|
||||||
|
let x = a.foo..a.bar();
|
||||||
|
assert!(x == (3..5));
|
||||||
|
|
||||||
|
let x = 1+3..;
|
||||||
|
assert!(x == (4..));
|
||||||
|
let x = ..1+3;
|
||||||
|
assert!(x == (..4));
|
||||||
|
|
||||||
|
let a = &[0i32, 1, 2, 3, 4, 5, 6];
|
||||||
|
let x = &a[1+1..2+2];
|
||||||
|
assert!(x == &a[2..4]);
|
||||||
|
let x = &a[..1+2];
|
||||||
|
assert!(x == &a[..3]);
|
||||||
|
let x = &a[1+2..];
|
||||||
|
assert!(x == &a[3..]);
|
||||||
|
|
||||||
|
for _i in 2+4..10-3 {}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue