mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 09:44:08 +00:00
auto merge of #20160 : nick29581/rust/ranges2, r=nikomatsakis
The first six commits are from an earlier PR (#19858) and have already been reviewed. This PR makes an awful hack in the compiler to accommodate slices both natively and in the index a range form. After a snapshot we can hopefully add the new Index impls and then we can remove these awful hacks. r? @nikomatsakis (or anyone who knows the compiler, really)
This commit is contained in:
commit
fea5aa656f
@ -453,7 +453,7 @@ impl<T> RingBuf<T> {
|
|||||||
|
|
||||||
if contiguous {
|
if contiguous {
|
||||||
let (empty, buf) = buf.split_at_mut(0);
|
let (empty, buf) = buf.split_at_mut(0);
|
||||||
(buf[mut tail..head], empty)
|
(buf.slice_mut(tail, head), empty)
|
||||||
} else {
|
} else {
|
||||||
let (mid, right) = buf.split_at_mut(tail);
|
let (mid, right) = buf.split_at_mut(tail);
|
||||||
let (left, _) = mid.split_at_mut(head);
|
let (left, _) = mid.split_at_mut(head);
|
||||||
|
@ -94,7 +94,7 @@ use core::iter::{range_step, MultiplicativeIterator};
|
|||||||
use core::kinds::Sized;
|
use core::kinds::Sized;
|
||||||
use core::mem::size_of;
|
use core::mem::size_of;
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::ops::FnMut;
|
use core::ops::{FnMut,SliceMut};
|
||||||
use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option};
|
use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option};
|
||||||
use core::prelude::{Ord, Ordering, RawPtr, Some, range};
|
use core::prelude::{Ord, Ordering, RawPtr, Some, range};
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
@ -1110,7 +1110,7 @@ impl<T> SliceExt<T> for [T] {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn move_from(&mut self, mut src: Vec<T>, start: uint, end: uint) -> uint {
|
fn move_from(&mut self, mut src: Vec<T>, start: uint, end: uint) -> uint {
|
||||||
for (a, b) in self.iter_mut().zip(src[mut start..end].iter_mut()) {
|
for (a, b) in self.iter_mut().zip(src.slice_mut(start, end).iter_mut()) {
|
||||||
mem::swap(a, b);
|
mem::swap(a, b);
|
||||||
}
|
}
|
||||||
cmp::min(self.len(), end-start)
|
cmp::min(self.len(), end-start)
|
||||||
@ -1326,7 +1326,7 @@ impl<T> BorrowFrom<Vec<T>> for [T] {
|
|||||||
|
|
||||||
#[unstable = "trait is unstable"]
|
#[unstable = "trait is unstable"]
|
||||||
impl<T> BorrowFromMut<Vec<T>> for [T] {
|
impl<T> BorrowFromMut<Vec<T>> for [T] {
|
||||||
fn borrow_from_mut(owned: &mut Vec<T>) -> &mut [T] { owned[mut] }
|
fn borrow_from_mut(owned: &mut Vec<T>) -> &mut [T] { owned.as_mut_slice_() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable = "trait is unstable"]
|
#[unstable = "trait is unstable"]
|
||||||
@ -2491,14 +2491,14 @@ mod tests {
|
|||||||
assert!(a == [7i,2,3,4]);
|
assert!(a == [7i,2,3,4]);
|
||||||
let mut a = [1i,2,3,4,5];
|
let mut a = [1i,2,3,4,5];
|
||||||
let b = vec![5i,6,7,8,9,0];
|
let b = vec![5i,6,7,8,9,0];
|
||||||
assert_eq!(a[mut 2..4].move_from(b,1,6), 2);
|
assert_eq!(a.slice_mut(2, 4).move_from(b,1,6), 2);
|
||||||
assert!(a == [1i,2,6,7,5]);
|
assert!(a == [1i,2,6,7,5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_reverse_part() {
|
fn test_reverse_part() {
|
||||||
let mut values = [1i,2,3,4,5];
|
let mut values = [1i,2,3,4,5];
|
||||||
values[mut 1..4].reverse();
|
values.slice_mut(1, 4).reverse();
|
||||||
assert!(values == [1,4,3,2,5]);
|
assert!(values == [1,4,3,2,5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2545,9 +2545,9 @@ mod tests {
|
|||||||
fn test_bytes_set_memory() {
|
fn test_bytes_set_memory() {
|
||||||
use slice::bytes::MutableByteVector;
|
use slice::bytes::MutableByteVector;
|
||||||
let mut values = [1u8,2,3,4,5];
|
let mut values = [1u8,2,3,4,5];
|
||||||
values[mut 0..5].set_memory(0xAB);
|
values.slice_mut(0, 5).set_memory(0xAB);
|
||||||
assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
|
assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
|
||||||
values[mut 2..4].set_memory(0xFF);
|
values.slice_mut(2, 4).set_memory(0xFF);
|
||||||
assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
|
assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
|
|||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[mut ..end].reverse();
|
buf.slice_to_mut(end).reverse();
|
||||||
|
|
||||||
// Remember start of the fractional digits.
|
// Remember start of the fractional digits.
|
||||||
// Points one beyond end of buf if none get generated,
|
// Points one beyond end of buf if none get generated,
|
||||||
@ -316,7 +316,7 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
|
|||||||
|
|
||||||
impl<'a> fmt::FormatWriter for Filler<'a> {
|
impl<'a> fmt::FormatWriter for Filler<'a> {
|
||||||
fn write(&mut self, bytes: &[u8]) -> fmt::Result {
|
fn write(&mut self, bytes: &[u8]) -> fmt::Result {
|
||||||
slice::bytes::copy_memory(self.buf[mut *self.end..],
|
slice::bytes::copy_memory(self.buf.slice_from_mut(*self.end),
|
||||||
bytes);
|
bytes);
|
||||||
*self.end += bytes.len();
|
*self.end += bytes.len();
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -908,6 +908,14 @@ impl<Idx: Clone + Step> Iterator<Idx> for RangeFrom<Idx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A range which is only bounded above.
|
||||||
|
#[deriving(Copy)]
|
||||||
|
#[lang="range_to"]
|
||||||
|
pub struct RangeTo<Idx> {
|
||||||
|
/// The upper bound of the range (exclusive).
|
||||||
|
pub end: Idx,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// 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`.
|
||||||
|
@ -264,24 +264,26 @@ impl<T> SliceExt<T> for [T] {
|
|||||||
fn as_mut_slice(&mut self) -> &mut [T] { self }
|
fn as_mut_slice(&mut self) -> &mut [T] { self }
|
||||||
|
|
||||||
fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T] {
|
fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T] {
|
||||||
self[mut start..end]
|
ops::SliceMut::slice_or_fail_mut(self, &start, &end)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn slice_from_mut(&mut self, start: uint) -> &mut [T] {
|
fn slice_from_mut(&mut self, start: uint) -> &mut [T] {
|
||||||
self[mut start..]
|
ops::SliceMut::slice_from_or_fail_mut(self, &start)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn slice_to_mut(&mut self, end: uint) -> &mut [T] {
|
fn slice_to_mut(&mut self, end: uint) -> &mut [T] {
|
||||||
self[mut ..end]
|
ops::SliceMut::slice_to_or_fail_mut(self, &end)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]) {
|
fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let self2: &mut [T] = mem::transmute_copy(&self);
|
let self2: &mut [T] = mem::transmute_copy(&self);
|
||||||
(self[mut ..mid], self2[mut mid..])
|
|
||||||
|
(ops::SliceMut::slice_to_or_fail_mut(self, &mid),
|
||||||
|
ops::SliceMut::slice_from_or_fail_mut(self2, &mid))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,14 +317,13 @@ impl<T> SliceExt<T> for [T] {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn tail_mut(&mut self) -> &mut [T] {
|
fn tail_mut(&mut self) -> &mut [T] {
|
||||||
let len = self.len();
|
self.slice_from_mut(1)
|
||||||
self[mut 1..len]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn init_mut(&mut self) -> &mut [T] {
|
fn init_mut(&mut self) -> &mut [T] {
|
||||||
let len = self.len();
|
let len = self.len();
|
||||||
self[mut 0..len - 1]
|
self.slice_to_mut(len-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -560,7 +561,7 @@ impl<T: Ord> OrdSliceExt<T> for [T] {
|
|||||||
self.swap(j, i-1);
|
self.swap(j, i-1);
|
||||||
|
|
||||||
// Step 4: Reverse the (previously) weakly decreasing part
|
// Step 4: Reverse the (previously) weakly decreasing part
|
||||||
self[mut i..].reverse();
|
self.slice_from_mut(i).reverse();
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -582,7 +583,7 @@ impl<T: Ord> OrdSliceExt<T> for [T] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: Reverse the weakly increasing part
|
// Step 2: Reverse the weakly increasing part
|
||||||
self[mut i..].reverse();
|
self.slice_from_mut(i).reverse();
|
||||||
|
|
||||||
// Step 3: Find the rightmost element equal to or bigger than the pivot (i-1)
|
// Step 3: Find the rightmost element equal to or bigger than the pivot (i-1)
|
||||||
let mut j = self.len() - 1;
|
let mut j = self.len() - 1;
|
||||||
@ -990,7 +991,7 @@ impl<'a, T, P> Iterator<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T)
|
|||||||
Some(idx) => {
|
Some(idx) => {
|
||||||
let tmp = mem::replace(&mut self.v, &mut []);
|
let tmp = mem::replace(&mut self.v, &mut []);
|
||||||
let (head, tail) = tmp.split_at_mut(idx);
|
let (head, tail) = tmp.split_at_mut(idx);
|
||||||
self.v = tail[mut 1..];
|
self.v = tail.slice_from_mut(1);
|
||||||
Some(head)
|
Some(head)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1026,7 +1027,7 @@ impl<'a, T, P> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T, P> where
|
|||||||
let tmp = mem::replace(&mut self.v, &mut []);
|
let tmp = mem::replace(&mut self.v, &mut []);
|
||||||
let (head, tail) = tmp.split_at_mut(idx);
|
let (head, tail) = tmp.split_at_mut(idx);
|
||||||
self.v = head;
|
self.v = head;
|
||||||
Some(tail[mut 1..])
|
Some(tail.slice_from_mut(1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -897,6 +897,7 @@ impl<'a> Iterator<&'a str> for SplitStr<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Section: Comparing strings
|
Section: Comparing strings
|
||||||
*/
|
*/
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
use core::ops::{Range, FullRange, RangeFrom};
|
use core::ops::{Range, FullRange, RangeFrom, RangeTo};
|
||||||
|
|
||||||
// Overhead of dtors
|
// Overhead of dtors
|
||||||
|
|
||||||
@ -55,6 +55,12 @@ fn test_range_from() {
|
|||||||
assert!(count == 10);
|
assert!(count == 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_range_to() {
|
||||||
|
// Not much to test.
|
||||||
|
let _ = RangeTo { end: 42u };
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_full_range() {
|
fn test_full_range() {
|
||||||
// Not much to test.
|
// Not much to test.
|
||||||
|
@ -735,7 +735,7 @@ mod tests {
|
|||||||
fn test_input(g: LabelledGraph) -> IoResult<String> {
|
fn test_input(g: LabelledGraph) -> IoResult<String> {
|
||||||
let mut writer = Vec::new();
|
let mut writer = Vec::new();
|
||||||
render(&g, &mut writer).unwrap();
|
render(&g, &mut writer).unwrap();
|
||||||
(&mut writer[]).read_to_string()
|
(&mut writer.as_slice()).read_to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
// All of the tests use raw-strings as the format for the expected outputs,
|
// All of the tests use raw-strings as the format for the expected outputs,
|
||||||
@ -847,7 +847,7 @@ r#"digraph hasse_diagram {
|
|||||||
edge(1, 3, ";"), edge(2, 3, ";" )));
|
edge(1, 3, ";"), edge(2, 3, ";" )));
|
||||||
|
|
||||||
render(&g, &mut writer).unwrap();
|
render(&g, &mut writer).unwrap();
|
||||||
let r = (&mut writer[]).read_to_string();
|
let r = (&mut writer.as_slice()).read_to_string();
|
||||||
|
|
||||||
assert_eq!(r.unwrap(),
|
assert_eq!(r.unwrap(),
|
||||||
r#"digraph syntax_tree {
|
r#"digraph syntax_tree {
|
||||||
|
@ -102,7 +102,7 @@ impl Writer for SeekableMemWriter {
|
|||||||
|
|
||||||
// Do the necessary writes
|
// Do the necessary writes
|
||||||
if left.len() > 0 {
|
if left.len() > 0 {
|
||||||
slice::bytes::copy_memory(self.buf[mut self.pos..], left);
|
slice::bytes::copy_memory(self.buf.slice_from_mut(self.pos), left);
|
||||||
}
|
}
|
||||||
if right.len() > 0 {
|
if right.len() > 0 {
|
||||||
self.buf.push_all(right);
|
self.buf.push_all(right);
|
||||||
|
@ -432,15 +432,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||||||
self.call(expr, pred, &**l, Some(&**r).into_iter())
|
self.call(expr, pred, &**l, Some(&**r).into_iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprSlice(ref base, ref start, ref end, _) => {
|
|
||||||
self.call(expr,
|
|
||||||
pred,
|
|
||||||
&**base,
|
|
||||||
start.iter().chain(end.iter()).map(|x| &**x))
|
|
||||||
}
|
|
||||||
|
|
||||||
ast::ExprRange(ref start, ref end) => {
|
ast::ExprRange(ref start, ref end) => {
|
||||||
let fields = Some(&**start).into_iter()
|
let fields = start.as_ref().map(|e| &**e).into_iter()
|
||||||
.chain(end.as_ref().map(|e| &**e).into_iter());
|
.chain(end.as_ref().map(|e| &**e).into_iter());
|
||||||
self.straightline(expr, pred, fields)
|
self.straightline(expr, pred, fields)
|
||||||
}
|
}
|
||||||
|
@ -431,26 +431,33 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprIndex(ref lhs, ref rhs) => { // lhs[rhs]
|
ast::ExprIndex(ref lhs, ref rhs) => { // lhs[rhs]
|
||||||
if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], PassArgs::ByRef) {
|
match rhs.node {
|
||||||
self.select_from_expr(&**lhs);
|
ast::ExprRange(ref start, ref end) => {
|
||||||
self.consume_expr(&**rhs);
|
// Hacked slicing syntax (KILLME).
|
||||||
|
let args = match (start, end) {
|
||||||
|
(&Some(ref e1), &Some(ref e2)) => vec![&**e1, &**e2],
|
||||||
|
(&Some(ref e), &None) => vec![&**e],
|
||||||
|
(&None, &Some(ref e)) => vec![&**e],
|
||||||
|
(&None, &None) => Vec::new()
|
||||||
|
};
|
||||||
|
let overloaded =
|
||||||
|
self.walk_overloaded_operator(expr, &**lhs, args, PassArgs::ByRef);
|
||||||
|
assert!(overloaded);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if !self.walk_overloaded_operator(expr,
|
||||||
|
&**lhs,
|
||||||
|
vec![&**rhs],
|
||||||
|
PassArgs::ByRef) {
|
||||||
|
self.select_from_expr(&**lhs);
|
||||||
|
self.consume_expr(&**rhs);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprSlice(ref base, ref start, ref end, _) => { // base[start..end]
|
|
||||||
let args = match (start, end) {
|
|
||||||
(&Some(ref e1), &Some(ref e2)) => vec![&**e1, &**e2],
|
|
||||||
(&Some(ref e), &None) => vec![&**e],
|
|
||||||
(&None, &Some(ref e)) => vec![&**e],
|
|
||||||
(&None, &None) => Vec::new()
|
|
||||||
};
|
|
||||||
let overloaded =
|
|
||||||
self.walk_overloaded_operator(expr, &**base, args, PassArgs::ByRef);
|
|
||||||
assert!(overloaded);
|
|
||||||
}
|
|
||||||
|
|
||||||
ast::ExprRange(ref start, ref end) => {
|
ast::ExprRange(ref start, ref end) => {
|
||||||
self.consume_expr(&**start);
|
start.as_ref().map(|e| self.consume_expr(&**e));
|
||||||
end.as_ref().map(|e| self.consume_expr(&**e));
|
end.as_ref().map(|e| self.consume_expr(&**e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,6 +269,7 @@ lets_do_this! {
|
|||||||
SliceMutTraitLangItem, "slice_mut", slice_mut_trait;
|
SliceMutTraitLangItem, "slice_mut", slice_mut_trait;
|
||||||
RangeStructLangItem, "range", range_struct;
|
RangeStructLangItem, "range", range_struct;
|
||||||
RangeFromStructLangItem, "range_from", range_from_struct;
|
RangeFromStructLangItem, "range_from", range_from_struct;
|
||||||
|
RangeToStructLangItem, "range_to", range_to_struct;
|
||||||
FullRangeStructLangItem, "full_range", full_range_struct;
|
FullRangeStructLangItem, "full_range", full_range_struct;
|
||||||
|
|
||||||
UnsafeTypeLangItem, "unsafe", unsafe_type;
|
UnsafeTypeLangItem, "unsafe", unsafe_type;
|
||||||
|
@ -514,7 +514,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
|
|||||||
ast::ExprBlock(..) | ast::ExprAssign(..) | ast::ExprAssignOp(..) |
|
ast::ExprBlock(..) | ast::ExprAssign(..) | ast::ExprAssignOp(..) |
|
||||||
ast::ExprMac(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
|
ast::ExprMac(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
|
||||||
ast::ExprParen(..) | ast::ExprInlineAsm(..) | ast::ExprBox(..) |
|
ast::ExprParen(..) | ast::ExprInlineAsm(..) | ast::ExprBox(..) |
|
||||||
ast::ExprSlice(..) | ast::ExprRange(..) => {
|
ast::ExprRange(..) => {
|
||||||
visit::walk_expr(ir, expr);
|
visit::walk_expr(ir, expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1191,15 +1191,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||||||
self.propagate_through_expr(&**l, r_succ)
|
self.propagate_through_expr(&**l, r_succ)
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprSlice(ref e1, ref e2, ref e3, _) => {
|
|
||||||
let succ = e3.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ));
|
|
||||||
let succ = e2.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ));
|
|
||||||
self.propagate_through_expr(&**e1, succ)
|
|
||||||
}
|
|
||||||
|
|
||||||
ast::ExprRange(ref e1, ref e2) => {
|
ast::ExprRange(ref e1, ref e2) => {
|
||||||
let succ = e2.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ));
|
let succ = e2.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ));
|
||||||
self.propagate_through_expr(&**e1, succ)
|
e1.as_ref().map_or(succ, |e| self.propagate_through_expr(&**e, succ))
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprBox(None, ref e) |
|
ast::ExprBox(None, ref e) |
|
||||||
@ -1495,7 +1489,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
|
|||||||
ast::ExprBlock(..) | ast::ExprMac(..) | ast::ExprAddrOf(..) |
|
ast::ExprBlock(..) | ast::ExprMac(..) | ast::ExprAddrOf(..) |
|
||||||
ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) |
|
ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) |
|
||||||
ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) |
|
ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) |
|
||||||
ast::ExprSlice(..) | ast::ExprRange(..) => {
|
ast::ExprRange(..) => {
|
||||||
visit::walk_expr(this, expr);
|
visit::walk_expr(this, expr);
|
||||||
}
|
}
|
||||||
ast::ExprIfLet(..) => {
|
ast::ExprIfLet(..) => {
|
||||||
|
@ -500,21 +500,28 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
|||||||
self.cat_tup_field(expr, base_cmt, idx.node, expr_ty)
|
self.cat_tup_field(expr, base_cmt, idx.node, expr_ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprIndex(ref base, _) => {
|
ast::ExprIndex(ref base, ref idx) => {
|
||||||
let method_call = ty::MethodCall::expr(expr.id());
|
match idx.node {
|
||||||
match self.typer.node_method_ty(method_call) {
|
ast::ExprRange(..) => {
|
||||||
Some(method_ty) => {
|
// Slicing syntax special case (KILLME).
|
||||||
// If this is an index implemented by a method call, then it will
|
self.cat_rvalue_node(expr.id(), expr.span(), expr_ty)
|
||||||
// include an implicit deref of the result.
|
|
||||||
let ret_ty = ty::ty_fn_ret(method_ty).unwrap();
|
|
||||||
self.cat_deref(expr,
|
|
||||||
self.cat_rvalue_node(expr.id(),
|
|
||||||
expr.span(),
|
|
||||||
ret_ty), 1, true)
|
|
||||||
}
|
}
|
||||||
None => {
|
_ => {
|
||||||
let base_cmt = self.cat_expr(&**base);
|
let method_call = ty::MethodCall::expr(expr.id());
|
||||||
self.cat_index(expr, base_cmt)
|
match self.typer.node_method_ty(method_call) {
|
||||||
|
Some(method_ty) => {
|
||||||
|
// If this is an index implemented by a method call, then it will
|
||||||
|
// include an implicit deref of the result.
|
||||||
|
let ret_ty = ty::ty_fn_ret(method_ty).unwrap();
|
||||||
|
self.cat_deref(expr,
|
||||||
|
self.cat_rvalue_node(expr.id(),
|
||||||
|
expr.span(),
|
||||||
|
ret_ty), 1, true)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.cat_index(expr, self.cat_expr(&**base))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -531,7 +538,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
|||||||
ast::ExprAddrOf(..) | ast::ExprCall(..) |
|
ast::ExprAddrOf(..) | ast::ExprCall(..) |
|
||||||
ast::ExprAssign(..) | ast::ExprAssignOp(..) |
|
ast::ExprAssign(..) | ast::ExprAssignOp(..) |
|
||||||
ast::ExprClosure(..) | ast::ExprRet(..) |
|
ast::ExprClosure(..) | ast::ExprRet(..) |
|
||||||
ast::ExprUnary(..) | ast::ExprSlice(..) | ast::ExprRange(..) |
|
ast::ExprUnary(..) | ast::ExprRange(..) |
|
||||||
ast::ExprMethodCall(..) | ast::ExprCast(..) |
|
ast::ExprMethodCall(..) | ast::ExprCast(..) |
|
||||||
ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) |
|
ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) |
|
||||||
ast::ExprBinary(..) | ast::ExprWhile(..) |
|
ast::ExprBinary(..) | ast::ExprWhile(..) |
|
||||||
|
@ -485,6 +485,7 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
|
|||||||
|
|
||||||
let prev_cx = visitor.cx;
|
let prev_cx = visitor.cx;
|
||||||
visitor.cx.parent = Some(expr.id);
|
visitor.cx.parent = Some(expr.id);
|
||||||
|
|
||||||
{
|
{
|
||||||
let region_maps = &mut visitor.region_maps;
|
let region_maps = &mut visitor.region_maps;
|
||||||
let terminating = |id| {
|
let terminating = |id| {
|
||||||
|
@ -4322,9 +4322,6 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
|
|||||||
// the index method invoked for `a[i]` always yields an `&T`
|
// the index method invoked for `a[i]` always yields an `&T`
|
||||||
ast::ExprIndex(..) => LvalueExpr,
|
ast::ExprIndex(..) => LvalueExpr,
|
||||||
|
|
||||||
// the slice method invoked for `a[..]` always yields an `&T`
|
|
||||||
ast::ExprSlice(..) => LvalueExpr,
|
|
||||||
|
|
||||||
// `for` loops are statements
|
// `for` loops are statements
|
||||||
ast::ExprForLoop(..) => RvalueStmtExpr,
|
ast::ExprForLoop(..) => RvalueStmtExpr,
|
||||||
|
|
||||||
@ -4389,8 +4386,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
|
|||||||
ast::ExprUnary(ast::UnDeref, _) |
|
ast::ExprUnary(ast::UnDeref, _) |
|
||||||
ast::ExprField(..) |
|
ast::ExprField(..) |
|
||||||
ast::ExprTupField(..) |
|
ast::ExprTupField(..) |
|
||||||
ast::ExprIndex(..) |
|
ast::ExprIndex(..) => {
|
||||||
ast::ExprSlice(..) => {
|
|
||||||
LvalueExpr
|
LvalueExpr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,14 +139,14 @@ impl FixedBuffer for FixedBuffer64 {
|
|||||||
let buffer_remaining = size - self.buffer_idx;
|
let buffer_remaining = size - self.buffer_idx;
|
||||||
if input.len() >= buffer_remaining {
|
if input.len() >= buffer_remaining {
|
||||||
copy_memory(
|
copy_memory(
|
||||||
self.buffer[mut self.buffer_idx..size],
|
self.buffer.slice_mut(self.buffer_idx, size),
|
||||||
input[..buffer_remaining]);
|
input[..buffer_remaining]);
|
||||||
self.buffer_idx = 0;
|
self.buffer_idx = 0;
|
||||||
func(&self.buffer);
|
func(&self.buffer);
|
||||||
i += buffer_remaining;
|
i += buffer_remaining;
|
||||||
} else {
|
} else {
|
||||||
copy_memory(
|
copy_memory(
|
||||||
self.buffer[mut self.buffer_idx..self.buffer_idx + input.len()],
|
self.buffer.slice_mut(self.buffer_idx, self.buffer_idx + input.len()),
|
||||||
input);
|
input);
|
||||||
self.buffer_idx += input.len();
|
self.buffer_idx += input.len();
|
||||||
return;
|
return;
|
||||||
@ -165,7 +165,7 @@ impl FixedBuffer for FixedBuffer64 {
|
|||||||
// be empty.
|
// be empty.
|
||||||
let input_remaining = input.len() - i;
|
let input_remaining = input.len() - i;
|
||||||
copy_memory(
|
copy_memory(
|
||||||
self.buffer[mut ..input_remaining],
|
self.buffer.slice_to_mut(input_remaining),
|
||||||
input[i..]);
|
input[i..]);
|
||||||
self.buffer_idx += input_remaining;
|
self.buffer_idx += input_remaining;
|
||||||
}
|
}
|
||||||
@ -176,13 +176,13 @@ impl FixedBuffer for FixedBuffer64 {
|
|||||||
|
|
||||||
fn zero_until(&mut self, idx: uint) {
|
fn zero_until(&mut self, idx: uint) {
|
||||||
assert!(idx >= self.buffer_idx);
|
assert!(idx >= self.buffer_idx);
|
||||||
self.buffer[mut self.buffer_idx..idx].set_memory(0);
|
self.buffer.slice_mut(self.buffer_idx, idx).set_memory(0);
|
||||||
self.buffer_idx = idx;
|
self.buffer_idx = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8] {
|
fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8] {
|
||||||
self.buffer_idx += len;
|
self.buffer_idx += len;
|
||||||
return self.buffer[mut self.buffer_idx - len..self.buffer_idx];
|
return self.buffer.slice_mut(self.buffer_idx - len, self.buffer_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn full_buffer<'s>(&'s mut self) -> &'s [u8] {
|
fn full_buffer<'s>(&'s mut self) -> &'s [u8] {
|
||||||
@ -362,7 +362,7 @@ impl Engine256State {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
read_u32v_be(w[mut 0..16], data);
|
read_u32v_be(w.slice_mut(0, 16), data);
|
||||||
|
|
||||||
// Putting the message schedule inside the same loop as the round calculations allows for
|
// Putting the message schedule inside the same loop as the round calculations allows for
|
||||||
// the compiler to generate better code.
|
// the compiler to generate better code.
|
||||||
@ -498,14 +498,14 @@ impl Digest for Sha256 {
|
|||||||
fn result(&mut self, out: &mut [u8]) {
|
fn result(&mut self, out: &mut [u8]) {
|
||||||
self.engine.finish();
|
self.engine.finish();
|
||||||
|
|
||||||
write_u32_be(out[mut 0..4], self.engine.state.h0);
|
write_u32_be(out.slice_mut(0, 4), self.engine.state.h0);
|
||||||
write_u32_be(out[mut 4..8], self.engine.state.h1);
|
write_u32_be(out.slice_mut(4, 8), self.engine.state.h1);
|
||||||
write_u32_be(out[mut 8..12], self.engine.state.h2);
|
write_u32_be(out.slice_mut(8, 12), self.engine.state.h2);
|
||||||
write_u32_be(out[mut 12..16], self.engine.state.h3);
|
write_u32_be(out.slice_mut(12, 16), self.engine.state.h3);
|
||||||
write_u32_be(out[mut 16..20], self.engine.state.h4);
|
write_u32_be(out.slice_mut(16, 20), self.engine.state.h4);
|
||||||
write_u32_be(out[mut 20..24], self.engine.state.h5);
|
write_u32_be(out.slice_mut(20, 24), self.engine.state.h5);
|
||||||
write_u32_be(out[mut 24..28], self.engine.state.h6);
|
write_u32_be(out.slice_mut(24, 28), self.engine.state.h6);
|
||||||
write_u32_be(out[mut 28..32], self.engine.state.h7);
|
write_u32_be(out.slice_mut(28, 32), self.engine.state.h7);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset(&mut self) {
|
fn reset(&mut self) {
|
||||||
|
@ -246,7 +246,6 @@ mod svh_visitor {
|
|||||||
SawExprAssign,
|
SawExprAssign,
|
||||||
SawExprAssignOp(ast::BinOp),
|
SawExprAssignOp(ast::BinOp),
|
||||||
SawExprIndex,
|
SawExprIndex,
|
||||||
SawExprSlice,
|
|
||||||
SawExprRange,
|
SawExprRange,
|
||||||
SawExprPath,
|
SawExprPath,
|
||||||
SawExprAddrOf(ast::Mutability),
|
SawExprAddrOf(ast::Mutability),
|
||||||
@ -280,7 +279,6 @@ mod svh_visitor {
|
|||||||
ExprField(_, id) => SawExprField(content(id.node)),
|
ExprField(_, id) => SawExprField(content(id.node)),
|
||||||
ExprTupField(_, id) => SawExprTupField(id.node),
|
ExprTupField(_, id) => SawExprTupField(id.node),
|
||||||
ExprIndex(..) => SawExprIndex,
|
ExprIndex(..) => SawExprIndex,
|
||||||
ExprSlice(..) => SawExprSlice,
|
|
||||||
ExprRange(..) => SawExprRange,
|
ExprRange(..) => SawExprRange,
|
||||||
ExprPath(..) => SawExprPath,
|
ExprPath(..) => SawExprPath,
|
||||||
ExprAddrOf(m, _) => SawExprAddrOf(m),
|
ExprAddrOf(m, _) => SawExprAddrOf(m),
|
||||||
|
@ -24,7 +24,8 @@ use trans::common;
|
|||||||
use trans::common::{Block, FunctionContext, ExprId, NodeInfo};
|
use trans::common::{Block, FunctionContext, ExprId, NodeInfo};
|
||||||
use trans::debuginfo;
|
use trans::debuginfo;
|
||||||
use trans::glue;
|
use trans::glue;
|
||||||
use middle::region;
|
// Temporary due to slicing syntax hacks (KILLME)
|
||||||
|
//use middle::region;
|
||||||
use trans::type_::Type;
|
use trans::type_::Type;
|
||||||
use middle::ty::{mod, Ty};
|
use middle::ty::{mod, Ty};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -128,7 +129,8 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
|
|||||||
// excluding id's that correspond to closure bodies only). For
|
// excluding id's that correspond to closure bodies only). For
|
||||||
// now we just say that if there is already an AST scope on the stack,
|
// now we just say that if there is already an AST scope on the stack,
|
||||||
// this new AST scope had better be its immediate child.
|
// this new AST scope had better be its immediate child.
|
||||||
let top_scope = self.top_ast_scope();
|
// Temporarily removed due to slicing syntax hacks (KILLME).
|
||||||
|
/*let top_scope = self.top_ast_scope();
|
||||||
if top_scope.is_some() {
|
if top_scope.is_some() {
|
||||||
assert_eq!(self.ccx
|
assert_eq!(self.ccx
|
||||||
.tcx()
|
.tcx()
|
||||||
@ -136,7 +138,7 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
|
|||||||
.opt_encl_scope(region::CodeExtent::from_node_id(debug_loc.id))
|
.opt_encl_scope(region::CodeExtent::from_node_id(debug_loc.id))
|
||||||
.map(|s|s.node_id()),
|
.map(|s|s.node_id()),
|
||||||
top_scope);
|
top_scope);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
self.push_scope(CleanupScope::new(AstScopeKind(debug_loc.id),
|
self.push_scope(CleanupScope::new(AstScopeKind(debug_loc.id),
|
||||||
Some(debug_loc)));
|
Some(debug_loc)));
|
||||||
|
@ -3533,20 +3533,14 @@ fn create_scope_map(cx: &CrateContext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprAssignOp(_, ref lhs, ref rhs) |
|
ast::ExprAssignOp(_, ref lhs, ref rhs) |
|
||||||
ast::ExprIndex(ref lhs, ref rhs) |
|
ast::ExprIndex(ref lhs, ref rhs) |
|
||||||
ast::ExprBinary(_, ref lhs, ref rhs) => {
|
ast::ExprBinary(_, ref lhs, ref rhs) => {
|
||||||
walk_expr(cx, &**lhs, scope_stack, scope_map);
|
walk_expr(cx, &**lhs, scope_stack, scope_map);
|
||||||
walk_expr(cx, &**rhs, scope_stack, scope_map);
|
walk_expr(cx, &**rhs, scope_stack, scope_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprSlice(ref base, ref start, ref end, _) => {
|
|
||||||
walk_expr(cx, &**base, scope_stack, scope_map);
|
|
||||||
start.as_ref().map(|x| walk_expr(cx, &**x, scope_stack, scope_map));
|
|
||||||
end.as_ref().map(|x| walk_expr(cx, &**x, scope_stack, scope_map));
|
|
||||||
}
|
|
||||||
|
|
||||||
ast::ExprRange(ref start, ref end) => {
|
ast::ExprRange(ref start, ref end) => {
|
||||||
walk_expr(cx, &**start, scope_stack, scope_map);
|
start.as_ref().map(|e| walk_expr(cx, &**e, scope_stack, scope_map));
|
||||||
end.as_ref().map(|e| walk_expr(cx, &**e, scope_stack, scope_map));
|
end.as_ref().map(|e| walk_expr(cx, &**e, scope_stack, scope_map));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,36 +585,40 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||||||
trans_rec_tup_field(bcx, &**base, idx.node)
|
trans_rec_tup_field(bcx, &**base, idx.node)
|
||||||
}
|
}
|
||||||
ast::ExprIndex(ref base, ref idx) => {
|
ast::ExprIndex(ref base, ref idx) => {
|
||||||
trans_index(bcx, expr, &**base, &**idx, MethodCall::expr(expr.id))
|
match idx.node {
|
||||||
}
|
ast::ExprRange(ref start, ref end) => {
|
||||||
ast::ExprSlice(ref base, ref start, ref end, _) => {
|
// Special case for slicing syntax (KILLME).
|
||||||
let _icx = push_ctxt("trans_slice");
|
let _icx = push_ctxt("trans_slice");
|
||||||
let ccx = bcx.ccx();
|
let ccx = bcx.ccx();
|
||||||
|
|
||||||
let method_call = MethodCall::expr(expr.id);
|
let method_call = MethodCall::expr(expr.id);
|
||||||
let method_ty = ccx.tcx()
|
let method_ty = ccx.tcx()
|
||||||
.method_map
|
.method_map
|
||||||
.borrow()
|
.borrow()
|
||||||
.get(&method_call)
|
.get(&method_call)
|
||||||
.map(|method| method.ty);
|
.map(|method| method.ty);
|
||||||
let base_datum = unpack_datum!(bcx, trans(bcx, &**base));
|
let base_datum = unpack_datum!(bcx, trans(bcx, &**base));
|
||||||
|
|
||||||
let mut args = vec![];
|
let mut args = vec![];
|
||||||
start.as_ref().map(|e| args.push((unpack_datum!(bcx, trans(bcx, &**e)), e.id)));
|
start.as_ref().map(|e| args.push((unpack_datum!(bcx, trans(bcx, &**e)), e.id)));
|
||||||
end.as_ref().map(|e| args.push((unpack_datum!(bcx, trans(bcx, &**e)), e.id)));
|
end.as_ref().map(|e| args.push((unpack_datum!(bcx, trans(bcx, &**e)), e.id)));
|
||||||
|
|
||||||
let result_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty.unwrap())).unwrap();
|
let result_ty = ty::ty_fn_ret(monomorphize_type(bcx,
|
||||||
let scratch = rvalue_scratch_datum(bcx, result_ty, "trans_slice");
|
method_ty.unwrap())).unwrap();
|
||||||
|
let scratch = rvalue_scratch_datum(bcx, result_ty, "trans_slice");
|
||||||
|
|
||||||
unpack_result!(bcx,
|
unpack_result!(bcx,
|
||||||
trans_overloaded_op(bcx,
|
trans_overloaded_op(bcx,
|
||||||
expr,
|
expr,
|
||||||
method_call,
|
method_call,
|
||||||
base_datum,
|
base_datum,
|
||||||
args,
|
args,
|
||||||
Some(SaveIn(scratch.val)),
|
Some(SaveIn(scratch.val)),
|
||||||
true));
|
true));
|
||||||
DatumBlock::new(bcx, scratch.to_expr_datum())
|
DatumBlock::new(bcx, scratch.to_expr_datum())
|
||||||
|
}
|
||||||
|
_ => trans_index(bcx, expr, &**base, &**idx, MethodCall::expr(expr.id))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ast::ExprBox(_, ref contents) => {
|
ast::ExprBox(_, ref contents) => {
|
||||||
// Special case for `Box<T>`
|
// Special case for `Box<T>`
|
||||||
@ -1064,22 +1068,34 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A range just desugars into a struct.
|
// A range just desugars into a struct.
|
||||||
let (did, fields) = match end {
|
// Note that the type of the start and end may not be the same, but
|
||||||
&Some(ref end) => {
|
// they should only differ in their lifetime, which should not matter
|
||||||
|
// in trans.
|
||||||
|
let (did, fields, ty_params) = match (start, end) {
|
||||||
|
(&Some(ref start), &Some(ref end)) => {
|
||||||
// Desugar to Range
|
// Desugar to Range
|
||||||
let fields = vec!(make_field("start", start.clone()),
|
let fields = vec![make_field("start", start.clone()),
|
||||||
make_field("end", end.clone()));
|
make_field("end", end.clone())];
|
||||||
(tcx.lang_items.range_struct(), fields)
|
(tcx.lang_items.range_struct(), fields, vec![node_id_type(bcx, start.id)])
|
||||||
}
|
}
|
||||||
&None => {
|
(&Some(ref start), &None) => {
|
||||||
// Desugar to RangeFrom
|
// Desugar to RangeFrom
|
||||||
let fields = vec!(make_field("start", start.clone()));
|
let fields = vec![make_field("start", start.clone())];
|
||||||
(tcx.lang_items.range_from_struct(), fields)
|
(tcx.lang_items.range_from_struct(), fields, vec![node_id_type(bcx, start.id)])
|
||||||
|
}
|
||||||
|
(&None, &Some(ref end)) => {
|
||||||
|
// Desugar to RangeTo
|
||||||
|
let fields = vec![make_field("end", end.clone())];
|
||||||
|
(tcx.lang_items.range_to_struct(), fields, vec![node_id_type(bcx, end.id)])
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// Desugar to FullRange
|
||||||
|
(tcx.lang_items.full_range_struct(), vec![], vec![])
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(did) = did {
|
if let Some(did) = did {
|
||||||
let substs = Substs::new_type(vec![node_id_type(bcx, start.id)], vec![]);
|
let substs = Substs::new_type(ty_params, vec![]);
|
||||||
trans_struct(bcx,
|
trans_struct(bcx,
|
||||||
fields.as_slice(),
|
fields.as_slice(),
|
||||||
None,
|
None,
|
||||||
|
@ -488,7 +488,6 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
|||||||
ast::ExprParen(ref expr) |
|
ast::ExprParen(ref expr) |
|
||||||
ast::ExprField(ref expr, _) |
|
ast::ExprField(ref expr, _) |
|
||||||
ast::ExprTupField(ref expr, _) |
|
ast::ExprTupField(ref expr, _) |
|
||||||
ast::ExprSlice(ref expr, _, _, _) |
|
|
||||||
ast::ExprIndex(ref expr, _) |
|
ast::ExprIndex(ref expr, _) |
|
||||||
ast::ExprUnary(ast::UnDeref, ref expr) => exprs.push(&**expr),
|
ast::ExprUnary(ast::UnDeref, ref expr) => exprs.push(&**expr),
|
||||||
_ => break,
|
_ => break,
|
||||||
|
@ -2003,7 +2003,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Copy, Show)]
|
#[deriving(Copy, Show,PartialEq,Eq)]
|
||||||
pub enum LvaluePreference {
|
pub enum LvaluePreference {
|
||||||
PreferMutLvalue,
|
PreferMutLvalue,
|
||||||
NoPreference
|
NoPreference
|
||||||
@ -2214,57 +2214,6 @@ fn autoderef_for_index<'a, 'tcx, T, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Autoderefs `base_expr`, looking for a `Slice` impl. If it finds one, installs the relevant
|
|
||||||
/// method info and returns the result type (else None).
|
|
||||||
fn try_overloaded_slice<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|
||||||
method_call: MethodCall,
|
|
||||||
expr: &ast::Expr,
|
|
||||||
base_expr: &ast::Expr,
|
|
||||||
base_ty: Ty<'tcx>,
|
|
||||||
start_expr: &Option<P<ast::Expr>>,
|
|
||||||
end_expr: &Option<P<ast::Expr>>,
|
|
||||||
mutbl: ast::Mutability)
|
|
||||||
-> Option<Ty<'tcx>> // return type is result of slice
|
|
||||||
{
|
|
||||||
let lvalue_pref = match mutbl {
|
|
||||||
ast::MutMutable => PreferMutLvalue,
|
|
||||||
ast::MutImmutable => NoPreference
|
|
||||||
};
|
|
||||||
|
|
||||||
let opt_method_ty =
|
|
||||||
autoderef_for_index(fcx, base_expr, base_ty, lvalue_pref, |adjusted_ty, autoderefref| {
|
|
||||||
try_overloaded_slice_step(fcx, method_call, expr, base_expr,
|
|
||||||
adjusted_ty, autoderefref, mutbl,
|
|
||||||
start_expr, end_expr)
|
|
||||||
});
|
|
||||||
|
|
||||||
// Regardless of whether the lookup succeeds, check the method arguments
|
|
||||||
// so that we have *some* type for each argument.
|
|
||||||
let method_ty_or_err = opt_method_ty.unwrap_or(ty::mk_err());
|
|
||||||
|
|
||||||
let mut args = vec![];
|
|
||||||
start_expr.as_ref().map(|x| args.push(x));
|
|
||||||
end_expr.as_ref().map(|x| args.push(x));
|
|
||||||
|
|
||||||
check_method_argument_types(fcx,
|
|
||||||
expr.span,
|
|
||||||
method_ty_or_err,
|
|
||||||
expr,
|
|
||||||
args.as_slice(),
|
|
||||||
AutorefArgs::Yes,
|
|
||||||
DontTupleArguments);
|
|
||||||
|
|
||||||
opt_method_ty.map(|method_ty| {
|
|
||||||
let result_ty = ty::ty_fn_ret(method_ty);
|
|
||||||
match result_ty {
|
|
||||||
ty::FnConverging(result_ty) => result_ty,
|
|
||||||
ty::FnDiverging => {
|
|
||||||
fcx.tcx().sess.span_bug(expr.span,
|
|
||||||
"slice trait does not define a `!` return")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks for a `Slice` (or `SliceMut`) impl at the relevant level of autoderef. If it finds one,
|
/// Checks for a `Slice` (or `SliceMut`) impl at the relevant level of autoderef. If it finds one,
|
||||||
/// installs method info and returns type of method (else None).
|
/// installs method info and returns type of method (else None).
|
||||||
@ -2274,65 +2223,79 @@ fn try_overloaded_slice_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||||||
base_expr: &ast::Expr,
|
base_expr: &ast::Expr,
|
||||||
base_ty: Ty<'tcx>, // autoderef'd type
|
base_ty: Ty<'tcx>, // autoderef'd type
|
||||||
autoderefref: ty::AutoDerefRef<'tcx>,
|
autoderefref: ty::AutoDerefRef<'tcx>,
|
||||||
mutbl: ast::Mutability,
|
lvalue_pref: LvaluePreference,
|
||||||
start_expr: &Option<P<ast::Expr>>,
|
start_expr: &Option<P<ast::Expr>>,
|
||||||
end_expr: &Option<P<ast::Expr>>)
|
end_expr: &Option<P<ast::Expr>>)
|
||||||
// result type is type of method being called
|
-> Option<(Ty<'tcx>, /* index type */
|
||||||
-> Option<Ty<'tcx>>
|
Ty<'tcx>)> /* return type */
|
||||||
{
|
{
|
||||||
let method = if mutbl == ast::MutMutable {
|
let input_ty = fcx.infcx().next_ty_var();
|
||||||
// Try `SliceMut` first, if preferred.
|
let return_ty = fcx.infcx().next_ty_var();
|
||||||
match fcx.tcx().lang_items.slice_mut_trait() {
|
|
||||||
Some(trait_did) => {
|
|
||||||
let method_name = match (start_expr, end_expr) {
|
|
||||||
(&Some(_), &Some(_)) => "slice_or_fail_mut",
|
|
||||||
(&Some(_), &None) => "slice_from_or_fail_mut",
|
|
||||||
(&None, &Some(_)) => "slice_to_or_fail_mut",
|
|
||||||
(&None, &None) => "as_mut_slice_",
|
|
||||||
};
|
|
||||||
|
|
||||||
method::lookup_in_trait_adjusted(fcx,
|
let method = match lvalue_pref {
|
||||||
expr.span,
|
PreferMutLvalue => {
|
||||||
Some(&*base_expr),
|
// Try `SliceMut` first, if preferred.
|
||||||
token::intern(method_name),
|
match fcx.tcx().lang_items.slice_mut_trait() {
|
||||||
trait_did,
|
Some(trait_did) => {
|
||||||
autoderefref,
|
let method_name = match (start_expr, end_expr) {
|
||||||
base_ty,
|
(&Some(_), &Some(_)) => "slice_or_fail_mut",
|
||||||
None)
|
(&Some(_), &None) => "slice_from_or_fail_mut",
|
||||||
|
(&None, &Some(_)) => "slice_to_or_fail_mut",
|
||||||
|
(&None, &None) => "as_mut_slice_",
|
||||||
|
};
|
||||||
|
|
||||||
|
method::lookup_in_trait_adjusted(fcx,
|
||||||
|
expr.span,
|
||||||
|
Some(&*base_expr),
|
||||||
|
token::intern(method_name),
|
||||||
|
trait_did,
|
||||||
|
autoderefref,
|
||||||
|
base_ty,
|
||||||
|
Some(vec![input_ty, return_ty]))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
} else {
|
NoPreference => {
|
||||||
// Otherwise, fall back to `Slice`.
|
// Otherwise, fall back to `Slice`.
|
||||||
// FIXME(#17293) this will not coerce base_expr, so we miss the Slice
|
match fcx.tcx().lang_items.slice_trait() {
|
||||||
// trait for `&mut [T]`.
|
Some(trait_did) => {
|
||||||
match fcx.tcx().lang_items.slice_trait() {
|
let method_name = match (start_expr, end_expr) {
|
||||||
Some(trait_did) => {
|
(&Some(_), &Some(_)) => "slice_or_fail",
|
||||||
let method_name = match (start_expr, end_expr) {
|
(&Some(_), &None) => "slice_from_or_fail",
|
||||||
(&Some(_), &Some(_)) => "slice_or_fail",
|
(&None, &Some(_)) => "slice_to_or_fail",
|
||||||
(&Some(_), &None) => "slice_from_or_fail",
|
(&None, &None) => "as_slice_",
|
||||||
(&None, &Some(_)) => "slice_to_or_fail",
|
};
|
||||||
(&None, &None) => "as_slice_",
|
|
||||||
};
|
|
||||||
|
|
||||||
method::lookup_in_trait_adjusted(fcx,
|
method::lookup_in_trait_adjusted(fcx,
|
||||||
expr.span,
|
expr.span,
|
||||||
Some(&*base_expr),
|
Some(&*base_expr),
|
||||||
token::intern(method_name),
|
token::intern(method_name),
|
||||||
trait_did,
|
trait_did,
|
||||||
autoderefref,
|
autoderefref,
|
||||||
base_ty,
|
base_ty,
|
||||||
None)
|
Some(vec![input_ty, return_ty]))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// If some lookup succeeded, install method in table
|
// If some lookup succeeded, install method in table
|
||||||
method.map(|method| {
|
method.map(|method| {
|
||||||
let ty = method.ty;
|
let method_ty = method.ty;
|
||||||
fcx.inh.method_map.borrow_mut().insert(method_call, method);
|
make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method));
|
||||||
ty
|
|
||||||
|
let result_ty = ty::ty_fn_ret(method_ty);
|
||||||
|
let result_ty = match result_ty {
|
||||||
|
ty::FnConverging(result_ty) => result_ty,
|
||||||
|
ty::FnDiverging => {
|
||||||
|
fcx.tcx().sess.span_bug(expr.span,
|
||||||
|
"slice trait does not define a `!` return")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(input_ty, result_ty)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4211,155 +4174,171 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||||||
}
|
}
|
||||||
ast::ExprIndex(ref base, ref idx) => {
|
ast::ExprIndex(ref base, ref idx) => {
|
||||||
check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
|
check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
|
||||||
check_expr(fcx, &**idx);
|
|
||||||
let base_t = fcx.expr_ty(&**base);
|
let base_t = fcx.expr_ty(&**base);
|
||||||
let idx_t = fcx.expr_ty(&**idx);
|
|
||||||
if ty::type_is_error(base_t) {
|
if ty::type_is_error(base_t) {
|
||||||
fcx.write_ty(id, base_t);
|
fcx.write_ty(id, base_t);
|
||||||
} else if ty::type_is_error(idx_t) {
|
|
||||||
fcx.write_ty(id, idx_t);
|
|
||||||
} else {
|
} else {
|
||||||
let base_t = structurally_resolved_type(fcx, expr.span, base_t);
|
match idx.node {
|
||||||
|
ast::ExprRange(ref start, ref end) => {
|
||||||
|
// A slice, rather than an index. Special cased for now (KILLME).
|
||||||
|
let base_t = structurally_resolved_type(fcx, expr.span, base_t);
|
||||||
|
|
||||||
let result =
|
let result =
|
||||||
autoderef_for_index(fcx, &**base, base_t, lvalue_pref, |adj_ty, adj| {
|
autoderef_for_index(fcx, &**base, base_t, lvalue_pref, |adj_ty, adj| {
|
||||||
try_index_step(fcx,
|
try_overloaded_slice_step(fcx,
|
||||||
MethodCall::expr(expr.id),
|
MethodCall::expr(expr.id),
|
||||||
expr,
|
expr,
|
||||||
&**base,
|
&**base,
|
||||||
adj_ty,
|
adj_ty,
|
||||||
adj,
|
adj,
|
||||||
lvalue_pref)
|
lvalue_pref,
|
||||||
});
|
start,
|
||||||
|
end)
|
||||||
|
});
|
||||||
|
|
||||||
match result {
|
let mut args = vec![];
|
||||||
Some((index_ty, element_ty)) => {
|
start.as_ref().map(|x| args.push(x));
|
||||||
check_expr_has_type(fcx, &**idx, index_ty);
|
end.as_ref().map(|x| args.push(x));
|
||||||
fcx.write_ty(id, element_ty);
|
|
||||||
|
match result {
|
||||||
|
Some((index_ty, element_ty)) => {
|
||||||
|
for a in args.iter() {
|
||||||
|
check_expr_has_type(fcx, &***a, index_ty);
|
||||||
|
}
|
||||||
|
fcx.write_ty(idx.id, element_ty);
|
||||||
|
fcx.write_ty(id, element_ty)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
for a in args.iter() {
|
||||||
|
check_expr(fcx, &***a);
|
||||||
|
}
|
||||||
|
fcx.type_error_message(expr.span,
|
||||||
|
|actual| {
|
||||||
|
format!("cannot take a slice of a value with type `{}`",
|
||||||
|
actual)
|
||||||
|
},
|
||||||
|
base_t,
|
||||||
|
None);
|
||||||
|
fcx.write_ty(idx.id, ty::mk_err());
|
||||||
|
fcx.write_ty(id, ty::mk_err())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
}
|
||||||
check_expr_has_type(fcx, &**idx, ty::mk_err());
|
_ => {
|
||||||
fcx.type_error_message(
|
check_expr(fcx, &**idx);
|
||||||
expr.span,
|
let idx_t = fcx.expr_ty(&**idx);
|
||||||
|actual| {
|
if ty::type_is_error(idx_t) {
|
||||||
format!("cannot index a value of type `{}`",
|
fcx.write_ty(id, idx_t);
|
||||||
actual)
|
} else {
|
||||||
},
|
let base_t = structurally_resolved_type(fcx, expr.span, base_t);
|
||||||
base_t,
|
|
||||||
None);
|
|
||||||
fcx.write_ty(id, ty::mk_err())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ast::ExprSlice(ref base, ref start, ref end, mutbl) => {
|
|
||||||
check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
|
|
||||||
let raw_base_t = fcx.expr_ty(&**base);
|
|
||||||
|
|
||||||
let mut some_err = false;
|
let result =
|
||||||
if ty::type_is_error(raw_base_t) {
|
autoderef_for_index(fcx, &**base, base_t, lvalue_pref, |adj_ty, adj| {
|
||||||
fcx.write_ty(id, raw_base_t);
|
try_index_step(fcx,
|
||||||
some_err = true;
|
MethodCall::expr(expr.id),
|
||||||
}
|
expr,
|
||||||
|
&**base,
|
||||||
|
adj_ty,
|
||||||
|
adj,
|
||||||
|
lvalue_pref)
|
||||||
|
});
|
||||||
|
|
||||||
{
|
match result {
|
||||||
let check_slice_idx = |e: &ast::Expr| {
|
Some((index_ty, element_ty)) => {
|
||||||
check_expr(fcx, e);
|
check_expr_has_type(fcx, &**idx, index_ty);
|
||||||
let e_t = fcx.expr_ty(e);
|
fcx.write_ty(id, element_ty);
|
||||||
if ty::type_is_error(e_t) {
|
}
|
||||||
fcx.write_ty(e.id, e_t);
|
_ => {
|
||||||
some_err = true;
|
check_expr_has_type(fcx, &**idx, ty::mk_err());
|
||||||
}
|
fcx.type_error_message(
|
||||||
};
|
expr.span,
|
||||||
start.as_ref().map(|e| check_slice_idx(&**e));
|
|actual| {
|
||||||
end.as_ref().map(|e| check_slice_idx(&**e));
|
format!("cannot index a value of type `{}`",
|
||||||
}
|
actual)
|
||||||
|
},
|
||||||
if !some_err {
|
base_t,
|
||||||
let base_t = structurally_resolved_type(fcx,
|
None);
|
||||||
expr.span,
|
fcx.write_ty(id, ty::mk_err())
|
||||||
raw_base_t);
|
}
|
||||||
let method_call = MethodCall::expr(expr.id);
|
}
|
||||||
match try_overloaded_slice(fcx,
|
|
||||||
method_call,
|
|
||||||
expr,
|
|
||||||
&**base,
|
|
||||||
base_t,
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
mutbl) {
|
|
||||||
Some(ty) => fcx.write_ty(id, ty),
|
|
||||||
None => {
|
|
||||||
fcx.type_error_message(expr.span,
|
|
||||||
|actual| {
|
|
||||||
format!("cannot take a {}slice of a value with type `{}`",
|
|
||||||
if mutbl == ast::MutMutable {
|
|
||||||
"mutable "
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
},
|
|
||||||
actual)
|
|
||||||
},
|
|
||||||
base_t,
|
|
||||||
None);
|
|
||||||
fcx.write_ty(id, ty::mk_err())
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprRange(ref start, ref end) => {
|
ast::ExprRange(ref start, ref end) => {
|
||||||
check_expr(fcx, &**start);
|
let t_start = start.as_ref().map(|e| {
|
||||||
let t_start = fcx.expr_ty(&**start);
|
|
||||||
|
|
||||||
let idx_type = if let &Some(ref e) = end {
|
|
||||||
check_expr(fcx, &**e);
|
check_expr(fcx, &**e);
|
||||||
let t_end = fcx.expr_ty(&**e);
|
fcx.expr_ty(&**e)
|
||||||
if ty::type_is_error(t_end) {
|
});
|
||||||
ty::mk_err()
|
let t_end = end.as_ref().map(|e| {
|
||||||
} else if t_start == ty::mk_err() {
|
check_expr(fcx, &**e);
|
||||||
ty::mk_err()
|
fcx.expr_ty(&**e)
|
||||||
} else {
|
});
|
||||||
infer::common_supertype(fcx.infcx(),
|
|
||||||
infer::RangeExpression(expr.span),
|
let idx_type = match (t_start, t_end) {
|
||||||
true,
|
(Some(ty), None) | (None, Some(ty)) => Some(ty),
|
||||||
t_start,
|
(Some(t_start), Some(t_end))
|
||||||
t_end)
|
if ty::type_is_error(t_start) || ty::type_is_error(t_end) => {
|
||||||
|
Some(ty::mk_err())
|
||||||
}
|
}
|
||||||
} else {
|
(Some(t_start), Some(t_end)) => {
|
||||||
t_start
|
Some(infer::common_supertype(fcx.infcx(),
|
||||||
|
infer::RangeExpression(expr.span),
|
||||||
|
true,
|
||||||
|
t_start,
|
||||||
|
t_end))
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
};
|
};
|
||||||
|
|
||||||
// Note that we don't check the type of start/end satisfy any
|
// Note that we don't check the type of start/end satisfy any
|
||||||
// bounds because right the range structs do not have any. If we add
|
// bounds because right the range structs do not have any. If we add
|
||||||
// some bounds, then we'll need to check `t_start` against them here.
|
// some bounds, then we'll need to check `t_start` against them here.
|
||||||
|
|
||||||
let range_type = if idx_type == ty::mk_err() {
|
let range_type = match idx_type {
|
||||||
ty::mk_err()
|
Some(idx_type) if ty::type_is_error(idx_type) => {
|
||||||
} else {
|
|
||||||
// Find the did from the appropriate lang item.
|
|
||||||
let did = if end.is_some() {
|
|
||||||
// Range
|
|
||||||
tcx.lang_items.range_struct()
|
|
||||||
} else {
|
|
||||||
// RangeFrom
|
|
||||||
tcx.lang_items.range_from_struct()
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(did) = did {
|
|
||||||
let polytype = ty::lookup_item_type(tcx, did);
|
|
||||||
let substs = Substs::new_type(vec![idx_type], vec![]);
|
|
||||||
let bounds = polytype.generics.to_bounds(tcx, &substs);
|
|
||||||
fcx.add_obligations_for_parameters(
|
|
||||||
traits::ObligationCause::new(expr.span,
|
|
||||||
fcx.body_id,
|
|
||||||
traits::ItemObligation(did)),
|
|
||||||
&bounds);
|
|
||||||
|
|
||||||
ty::mk_struct(tcx, did, tcx.mk_substs(substs))
|
|
||||||
} else {
|
|
||||||
ty::mk_err()
|
ty::mk_err()
|
||||||
}
|
}
|
||||||
|
Some(idx_type) => {
|
||||||
|
// Find the did from the appropriate lang item.
|
||||||
|
let did = match (start, end) {
|
||||||
|
(&Some(_), &Some(_)) => tcx.lang_items.range_struct(),
|
||||||
|
(&Some(_), &None) => tcx.lang_items.range_from_struct(),
|
||||||
|
(&None, &Some(_)) => tcx.lang_items.range_to_struct(),
|
||||||
|
(&None, &None) => {
|
||||||
|
tcx.sess.span_bug(expr.span, "full range should be dealt with above")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(did) = did {
|
||||||
|
let polytype = ty::lookup_item_type(tcx, did);
|
||||||
|
let substs = Substs::new_type(vec![idx_type], vec![]);
|
||||||
|
let bounds = polytype.generics.to_bounds(tcx, &substs);
|
||||||
|
fcx.add_obligations_for_parameters(
|
||||||
|
traits::ObligationCause::new(expr.span,
|
||||||
|
fcx.body_id,
|
||||||
|
traits::ItemObligation(did)),
|
||||||
|
&bounds);
|
||||||
|
|
||||||
|
ty::mk_struct(tcx, did, tcx.mk_substs(substs))
|
||||||
|
} else {
|
||||||
|
tcx.sess.span_err(expr.span, "No lang item for range syntax");
|
||||||
|
ty::mk_err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
// Neither start nor end => FullRange
|
||||||
|
if let Some(did) = tcx.lang_items.full_range_struct() {
|
||||||
|
let substs = Substs::new_type(vec![], vec![]);
|
||||||
|
ty::mk_struct(tcx, did, tcx.mk_substs(substs))
|
||||||
|
} else {
|
||||||
|
tcx.sess.span_err(expr.span, "No lang item for range syntax");
|
||||||
|
ty::mk_err()
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fcx.write_ty(id, range_type);
|
fcx.write_ty(id, range_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ impl<R: Reader> BufferedReader<R> {
|
|||||||
impl<R: Reader> Buffer for BufferedReader<R> {
|
impl<R: Reader> Buffer for BufferedReader<R> {
|
||||||
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
|
||||||
if self.pos == self.cap {
|
if self.pos == self.cap {
|
||||||
self.cap = try!(self.inner.read(self.buf[mut]));
|
self.cap = try!(self.inner.read(self.buf.as_mut_slice()));
|
||||||
self.pos = 0;
|
self.pos = 0;
|
||||||
}
|
}
|
||||||
Ok(self.buf[self.pos..self.cap])
|
Ok(self.buf[self.pos..self.cap])
|
||||||
@ -219,7 +219,7 @@ impl<W: Writer> Writer for BufferedWriter<W> {
|
|||||||
if buf.len() > self.buf.len() {
|
if buf.len() > self.buf.len() {
|
||||||
self.inner.as_mut().unwrap().write(buf)
|
self.inner.as_mut().unwrap().write(buf)
|
||||||
} else {
|
} else {
|
||||||
let dst = self.buf[mut self.pos..];
|
let dst = self.buf.slice_from_mut(self.pos);
|
||||||
slice::bytes::copy_memory(dst, buf);
|
slice::bytes::copy_memory(dst, buf);
|
||||||
self.pos += buf.len();
|
self.pos += buf.len();
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -87,7 +87,7 @@ impl Reader for ChanReader {
|
|||||||
loop {
|
loop {
|
||||||
let count = match self.fill_buf().ok() {
|
let count = match self.fill_buf().ok() {
|
||||||
Some(src) => {
|
Some(src) => {
|
||||||
let dst = buf[mut num_read..];
|
let dst = buf.slice_from_mut(num_read);
|
||||||
let count = cmp::min(src.len(), dst.len());
|
let count = cmp::min(src.len(), dst.len());
|
||||||
bytes::copy_memory(dst, src[..count]);
|
bytes::copy_memory(dst, src[..count]);
|
||||||
count
|
count
|
||||||
|
@ -931,11 +931,11 @@ mod test {
|
|||||||
{
|
{
|
||||||
let mut read_stream = File::open_mode(filename, Open, Read);
|
let mut read_stream = File::open_mode(filename, Open, Read);
|
||||||
{
|
{
|
||||||
let read_buf = read_mem[mut 0..4];
|
let read_buf = read_mem.slice_mut(0, 4);
|
||||||
check!(read_stream.read(read_buf));
|
check!(read_stream.read(read_buf));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let read_buf = read_mem[mut 4..8];
|
let read_buf = read_mem.slice_mut(4, 8);
|
||||||
check!(read_stream.read(read_buf));
|
check!(read_stream.read(read_buf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ impl Reader for MemReader {
|
|||||||
let write_len = min(buf.len(), self.buf.len() - self.pos);
|
let write_len = min(buf.len(), self.buf.len() - self.pos);
|
||||||
{
|
{
|
||||||
let input = self.buf[self.pos.. self.pos + write_len];
|
let input = self.buf[self.pos.. self.pos + write_len];
|
||||||
let output = buf[mut ..write_len];
|
let output = buf.slice_to_mut(write_len);
|
||||||
assert_eq!(input.len(), output.len());
|
assert_eq!(input.len(), output.len());
|
||||||
slice::bytes::copy_memory(output, input);
|
slice::bytes::copy_memory(output, input);
|
||||||
}
|
}
|
||||||
@ -214,7 +214,7 @@ impl<'a> Reader for &'a [u8] {
|
|||||||
let write_len = min(buf.len(), self.len());
|
let write_len = min(buf.len(), self.len());
|
||||||
{
|
{
|
||||||
let input = self[..write_len];
|
let input = self[..write_len];
|
||||||
let output = buf[mut ..write_len];
|
let output = buf.slice_to_mut(write_len);
|
||||||
slice::bytes::copy_memory(output, input);
|
slice::bytes::copy_memory(output, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +279,7 @@ impl<'a> BufWriter<'a> {
|
|||||||
impl<'a> Writer for BufWriter<'a> {
|
impl<'a> Writer for BufWriter<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, src: &[u8]) -> IoResult<()> {
|
fn write(&mut self, src: &[u8]) -> IoResult<()> {
|
||||||
let dst = self.buf[mut self.pos..];
|
let dst = self.buf.slice_from_mut(self.pos);
|
||||||
let dst_len = dst.len();
|
let dst_len = dst.len();
|
||||||
|
|
||||||
if dst_len == 0 {
|
if dst_len == 0 {
|
||||||
@ -359,7 +359,7 @@ impl<'a> Reader for BufReader<'a> {
|
|||||||
let write_len = min(buf.len(), self.buf.len() - self.pos);
|
let write_len = min(buf.len(), self.buf.len() - self.pos);
|
||||||
{
|
{
|
||||||
let input = self.buf[self.pos.. self.pos + write_len];
|
let input = self.buf[self.pos.. self.pos + write_len];
|
||||||
let output = buf[mut ..write_len];
|
let output = buf.slice_to_mut(write_len);
|
||||||
assert_eq!(input.len(), output.len());
|
assert_eq!(input.len(), output.len());
|
||||||
slice::bytes::copy_memory(output, input);
|
slice::bytes::copy_memory(output, input);
|
||||||
}
|
}
|
||||||
@ -652,7 +652,7 @@ mod test {
|
|||||||
assert!(r.read_at_least(buf.len(), &mut buf).is_ok());
|
assert!(r.read_at_least(buf.len(), &mut buf).is_ok());
|
||||||
let b: &[_] = &[1, 2, 3];
|
let b: &[_] = &[1, 2, 3];
|
||||||
assert_eq!(buf, b);
|
assert_eq!(buf, b);
|
||||||
assert!(r.read_at_least(0, buf[mut ..0]).is_ok());
|
assert!(r.read_at_least(0, buf.slice_to_mut(0)).is_ok());
|
||||||
assert_eq!(buf, b);
|
assert_eq!(buf, b);
|
||||||
assert!(r.read_at_least(buf.len(), &mut buf).is_ok());
|
assert!(r.read_at_least(buf.len(), &mut buf).is_ok());
|
||||||
let b: &[_] = &[4, 5, 6];
|
let b: &[_] = &[4, 5, 6];
|
||||||
|
@ -513,7 +513,7 @@ pub trait Reader {
|
|||||||
while read < min {
|
while read < min {
|
||||||
let mut zeroes = 0;
|
let mut zeroes = 0;
|
||||||
loop {
|
loop {
|
||||||
match self.read(buf[mut read..]) {
|
match self.read(buf.slice_from_mut(read)) {
|
||||||
Ok(0) => {
|
Ok(0) => {
|
||||||
zeroes += 1;
|
zeroes += 1;
|
||||||
if zeroes >= NO_PROGRESS_LIMIT {
|
if zeroes >= NO_PROGRESS_LIMIT {
|
||||||
@ -1123,7 +1123,7 @@ pub trait Writer {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn write_char(&mut self, c: char) -> IoResult<()> {
|
fn write_char(&mut self, c: char) -> IoResult<()> {
|
||||||
let mut buf = [0u8, ..4];
|
let mut buf = [0u8, ..4];
|
||||||
let n = c.encode_utf8(buf[mut]).unwrap_or(0);
|
let n = c.encode_utf8(buf.as_mut_slice()).unwrap_or(0);
|
||||||
self.write(buf[..n])
|
self.write(buf[..n])
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1555,7 +1555,7 @@ pub trait Buffer: Reader {
|
|||||||
{
|
{
|
||||||
let mut start = 1;
|
let mut start = 1;
|
||||||
while start < width {
|
while start < width {
|
||||||
match try!(self.read(buf[mut start..width])) {
|
match try!(self.read(buf.slice_mut(start, width))) {
|
||||||
n if n == width - start => break,
|
n if n == width - start => break,
|
||||||
n if n < width - start => { start += n; }
|
n if n < width - start => { start += n; }
|
||||||
_ => return Err(standard_error(InvalidInput)),
|
_ => return Err(standard_error(InvalidInput)),
|
||||||
|
@ -250,7 +250,7 @@ impl<'a> Parser<'a> {
|
|||||||
assert!(head.len() + tail.len() <= 8);
|
assert!(head.len() + tail.len() <= 8);
|
||||||
let mut gs = [0u16, ..8];
|
let mut gs = [0u16, ..8];
|
||||||
gs.clone_from_slice(head);
|
gs.clone_from_slice(head);
|
||||||
gs[mut 8 - tail.len() .. 8].clone_from_slice(tail);
|
gs.slice_mut(8 - tail.len(), 8).clone_from_slice(tail);
|
||||||
Ipv6Addr(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7])
|
Ipv6Addr(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ use sys_common;
|
|||||||
/// match socket.recv_from(&mut buf) {
|
/// match socket.recv_from(&mut buf) {
|
||||||
/// Ok((amt, src)) => {
|
/// Ok((amt, src)) => {
|
||||||
/// // Send a reply to the socket we received data from
|
/// // Send a reply to the socket we received data from
|
||||||
/// let buf = buf[mut ..amt];
|
/// let buf = buf.slice_to_mut(amt);
|
||||||
/// buf.reverse();
|
/// buf.reverse();
|
||||||
/// socket.send_to(buf, src);
|
/// socket.send_to(buf, src);
|
||||||
/// }
|
/// }
|
||||||
|
@ -51,7 +51,7 @@ impl<R: Reader> Reader for LimitReader<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let len = cmp::min(self.limit, buf.len());
|
let len = cmp::min(self.limit, buf.len());
|
||||||
let res = self.inner.read(buf[mut ..len]);
|
let res = self.inner.read(buf.slice_to_mut(len));
|
||||||
match res {
|
match res {
|
||||||
Ok(len) => self.limit -= len,
|
Ok(len) => self.limit -= len,
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -55,7 +55,7 @@ mod imp {
|
|||||||
let mut read = 0;
|
let mut read = 0;
|
||||||
let len = v.len();
|
let len = v.len();
|
||||||
while read < len {
|
while read < len {
|
||||||
let result = getrandom(v[mut read..]);
|
let result = getrandom(v.slice_from_mut(read));
|
||||||
if result == -1 {
|
if result == -1 {
|
||||||
let err = errno() as libc::c_int;
|
let err = errno() as libc::c_int;
|
||||||
if err == libc::EINTR {
|
if err == libc::EINTR {
|
||||||
|
@ -139,7 +139,7 @@ fn abort_(args: &fmt::Arguments) -> ! {
|
|||||||
}
|
}
|
||||||
impl<'a> FormatWriter for BufWriter<'a> {
|
impl<'a> FormatWriter for BufWriter<'a> {
|
||||||
fn write(&mut self, bytes: &[u8]) -> fmt::Result {
|
fn write(&mut self, bytes: &[u8]) -> fmt::Result {
|
||||||
let left = self.buf[mut self.pos..];
|
let left = self.buf.slice_from_mut(self.pos);
|
||||||
let to_write = bytes[..cmp::min(bytes.len(), left.len())];
|
let to_write = bytes[..cmp::min(bytes.len(), left.len())];
|
||||||
slice::bytes::copy_memory(left, to_write);
|
slice::bytes::copy_memory(left, to_write);
|
||||||
self.pos += to_write.len();
|
self.pos += to_write.len();
|
||||||
|
@ -723,8 +723,7 @@ pub enum Expr_ {
|
|||||||
ExprField(P<Expr>, SpannedIdent),
|
ExprField(P<Expr>, SpannedIdent),
|
||||||
ExprTupField(P<Expr>, Spanned<uint>),
|
ExprTupField(P<Expr>, Spanned<uint>),
|
||||||
ExprIndex(P<Expr>, P<Expr>),
|
ExprIndex(P<Expr>, P<Expr>),
|
||||||
ExprSlice(P<Expr>, Option<P<Expr>>, Option<P<Expr>>, Mutability),
|
ExprRange(Option<P<Expr>>, Option<P<Expr>>),
|
||||||
ExprRange(P<Expr>, Option<P<Expr>>),
|
|
||||||
|
|
||||||
/// Variable reference, possibly containing `::` and/or
|
/// Variable reference, possibly containing `::` and/or
|
||||||
/// type parameters, e.g. foo::bar::<baz>
|
/// type parameters, e.g. foo::bar::<baz>
|
||||||
|
@ -307,10 +307,10 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
|
|||||||
|
|
||||||
fn visit_expr(&mut self, e: &ast::Expr) {
|
fn visit_expr(&mut self, e: &ast::Expr) {
|
||||||
match e.node {
|
match e.node {
|
||||||
ast::ExprSlice(..) => {
|
ast::ExprRange(..) => {
|
||||||
self.gate_feature("slicing_syntax",
|
self.gate_feature("slicing_syntax",
|
||||||
e.span,
|
e.span,
|
||||||
"slicing syntax is experimental");
|
"range syntax is experimental");
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -1384,14 +1384,8 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) ->
|
|||||||
ExprIndex(el, er) => {
|
ExprIndex(el, er) => {
|
||||||
ExprIndex(folder.fold_expr(el), folder.fold_expr(er))
|
ExprIndex(folder.fold_expr(el), folder.fold_expr(er))
|
||||||
}
|
}
|
||||||
ExprSlice(e, e1, e2, m) => {
|
|
||||||
ExprSlice(folder.fold_expr(e),
|
|
||||||
e1.map(|x| folder.fold_expr(x)),
|
|
||||||
e2.map(|x| folder.fold_expr(x)),
|
|
||||||
m)
|
|
||||||
}
|
|
||||||
ExprRange(e1, e2) => {
|
ExprRange(e1, e2) => {
|
||||||
ExprRange(folder.fold_expr(e1),
|
ExprRange(e1.map(|x| folder.fold_expr(x)),
|
||||||
e2.map(|x| folder.fold_expr(x)))
|
e2.map(|x| folder.fold_expr(x)))
|
||||||
}
|
}
|
||||||
ExprPath(pth) => ExprPath(folder.fold_path(pth)),
|
ExprPath(pth) => ExprPath(folder.fold_path(pth)),
|
||||||
|
@ -25,7 +25,7 @@ use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, Explicit
|
|||||||
use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
|
use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
|
||||||
use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
|
use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
|
||||||
use ast::{ExprBreak, ExprCall, ExprCast};
|
use ast::{ExprBreak, ExprCall, ExprCast};
|
||||||
use ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex, ExprSlice};
|
use ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex};
|
||||||
use ast::{ExprLit, ExprLoop, ExprMac, ExprRange};
|
use ast::{ExprLit, ExprLoop, ExprMac, ExprRange};
|
||||||
use ast::{ExprMethodCall, ExprParen, ExprPath};
|
use ast::{ExprMethodCall, ExprParen, ExprPath};
|
||||||
use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
|
use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
|
||||||
@ -66,7 +66,7 @@ use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
|
|||||||
use ast::{Visibility, WhereClause};
|
use ast::{Visibility, WhereClause};
|
||||||
use ast;
|
use ast;
|
||||||
use ast_util::{mod, as_prec, ident_to_path, operator_prec};
|
use ast_util::{mod, as_prec, ident_to_path, operator_prec};
|
||||||
use codemap::{mod, Span, BytePos, Spanned, spanned, mk_sp};
|
use codemap::{mod, Span, BytePos, Spanned, spanned, mk_sp, DUMMY_SP};
|
||||||
use diagnostic;
|
use diagnostic;
|
||||||
use ext::tt::macro_parser;
|
use ext::tt::macro_parser;
|
||||||
use parse;
|
use parse;
|
||||||
@ -2135,16 +2135,23 @@ impl<'a> Parser<'a> {
|
|||||||
expr: P<Expr>,
|
expr: P<Expr>,
|
||||||
start: Option<P<Expr>>,
|
start: Option<P<Expr>>,
|
||||||
end: Option<P<Expr>>,
|
end: Option<P<Expr>>,
|
||||||
mutbl: Mutability)
|
_mutbl: Mutability)
|
||||||
-> ast::Expr_ {
|
-> ast::Expr_ {
|
||||||
ExprSlice(expr, start, end, mutbl)
|
// FIXME: we could give more accurate span info here.
|
||||||
|
let (lo, hi) = match (&start, &end) {
|
||||||
|
(&Some(ref s), &Some(ref e)) => (s.span.lo, e.span.hi),
|
||||||
|
(&Some(ref s), &None) => (s.span.lo, s.span.hi),
|
||||||
|
(&None, &Some(ref e)) => (e.span.lo, e.span.hi),
|
||||||
|
(&None, &None) => (DUMMY_SP.lo, DUMMY_SP.hi),
|
||||||
|
};
|
||||||
|
ExprIndex(expr, self.mk_expr(lo, hi, ExprRange(start, end)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_range(&mut self,
|
pub fn mk_range(&mut self,
|
||||||
start: P<Expr>,
|
start: P<Expr>,
|
||||||
end: Option<P<Expr>>)
|
end: Option<P<Expr>>)
|
||||||
-> ast::Expr_ {
|
-> ast::Expr_ {
|
||||||
ExprRange(start, end)
|
ExprRange(Some(start), end)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mk_field(&mut self, expr: P<Expr>, ident: ast::SpannedIdent) -> ast::Expr_ {
|
pub fn mk_field(&mut self, expr: P<Expr>, ident: ast::SpannedIdent) -> ast::Expr_ {
|
||||||
|
@ -1739,15 +1739,7 @@ impl<'a> State<'a> {
|
|||||||
try!(self.print_expr(&**index));
|
try!(self.print_expr(&**index));
|
||||||
try!(word(&mut self.s, "]"));
|
try!(word(&mut self.s, "]"));
|
||||||
}
|
}
|
||||||
ast::ExprSlice(ref e, ref start, ref end, ref mutbl) => {
|
ast::ExprRange(ref start, ref end) => {
|
||||||
try!(self.print_expr(&**e));
|
|
||||||
try!(word(&mut self.s, "["));
|
|
||||||
if mutbl == &ast::MutMutable {
|
|
||||||
try!(word(&mut self.s, "mut"));
|
|
||||||
if start.is_some() || end.is_some() {
|
|
||||||
try!(space(&mut self.s));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let &Some(ref e) = start {
|
if let &Some(ref e) = start {
|
||||||
try!(self.print_expr(&**e));
|
try!(self.print_expr(&**e));
|
||||||
}
|
}
|
||||||
@ -1757,14 +1749,6 @@ impl<'a> State<'a> {
|
|||||||
if let &Some(ref e) = end {
|
if let &Some(ref e) = end {
|
||||||
try!(self.print_expr(&**e));
|
try!(self.print_expr(&**e));
|
||||||
}
|
}
|
||||||
try!(word(&mut self.s, "]"));
|
|
||||||
}
|
|
||||||
ast::ExprRange(ref start, ref end) => {
|
|
||||||
try!(self.print_expr(&**start));
|
|
||||||
try!(word(&mut self.s, ".."));
|
|
||||||
if let &Some(ref e) = end {
|
|
||||||
try!(self.print_expr(&**e));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ast::ExprPath(ref path) => try!(self.print_path(path, true)),
|
ast::ExprPath(ref path) => try!(self.print_path(path, true)),
|
||||||
ast::ExprBreak(opt_ident) => {
|
ast::ExprBreak(opt_ident) => {
|
||||||
|
@ -866,13 +866,8 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
|
|||||||
visitor.visit_expr(&**main_expression);
|
visitor.visit_expr(&**main_expression);
|
||||||
visitor.visit_expr(&**index_expression)
|
visitor.visit_expr(&**index_expression)
|
||||||
}
|
}
|
||||||
ExprSlice(ref main_expression, ref start, ref end, _) => {
|
|
||||||
visitor.visit_expr(&**main_expression);
|
|
||||||
walk_expr_opt(visitor, start);
|
|
||||||
walk_expr_opt(visitor, end)
|
|
||||||
}
|
|
||||||
ExprRange(ref start, ref end) => {
|
ExprRange(ref start, ref end) => {
|
||||||
visitor.visit_expr(&**start);
|
walk_expr_opt(visitor, start);
|
||||||
walk_expr_opt(visitor, end)
|
walk_expr_opt(visitor, end)
|
||||||
}
|
}
|
||||||
ExprPath(ref path) => {
|
ExprPath(ref path) => {
|
||||||
|
@ -521,7 +521,7 @@ impl<I> Iterator<u16> for Utf16Encoder<I> where I: Iterator<char> {
|
|||||||
|
|
||||||
let mut buf = [0u16, ..2];
|
let mut buf = [0u16, ..2];
|
||||||
self.chars.next().map(|ch| {
|
self.chars.next().map(|ch| {
|
||||||
let n = ch.encode_utf16(buf[mut]).unwrap_or(0);
|
let n = ch.encode_utf16(buf.as_mut_slice()).unwrap_or(0);
|
||||||
if n == 2 { self.extra = buf[1]; }
|
if n == 2 { self.extra = buf[1]; }
|
||||||
buf[0]
|
buf[0]
|
||||||
})
|
})
|
||||||
|
@ -52,7 +52,7 @@ fn rotate(x: &mut [i32]) {
|
|||||||
|
|
||||||
fn next_permutation(perm: &mut [i32], count: &mut [i32]) {
|
fn next_permutation(perm: &mut [i32], count: &mut [i32]) {
|
||||||
for i in range(1, perm.len()) {
|
for i in range(1, perm.len()) {
|
||||||
rotate(perm[mut ..i + 1]);
|
rotate(perm.slice_to_mut(i + 1));
|
||||||
let count_i = &mut count[i];
|
let count_i = &mut count[i];
|
||||||
if *count_i >= i as i32 {
|
if *count_i >= i as i32 {
|
||||||
*count_i = 0;
|
*count_i = 0;
|
||||||
@ -131,7 +131,7 @@ impl Perm {
|
|||||||
|
|
||||||
|
|
||||||
fn reverse(tperm: &mut [i32], mut k: uint) {
|
fn reverse(tperm: &mut [i32], mut k: uint) {
|
||||||
tperm[mut ..k].reverse()
|
tperm.slice_to_mut(k).reverse()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn work(mut perm: Perm, n: uint, max: uint) -> (i32, i32) {
|
fn work(mut perm: Perm, n: uint, max: uint) -> (i32, i32) {
|
||||||
|
@ -128,7 +128,7 @@ impl<'a, W: Writer> RepeatFasta<'a, W> {
|
|||||||
|
|
||||||
copy_memory(buf.as_mut_slice(), alu);
|
copy_memory(buf.as_mut_slice(), alu);
|
||||||
let buf_len = buf.len();
|
let buf_len = buf.len();
|
||||||
copy_memory(buf[mut alu_len..buf_len],
|
copy_memory(buf.slice_mut(alu_len, buf_len),
|
||||||
alu[..LINE_LEN]);
|
alu[..LINE_LEN]);
|
||||||
|
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
|
@ -254,6 +254,6 @@ fn parallel<'a, I, T, F>(mut iter: I, f: F)
|
|||||||
fn main() {
|
fn main() {
|
||||||
let mut data = read_to_end(&mut stdin_raw()).unwrap();
|
let mut data = read_to_end(&mut stdin_raw()).unwrap();
|
||||||
let tables = &Tables::new();
|
let tables = &Tables::new();
|
||||||
parallel(mut_dna_seqs(data[mut]), |&: seq| reverse_complement(seq, tables));
|
parallel(mut_dna_seqs(data.as_mut_slice()), |&: seq| reverse_complement(seq, tables));
|
||||||
stdout_raw().write(data.as_mut_slice()).unwrap();
|
stdout_raw().write(data.as_mut_slice()).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// Test range syntax - type errors.
|
// Test range syntax - type errors.
|
||||||
|
#![feature(slicing_syntax)]
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
// Mixed types.
|
// Mixed types.
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// Test range syntax - borrow errors.
|
// Test range syntax - borrow errors.
|
||||||
|
#![feature(slicing_syntax)]
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let r = {
|
let r = {
|
||||||
|
@ -20,8 +20,4 @@ fn main() {
|
|||||||
x[Foo..]; //~ ERROR cannot take a slice of a value with type `Foo`
|
x[Foo..]; //~ ERROR cannot take a slice of a value with type `Foo`
|
||||||
x[..Foo]; //~ ERROR cannot take a slice of a value with type `Foo`
|
x[..Foo]; //~ ERROR cannot take a slice of a value with type `Foo`
|
||||||
x[Foo..Foo]; //~ ERROR cannot take a slice of a value with type `Foo`
|
x[Foo..Foo]; //~ ERROR cannot take a slice of a value with type `Foo`
|
||||||
x[mut]; //~ ERROR cannot take a mutable slice of a value with type `Foo`
|
|
||||||
x[mut Foo..]; //~ ERROR cannot take a mutable slice of a value with type `Foo`
|
|
||||||
x[mut ..Foo]; //~ ERROR cannot take a mutable slice of a value with type `Foo`
|
|
||||||
x[mut Foo..Foo]; //~ ERROR cannot take a mutable slice of a value with type `Foo`
|
|
||||||
}
|
}
|
||||||
|
@ -15,5 +15,6 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
let x: &[int] = &[1, 2, 3, 4, 5];
|
let x: &[int] = &[1, 2, 3, 4, 5];
|
||||||
// Can't mutably slice an immutable slice
|
// Can't mutably slice an immutable slice
|
||||||
let y = x[mut 2..4]; //~ ERROR cannot borrow
|
let slice: &mut [int] = &mut [0, 1];
|
||||||
|
x[2..4] = slice; //~ ERROR cannot borrow
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,4 @@ fn main() {
|
|||||||
let x: &[int] = &[1, 2, 3, 4, 5];
|
let x: &[int] = &[1, 2, 3, 4, 5];
|
||||||
// Immutable slices are not mutable.
|
// Immutable slices are not mutable.
|
||||||
let y: &mut[_] = x[2..4]; //~ ERROR cannot borrow immutable dereference of `&`-pointer as mutabl
|
let y: &mut[_] = x[2..4]; //~ ERROR cannot borrow immutable dereference of `&`-pointer as mutabl
|
||||||
|
|
||||||
let x: &mut [int] = &mut [1, 2, 3, 4, 5];
|
|
||||||
// Can't borrow mutably twice
|
|
||||||
let y = x[mut 1..2];
|
|
||||||
let y = x[mut 4..5]; //~ERROR cannot borrow
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
// Test range syntax.
|
// Test range syntax.
|
||||||
|
|
||||||
|
#![feature(slicing_syntax)]
|
||||||
|
|
||||||
fn foo() -> int { 42 }
|
fn foo() -> int { 42 }
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
Loading…
Reference in New Issue
Block a user