diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs index 2715ff0678af7..df8e08f07a321 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/ring_buf.rs @@ -453,7 +453,7 @@ impl RingBuf { if contiguous { let (empty, buf) = buf.split_at_mut(0); - (buf[mut tail..head], empty) + (buf.slice_mut(tail, head), empty) } else { let (mid, right) = buf.split_at_mut(tail); let (left, _) = mid.split_at_mut(head); diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index d6d94f57acf45..404804cd91d2e 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -94,7 +94,7 @@ use core::iter::{range_step, MultiplicativeIterator}; use core::kinds::Sized; use core::mem::size_of; 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::{Ord, Ordering, RawPtr, Some, range}; use core::ptr; @@ -1110,7 +1110,7 @@ impl SliceExt for [T] { #[inline] fn move_from(&mut self, mut src: Vec, 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); } cmp::min(self.len(), end-start) @@ -1326,7 +1326,7 @@ impl BorrowFrom> for [T] { #[unstable = "trait is unstable"] impl BorrowFromMut> for [T] { - fn borrow_from_mut(owned: &mut Vec) -> &mut [T] { owned[mut] } + fn borrow_from_mut(owned: &mut Vec) -> &mut [T] { owned.as_mut_slice_() } } #[unstable = "trait is unstable"] @@ -2491,14 +2491,14 @@ mod tests { assert!(a == [7i,2,3,4]); let mut a = [1i,2,3,4,5]; 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]); } #[test] fn test_reverse_part() { 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]); } @@ -2545,9 +2545,9 @@ mod tests { fn test_bytes_set_memory() { use slice::bytes::MutableByteVector; 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]); - values[mut 2..4].set_memory(0xFF); + values.slice_mut(2, 4).set_memory(0xFF); assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]); } diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index 47701ab8ffd63..329fe7c7b4913 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -179,7 +179,7 @@ pub fn float_to_str_bytes_common( _ => () } - buf[mut ..end].reverse(); + buf.slice_to_mut(end).reverse(); // Remember start of the fractional digits. // Points one beyond end of buf if none get generated, @@ -316,7 +316,7 @@ pub fn float_to_str_bytes_common( impl<'a> fmt::FormatWriter for Filler<'a> { 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); *self.end += bytes.len(); Ok(()) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 0cd8c1d69d1a1..f6b79ccc42b01 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -908,6 +908,14 @@ impl Iterator for RangeFrom { } } +/// A range which is only bounded above. +#[deriving(Copy)] +#[lang="range_to"] +pub struct RangeTo { + /// The upper bound of the range (exclusive). + pub end: Idx, +} + /// The `Deref` trait is used to specify the functionality of dereferencing /// operations like `*v`. diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 26684864c4c49..d25f96ac15fa6 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -264,24 +264,26 @@ impl SliceExt for [T] { fn as_mut_slice(&mut self) -> &mut [T] { self } 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] fn slice_from_mut(&mut self, start: uint) -> &mut [T] { - self[mut start..] + ops::SliceMut::slice_from_or_fail_mut(self, &start) } #[inline] fn slice_to_mut(&mut self, end: uint) -> &mut [T] { - self[mut ..end] + ops::SliceMut::slice_to_or_fail_mut(self, &end) } #[inline] fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]) { unsafe { 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 SliceExt for [T] { #[inline] fn tail_mut(&mut self) -> &mut [T] { - let len = self.len(); - self[mut 1..len] + self.slice_from_mut(1) } #[inline] fn init_mut(&mut self) -> &mut [T] { let len = self.len(); - self[mut 0..len - 1] + self.slice_to_mut(len-1) } #[inline] @@ -560,7 +561,7 @@ impl OrdSliceExt for [T] { self.swap(j, i-1); // Step 4: Reverse the (previously) weakly decreasing part - self[mut i..].reverse(); + self.slice_from_mut(i).reverse(); true } @@ -582,7 +583,7 @@ impl OrdSliceExt for [T] { } // 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) 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) => { let tmp = mem::replace(&mut self.v, &mut []); let (head, tail) = tmp.split_at_mut(idx); - self.v = tail[mut 1..]; + self.v = tail.slice_from_mut(1); 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 (head, tail) = tmp.split_at_mut(idx); self.v = head; - Some(tail[mut 1..]) + Some(tail.slice_from_mut(1)) } } } diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 1e7fe8f060c3e..1fc5f90028dad 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -897,6 +897,7 @@ impl<'a> Iterator<&'a str> for SplitStr<'a> { } } + /* Section: Comparing strings */ diff --git a/src/libcoretest/ops.rs b/src/libcoretest/ops.rs index a8889ce9e348b..430188c7e4322 100644 --- a/src/libcoretest/ops.rs +++ b/src/libcoretest/ops.rs @@ -9,7 +9,7 @@ // except according to those terms. use test::Bencher; -use core::ops::{Range, FullRange, RangeFrom}; +use core::ops::{Range, FullRange, RangeFrom, RangeTo}; // Overhead of dtors @@ -55,6 +55,12 @@ fn test_range_from() { assert!(count == 10); } +#[test] +fn test_range_to() { + // Not much to test. + let _ = RangeTo { end: 42u }; +} + #[test] fn test_full_range() { // Not much to test. diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index ce3df1090bd58..7dd0649e4837d 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -735,7 +735,7 @@ mod tests { fn test_input(g: LabelledGraph) -> IoResult { let mut writer = Vec::new(); 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, @@ -847,7 +847,7 @@ r#"digraph hasse_diagram { edge(1, 3, ";"), edge(2, 3, ";" ))); 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(), r#"digraph syntax_tree { diff --git a/src/librbml/io.rs b/src/librbml/io.rs index b46b977d7012d..cbe69295050ec 100644 --- a/src/librbml/io.rs +++ b/src/librbml/io.rs @@ -102,7 +102,7 @@ impl Writer for SeekableMemWriter { // Do the necessary writes 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 { self.buf.push_all(right); diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index f50790f7e9b15..92aa70548c82b 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -432,15 +432,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { 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) => { - 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()); self.straightline(expr, pred, fields) } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 1dfd602794f80..b7cfb22b85f8c 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -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] - if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], PassArgs::ByRef) { - self.select_from_expr(&**lhs); - self.consume_expr(&**rhs); + match rhs.node { + ast::ExprRange(ref start, ref end) => { + // 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) => { - self.consume_expr(&**start); + start.as_ref().map(|e| self.consume_expr(&**e)); end.as_ref().map(|e| self.consume_expr(&**e)); } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 90e3e2bb34aba..2aef430719923 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -269,6 +269,7 @@ lets_do_this! { SliceMutTraitLangItem, "slice_mut", slice_mut_trait; RangeStructLangItem, "range", range_struct; RangeFromStructLangItem, "range_from", range_from_struct; + RangeToStructLangItem, "range_to", range_to_struct; FullRangeStructLangItem, "full_range", full_range_struct; UnsafeTypeLangItem, "unsafe", unsafe_type; diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index f59a67e2e806d..d3859ca12a971 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -514,7 +514,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { ast::ExprBlock(..) | ast::ExprAssign(..) | ast::ExprAssignOp(..) | ast::ExprMac(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) | ast::ExprInlineAsm(..) | ast::ExprBox(..) | - ast::ExprSlice(..) | ast::ExprRange(..) => { + ast::ExprRange(..) => { visit::walk_expr(ir, expr); } } @@ -1191,15 +1191,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { 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) => { 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) | @@ -1495,7 +1489,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) { ast::ExprBlock(..) | ast::ExprMac(..) | ast::ExprAddrOf(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) | ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) | - ast::ExprSlice(..) | ast::ExprRange(..) => { + ast::ExprRange(..) => { visit::walk_expr(this, expr); } ast::ExprIfLet(..) => { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 87841c7675b91..5d3134b9629b2 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -500,21 +500,28 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { self.cat_tup_field(expr, base_cmt, idx.node, expr_ty) } - ast::ExprIndex(ref base, _) => { - let method_call = ty::MethodCall::expr(expr.id()); - 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) + ast::ExprIndex(ref base, ref idx) => { + match idx.node { + ast::ExprRange(..) => { + // Slicing syntax special case (KILLME). + self.cat_rvalue_node(expr.id(), expr.span(), expr_ty) } - None => { - let base_cmt = self.cat_expr(&**base); - self.cat_index(expr, base_cmt) + _ => { + let method_call = ty::MethodCall::expr(expr.id()); + 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::ExprAssign(..) | ast::ExprAssignOp(..) | ast::ExprClosure(..) | ast::ExprRet(..) | - ast::ExprUnary(..) | ast::ExprSlice(..) | ast::ExprRange(..) | + ast::ExprUnary(..) | ast::ExprRange(..) | ast::ExprMethodCall(..) | ast::ExprCast(..) | ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) | ast::ExprBinary(..) | ast::ExprWhile(..) | diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 8df78281cc227..392724bc9a18e 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -485,6 +485,7 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) { let prev_cx = visitor.cx; visitor.cx.parent = Some(expr.id); + { let region_maps = &mut visitor.region_maps; let terminating = |id| { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 398e52cf0430b..232646f64a7d1 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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` ast::ExprIndex(..) => LvalueExpr, - // the slice method invoked for `a[..]` always yields an `&T` - ast::ExprSlice(..) => LvalueExpr, - // `for` loops are statements ast::ExprForLoop(..) => RvalueStmtExpr, @@ -4389,8 +4386,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { ast::ExprUnary(ast::UnDeref, _) | ast::ExprField(..) | ast::ExprTupField(..) | - ast::ExprIndex(..) | - ast::ExprSlice(..) => { + ast::ExprIndex(..) => { LvalueExpr } diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs index 074341ccff49d..e1f0168d86be4 100644 --- a/src/librustc_back/sha2.rs +++ b/src/librustc_back/sha2.rs @@ -139,14 +139,14 @@ impl FixedBuffer for FixedBuffer64 { let buffer_remaining = size - self.buffer_idx; if input.len() >= buffer_remaining { copy_memory( - self.buffer[mut self.buffer_idx..size], + self.buffer.slice_mut(self.buffer_idx, size), input[..buffer_remaining]); self.buffer_idx = 0; func(&self.buffer); i += buffer_remaining; } else { 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); self.buffer_idx += input.len(); return; @@ -165,7 +165,7 @@ impl FixedBuffer for FixedBuffer64 { // be empty. let input_remaining = input.len() - i; copy_memory( - self.buffer[mut ..input_remaining], + self.buffer.slice_to_mut(input_remaining), input[i..]); self.buffer_idx += input_remaining; } @@ -176,13 +176,13 @@ impl FixedBuffer for FixedBuffer64 { fn zero_until(&mut self, idx: uint) { 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; } fn next<'s>(&'s mut self, len: uint) -> &'s mut [u8] { 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] { @@ -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 // the compiler to generate better code. @@ -498,14 +498,14 @@ impl Digest for Sha256 { fn result(&mut self, out: &mut [u8]) { self.engine.finish(); - write_u32_be(out[mut 0..4], self.engine.state.h0); - write_u32_be(out[mut 4..8], self.engine.state.h1); - write_u32_be(out[mut 8..12], self.engine.state.h2); - write_u32_be(out[mut 12..16], self.engine.state.h3); - write_u32_be(out[mut 16..20], self.engine.state.h4); - write_u32_be(out[mut 20..24], self.engine.state.h5); - write_u32_be(out[mut 24..28], self.engine.state.h6); - write_u32_be(out[mut 28..32], self.engine.state.h7); + write_u32_be(out.slice_mut(0, 4), self.engine.state.h0); + write_u32_be(out.slice_mut(4, 8), self.engine.state.h1); + write_u32_be(out.slice_mut(8, 12), self.engine.state.h2); + write_u32_be(out.slice_mut(12, 16), self.engine.state.h3); + write_u32_be(out.slice_mut(16, 20), self.engine.state.h4); + write_u32_be(out.slice_mut(20, 24), self.engine.state.h5); + write_u32_be(out.slice_mut(24, 28), self.engine.state.h6); + write_u32_be(out.slice_mut(28, 32), self.engine.state.h7); } fn reset(&mut self) { diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs index c68e9055269c0..2374e8b340be7 100644 --- a/src/librustc_back/svh.rs +++ b/src/librustc_back/svh.rs @@ -246,7 +246,6 @@ mod svh_visitor { SawExprAssign, SawExprAssignOp(ast::BinOp), SawExprIndex, - SawExprSlice, SawExprRange, SawExprPath, SawExprAddrOf(ast::Mutability), @@ -280,7 +279,6 @@ mod svh_visitor { ExprField(_, id) => SawExprField(content(id.node)), ExprTupField(_, id) => SawExprTupField(id.node), ExprIndex(..) => SawExprIndex, - ExprSlice(..) => SawExprSlice, ExprRange(..) => SawExprRange, ExprPath(..) => SawExprPath, ExprAddrOf(m, _) => SawExprAddrOf(m), diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index c1bb21c496adf..f96aa484ffc95 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -24,7 +24,8 @@ use trans::common; use trans::common::{Block, FunctionContext, ExprId, NodeInfo}; use trans::debuginfo; use trans::glue; -use middle::region; +// Temporary due to slicing syntax hacks (KILLME) +//use middle::region; use trans::type_::Type; use middle::ty::{mod, Ty}; 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 // 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. - 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() { assert_eq!(self.ccx .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)) .map(|s|s.node_id()), top_scope); - } + }*/ self.push_scope(CleanupScope::new(AstScopeKind(debug_loc.id), Some(debug_loc))); diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index ea2d42bebdfc4..56c42c7afdeb8 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -3533,20 +3533,14 @@ fn create_scope_map(cx: &CrateContext, } ast::ExprAssignOp(_, ref lhs, ref rhs) | - ast::ExprIndex(ref lhs, ref rhs) | + ast::ExprIndex(ref lhs, ref rhs) | ast::ExprBinary(_, ref lhs, ref rhs) => { walk_expr(cx, &**lhs, 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) => { - 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)); } diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 60b5a08c7c5df..f49769ba0d9c6 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -585,36 +585,40 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, trans_rec_tup_field(bcx, &**base, idx.node) } ast::ExprIndex(ref base, ref idx) => { - trans_index(bcx, expr, &**base, &**idx, MethodCall::expr(expr.id)) - } - ast::ExprSlice(ref base, ref start, ref end, _) => { - let _icx = push_ctxt("trans_slice"); - let ccx = bcx.ccx(); - - let method_call = MethodCall::expr(expr.id); - let method_ty = ccx.tcx() - .method_map - .borrow() - .get(&method_call) - .map(|method| method.ty); - let base_datum = unpack_datum!(bcx, trans(bcx, &**base)); - - let mut args = vec![]; - 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))); - - let result_ty = ty::ty_fn_ret(monomorphize_type(bcx, method_ty.unwrap())).unwrap(); - let scratch = rvalue_scratch_datum(bcx, result_ty, "trans_slice"); - - unpack_result!(bcx, - trans_overloaded_op(bcx, - expr, - method_call, - base_datum, - args, - Some(SaveIn(scratch.val)), - true)); - DatumBlock::new(bcx, scratch.to_expr_datum()) + match idx.node { + ast::ExprRange(ref start, ref end) => { + // Special case for slicing syntax (KILLME). + let _icx = push_ctxt("trans_slice"); + let ccx = bcx.ccx(); + + let method_call = MethodCall::expr(expr.id); + let method_ty = ccx.tcx() + .method_map + .borrow() + .get(&method_call) + .map(|method| method.ty); + let base_datum = unpack_datum!(bcx, trans(bcx, &**base)); + + let mut args = vec![]; + 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))); + + let result_ty = ty::ty_fn_ret(monomorphize_type(bcx, + method_ty.unwrap())).unwrap(); + let scratch = rvalue_scratch_datum(bcx, result_ty, "trans_slice"); + + unpack_result!(bcx, + trans_overloaded_op(bcx, + expr, + method_call, + base_datum, + args, + Some(SaveIn(scratch.val)), + true)); + DatumBlock::new(bcx, scratch.to_expr_datum()) + } + _ => trans_index(bcx, expr, &**base, &**idx, MethodCall::expr(expr.id)) + } } ast::ExprBox(_, ref contents) => { // Special case for `Box` @@ -1064,22 +1068,34 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } // A range just desugars into a struct. - let (did, fields) = match end { - &Some(ref end) => { + // Note that the type of the start and end may not be the same, but + // 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 - let fields = vec!(make_field("start", start.clone()), - make_field("end", end.clone())); - (tcx.lang_items.range_struct(), fields) + let fields = vec![make_field("start", start.clone()), + make_field("end", end.clone())]; + (tcx.lang_items.range_struct(), fields, vec![node_id_type(bcx, start.id)]) } - &None => { + (&Some(ref start), &None) => { // Desugar to RangeFrom - let fields = vec!(make_field("start", start.clone())); - (tcx.lang_items.range_from_struct(), fields) + let fields = vec![make_field("start", start.clone())]; + (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 { - let substs = Substs::new_type(vec![node_id_type(bcx, start.id)], vec![]); + let substs = Substs::new_type(ty_params, vec![]); trans_struct(bcx, fields.as_slice(), None, diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 8ce7a7edb46d1..cf6715e2d7320 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -488,7 +488,6 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { ast::ExprParen(ref expr) | ast::ExprField(ref expr, _) | ast::ExprTupField(ref expr, _) | - ast::ExprSlice(ref expr, _, _, _) | ast::ExprIndex(ref expr, _) | ast::ExprUnary(ast::UnDeref, ref expr) => exprs.push(&**expr), _ => break, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 68cf139338aa2..fb23ad8e340ce 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2003,7 +2003,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } -#[deriving(Copy, Show)] +#[deriving(Copy, Show,PartialEq,Eq)] pub enum LvaluePreference { PreferMutLvalue, 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>, - end_expr: &Option>, - mutbl: ast::Mutability) - -> Option> // 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, /// 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_ty: Ty<'tcx>, // autoderef'd type autoderefref: ty::AutoDerefRef<'tcx>, - mutbl: ast::Mutability, + lvalue_pref: LvaluePreference, start_expr: &Option>, end_expr: &Option>) - // result type is type of method being called - -> Option> + -> Option<(Ty<'tcx>, /* index type */ + Ty<'tcx>)> /* return type */ { - let method = if mutbl == ast::MutMutable { - // Try `SliceMut` first, if preferred. - 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_", - }; + let input_ty = fcx.infcx().next_ty_var(); + let return_ty = fcx.infcx().next_ty_var(); - method::lookup_in_trait_adjusted(fcx, - expr.span, - Some(&*base_expr), - token::intern(method_name), - trait_did, - autoderefref, - base_ty, - None) + let method = match lvalue_pref { + PreferMutLvalue => { + // Try `SliceMut` first, if preferred. + 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, + expr.span, + Some(&*base_expr), + token::intern(method_name), + trait_did, + autoderefref, + base_ty, + Some(vec![input_ty, return_ty])) + } + _ => None, } - _ => None, } - } else { - // Otherwise, fall back to `Slice`. - // FIXME(#17293) this will not coerce base_expr, so we miss the Slice - // trait for `&mut [T]`. - match fcx.tcx().lang_items.slice_trait() { - Some(trait_did) => { - let method_name = match (start_expr, end_expr) { - (&Some(_), &Some(_)) => "slice_or_fail", - (&Some(_), &None) => "slice_from_or_fail", - (&None, &Some(_)) => "slice_to_or_fail", - (&None, &None) => "as_slice_", - }; + NoPreference => { + // Otherwise, fall back to `Slice`. + match fcx.tcx().lang_items.slice_trait() { + Some(trait_did) => { + let method_name = match (start_expr, end_expr) { + (&Some(_), &Some(_)) => "slice_or_fail", + (&Some(_), &None) => "slice_from_or_fail", + (&None, &Some(_)) => "slice_to_or_fail", + (&None, &None) => "as_slice_", + }; - method::lookup_in_trait_adjusted(fcx, - expr.span, - Some(&*base_expr), - token::intern(method_name), - trait_did, - autoderefref, - base_ty, - None) + 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, } }; // If some lookup succeeded, install method in table method.map(|method| { - let ty = method.ty; - fcx.inh.method_map.borrow_mut().insert(method_call, method); - ty + let method_ty = method.ty; + make_overloaded_lvalue_return_type(fcx, Some(method_call), Some(method)); + + 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) => { check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref); - check_expr(fcx, &**idx); let base_t = fcx.expr_ty(&**base); - let idx_t = fcx.expr_ty(&**idx); if ty::type_is_error(base_t) { fcx.write_ty(id, base_t); - } else if ty::type_is_error(idx_t) { - fcx.write_ty(id, idx_t); } else { - let base_t = structurally_resolved_type(fcx, expr.span, base_t); - - let result = - autoderef_for_index(fcx, &**base, base_t, lvalue_pref, |adj_ty, adj| { - try_index_step(fcx, - MethodCall::expr(expr.id), - expr, - &**base, - adj_ty, - adj, - lvalue_pref) - }); - - match result { - Some((index_ty, element_ty)) => { - check_expr_has_type(fcx, &**idx, index_ty); - fcx.write_ty(id, element_ty); - } - _ => { - check_expr_has_type(fcx, &**idx, ty::mk_err()); - fcx.type_error_message( - expr.span, - |actual| { - format!("cannot index a value of type `{}`", - actual) - }, - base_t, - None); - fcx.write_ty(id, ty::mk_err()) + 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 = + autoderef_for_index(fcx, &**base, base_t, lvalue_pref, |adj_ty, adj| { + try_overloaded_slice_step(fcx, + MethodCall::expr(expr.id), + expr, + &**base, + adj_ty, + adj, + lvalue_pref, + start, + end) + }); + + let mut args = vec![]; + start.as_ref().map(|x| args.push(x)); + end.as_ref().map(|x| args.push(x)); + + 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()) + } } - } - } - } - 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; - if ty::type_is_error(raw_base_t) { - fcx.write_ty(id, raw_base_t); - some_err = true; - } - - { - let check_slice_idx = |e: &ast::Expr| { - check_expr(fcx, e); - let e_t = fcx.expr_ty(e); - if ty::type_is_error(e_t) { - fcx.write_ty(e.id, e_t); - some_err = true; - } - }; - start.as_ref().map(|e| check_slice_idx(&**e)); - end.as_ref().map(|e| check_slice_idx(&**e)); - } - - if !some_err { - let base_t = structurally_resolved_type(fcx, - expr.span, - 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()) + } + _ => { + check_expr(fcx, &**idx); + let idx_t = fcx.expr_ty(&**idx); + if ty::type_is_error(idx_t) { + fcx.write_ty(id, idx_t); + } else { + let base_t = structurally_resolved_type(fcx, expr.span, base_t); + + let result = + autoderef_for_index(fcx, &**base, base_t, lvalue_pref, |adj_ty, adj| { + try_index_step(fcx, + MethodCall::expr(expr.id), + expr, + &**base, + adj_ty, + adj, + lvalue_pref) + }); + + match result { + Some((index_ty, element_ty)) => { + check_expr_has_type(fcx, &**idx, index_ty); + fcx.write_ty(id, element_ty); + } + _ => { + check_expr_has_type(fcx, &**idx, ty::mk_err()); + fcx.type_error_message( + expr.span, + |actual| { + format!("cannot index a value of type `{}`", + actual) + }, + base_t, + None); + fcx.write_ty(id, ty::mk_err()) + } + } } + } } } } ast::ExprRange(ref start, ref end) => { - check_expr(fcx, &**start); - let t_start = fcx.expr_ty(&**start); - - let idx_type = if let &Some(ref e) = end { + let t_start = start.as_ref().map(|e| { check_expr(fcx, &**e); - let t_end = fcx.expr_ty(&**e); - if ty::type_is_error(t_end) { - ty::mk_err() - } else if t_start == ty::mk_err() { - ty::mk_err() - } else { - infer::common_supertype(fcx.infcx(), - infer::RangeExpression(expr.span), - true, - t_start, - t_end) + fcx.expr_ty(&**e) + }); + let t_end = end.as_ref().map(|e| { + check_expr(fcx, &**e); + fcx.expr_ty(&**e) + }); + + let idx_type = match (t_start, t_end) { + (Some(ty), None) | (None, Some(ty)) => Some(ty), + (Some(t_start), Some(t_end)) + if ty::type_is_error(t_start) || ty::type_is_error(t_end) => { + Some(ty::mk_err()) } - } else { - t_start + (Some(t_start), Some(t_end)) => { + 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 // 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. - let range_type = if idx_type == ty::mk_err() { - ty::mk_err() - } 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 { + let range_type = match idx_type { + Some(idx_type) if ty::type_is_error(idx_type) => { 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); } diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index c26450310a9b2..fdbce101c1d6c 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -104,7 +104,7 @@ impl BufferedReader { impl Buffer for BufferedReader { fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { 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; } Ok(self.buf[self.pos..self.cap]) @@ -219,7 +219,7 @@ impl Writer for BufferedWriter { if buf.len() > self.buf.len() { self.inner.as_mut().unwrap().write(buf) } else { - let dst = self.buf[mut self.pos..]; + let dst = self.buf.slice_from_mut(self.pos); slice::bytes::copy_memory(dst, buf); self.pos += buf.len(); Ok(()) diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs index 3a18b0dc1b525..5f68bbef93220 100644 --- a/src/libstd/io/comm_adapters.rs +++ b/src/libstd/io/comm_adapters.rs @@ -87,7 +87,7 @@ impl Reader for ChanReader { loop { let count = match self.fill_buf().ok() { Some(src) => { - let dst = buf[mut num_read..]; + let dst = buf.slice_from_mut(num_read); let count = cmp::min(src.len(), dst.len()); bytes::copy_memory(dst, src[..count]); count diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index 4e736908c3720..f2db2875ebf2c 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -931,11 +931,11 @@ mod test { { 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)); } { - let read_buf = read_mem[mut 4..8]; + let read_buf = read_mem.slice_mut(4, 8); check!(read_stream.read(read_buf)); } } diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs index 01151059530f0..20b1162d859c7 100644 --- a/src/libstd/io/mem.rs +++ b/src/libstd/io/mem.rs @@ -169,7 +169,7 @@ impl Reader for MemReader { let write_len = min(buf.len(), self.buf.len() - self.pos); { 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()); 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 input = self[..write_len]; - let output = buf[mut ..write_len]; + let output = buf.slice_to_mut(write_len); slice::bytes::copy_memory(output, input); } @@ -279,7 +279,7 @@ impl<'a> BufWriter<'a> { impl<'a> Writer for BufWriter<'a> { #[inline] 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(); 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 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()); slice::bytes::copy_memory(output, input); } @@ -652,7 +652,7 @@ mod test { assert!(r.read_at_least(buf.len(), &mut buf).is_ok()); let b: &[_] = &[1, 2, 3]; 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!(r.read_at_least(buf.len(), &mut buf).is_ok()); let b: &[_] = &[4, 5, 6]; diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index b6f8bb25b6531..e1f5efae79fc7 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -513,7 +513,7 @@ pub trait Reader { while read < min { let mut zeroes = 0; loop { - match self.read(buf[mut read..]) { + match self.read(buf.slice_from_mut(read)) { Ok(0) => { zeroes += 1; if zeroes >= NO_PROGRESS_LIMIT { @@ -1123,7 +1123,7 @@ pub trait Writer { #[inline] fn write_char(&mut self, c: char) -> IoResult<()> { 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]) } @@ -1555,7 +1555,7 @@ pub trait Buffer: Reader { { let mut start = 1; 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 => { start += n; } _ => return Err(standard_error(InvalidInput)), diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs index add986387daf7..4830b15a8432e 100644 --- a/src/libstd/io/net/ip.rs +++ b/src/libstd/io/net/ip.rs @@ -250,7 +250,7 @@ impl<'a> Parser<'a> { assert!(head.len() + tail.len() <= 8); let mut gs = [0u16, ..8]; 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]) } diff --git a/src/libstd/io/net/udp.rs b/src/libstd/io/net/udp.rs index a36703172c3ca..5bf47dceb5a0e 100644 --- a/src/libstd/io/net/udp.rs +++ b/src/libstd/io/net/udp.rs @@ -49,7 +49,7 @@ use sys_common; /// match socket.recv_from(&mut buf) { /// Ok((amt, src)) => { /// // Send a reply to the socket we received data from -/// let buf = buf[mut ..amt]; +/// let buf = buf.slice_to_mut(amt); /// buf.reverse(); /// socket.send_to(buf, src); /// } diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs index 18fabcbd1a2a4..43893ca012653 100644 --- a/src/libstd/io/util.rs +++ b/src/libstd/io/util.rs @@ -51,7 +51,7 @@ impl Reader for LimitReader { } 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 { Ok(len) => self.limit -= len, _ => {} diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index 68c99b1275855..46c3a4f622a54 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -55,7 +55,7 @@ mod imp { let mut read = 0; let len = v.len(); while read < len { - let result = getrandom(v[mut read..]); + let result = getrandom(v.slice_from_mut(read)); if result == -1 { let err = errno() as libc::c_int; if err == libc::EINTR { diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs index 26dadfd9fb1db..6b007056a5114 100644 --- a/src/libstd/rt/util.rs +++ b/src/libstd/rt/util.rs @@ -139,7 +139,7 @@ fn abort_(args: &fmt::Arguments) -> ! { } impl<'a> FormatWriter for BufWriter<'a> { 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())]; slice::bytes::copy_memory(left, to_write); self.pos += to_write.len(); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d4932fbb5f1c5..debcbcd2154bd 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -723,8 +723,7 @@ pub enum Expr_ { ExprField(P, SpannedIdent), ExprTupField(P, Spanned), ExprIndex(P, P), - ExprSlice(P, Option>, Option>, Mutability), - ExprRange(P, Option>), + ExprRange(Option>, Option>), /// Variable reference, possibly containing `::` and/or /// type parameters, e.g. foo::bar:: diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 28f7a78ddd08a..4607520655ea1 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -307,10 +307,10 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { fn visit_expr(&mut self, e: &ast::Expr) { match e.node { - ast::ExprSlice(..) => { + ast::ExprRange(..) => { self.gate_feature("slicing_syntax", e.span, - "slicing syntax is experimental"); + "range syntax is experimental"); } _ => {} } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index c58901701f530..11a9fdee0b9b0 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1384,14 +1384,8 @@ pub fn noop_fold_expr(Expr {id, node, span}: Expr, folder: &mut T) -> ExprIndex(el, 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(folder.fold_expr(e1), + ExprRange(e1.map(|x| folder.fold_expr(x)), e2.map(|x| folder.fold_expr(x))) } ExprPath(pth) => ExprPath(folder.fold_path(pth)), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a2e2abab03e55..2f43661eebeba 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -25,7 +25,7 @@ use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, Explicit use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain}; use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox}; 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::{ExprMethodCall, ExprParen, ExprPath}; use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary}; @@ -66,7 +66,7 @@ use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::{Visibility, WhereClause}; use ast; 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 ext::tt::macro_parser; use parse; @@ -2135,16 +2135,23 @@ impl<'a> Parser<'a> { expr: P, start: Option>, end: Option>, - mutbl: Mutability) + _mutbl: Mutability) -> 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, start: P, end: Option>) -> ast::Expr_ { - ExprRange(start, end) + ExprRange(Some(start), end) } pub fn mk_field(&mut self, expr: P, ident: ast::SpannedIdent) -> ast::Expr_ { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 623f20bccd2ee..accffbc35babe 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1739,15 +1739,7 @@ impl<'a> State<'a> { try!(self.print_expr(&**index)); try!(word(&mut self.s, "]")); } - ast::ExprSlice(ref e, ref start, ref end, ref mutbl) => { - 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)); - } - } + ast::ExprRange(ref start, ref end) => { if let &Some(ref e) = start { try!(self.print_expr(&**e)); } @@ -1757,14 +1749,6 @@ impl<'a> State<'a> { if let &Some(ref e) = end { 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::ExprBreak(opt_ident) => { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 714339d0f0aaa..22cfea862517e 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -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(&**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) => { - visitor.visit_expr(&**start); + walk_expr_opt(visitor, start); walk_expr_opt(visitor, end) } ExprPath(ref path) => { diff --git a/src/libunicode/u_str.rs b/src/libunicode/u_str.rs index 3b0cc1443f0c7..398728bb51652 100644 --- a/src/libunicode/u_str.rs +++ b/src/libunicode/u_str.rs @@ -521,7 +521,7 @@ impl Iterator for Utf16Encoder where I: Iterator { let mut buf = [0u16, ..2]; 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]; } buf[0] }) diff --git a/src/test/bench/shootout-fannkuch-redux.rs b/src/test/bench/shootout-fannkuch-redux.rs index 723b2b722d7e1..ef38f5ef74341 100644 --- a/src/test/bench/shootout-fannkuch-redux.rs +++ b/src/test/bench/shootout-fannkuch-redux.rs @@ -52,7 +52,7 @@ fn rotate(x: &mut [i32]) { fn next_permutation(perm: &mut [i32], count: &mut [i32]) { 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]; if *count_i >= i as i32 { *count_i = 0; @@ -131,7 +131,7 @@ impl Perm { 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) { diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs index eb18cfdaed3ad..178d6777939d8 100644 --- a/src/test/bench/shootout-fasta-redux.rs +++ b/src/test/bench/shootout-fasta-redux.rs @@ -128,7 +128,7 @@ impl<'a, W: Writer> RepeatFasta<'a, W> { copy_memory(buf.as_mut_slice(), alu); 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]); let mut pos = 0; diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs index 66965110f73ee..6ee2233f16862 100644 --- a/src/test/bench/shootout-reverse-complement.rs +++ b/src/test/bench/shootout-reverse-complement.rs @@ -254,6 +254,6 @@ fn parallel<'a, I, T, F>(mut iter: I, f: F) fn main() { let mut data = read_to_end(&mut stdin_raw()).unwrap(); 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(); } diff --git a/src/test/compile-fail/range-1.rs b/src/test/compile-fail/range-1.rs index ca7401dc26c8c..4af748661fd12 100644 --- a/src/test/compile-fail/range-1.rs +++ b/src/test/compile-fail/range-1.rs @@ -9,6 +9,7 @@ // except according to those terms. // Test range syntax - type errors. +#![feature(slicing_syntax)] pub fn main() { // Mixed types. diff --git a/src/test/compile-fail/range-2.rs b/src/test/compile-fail/range-2.rs index 40690bd844bce..74c304884a07c 100644 --- a/src/test/compile-fail/range-2.rs +++ b/src/test/compile-fail/range-2.rs @@ -9,6 +9,7 @@ // except according to those terms. // Test range syntax - borrow errors. +#![feature(slicing_syntax)] pub fn main() { let r = { diff --git a/src/test/compile-fail/slice-2.rs b/src/test/compile-fail/slice-2.rs index 63f79c808ae22..24f710d2ae3f4 100644 --- a/src/test/compile-fail/slice-2.rs +++ b/src/test/compile-fail/slice-2.rs @@ -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..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` } diff --git a/src/test/compile-fail/slice-mut-2.rs b/src/test/compile-fail/slice-mut-2.rs index 6778ed88ff70b..8970bcfd153a1 100644 --- a/src/test/compile-fail/slice-mut-2.rs +++ b/src/test/compile-fail/slice-mut-2.rs @@ -15,5 +15,6 @@ fn main() { let x: &[int] = &[1, 2, 3, 4, 5]; // 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 } diff --git a/src/test/compile-fail/slice-mut.rs b/src/test/compile-fail/slice-mut.rs index cbfa3ed85fd6c..ad6b384d74701 100644 --- a/src/test/compile-fail/slice-mut.rs +++ b/src/test/compile-fail/slice-mut.rs @@ -16,9 +16,4 @@ fn main() { let x: &[int] = &[1, 2, 3, 4, 5]; // Immutable slices are not mutable. 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 } diff --git a/src/test/run-pass/range.rs b/src/test/run-pass/range.rs index 027121dd4229d..864cee03f24da 100644 --- a/src/test/run-pass/range.rs +++ b/src/test/run-pass/range.rs @@ -10,6 +10,8 @@ // Test range syntax. +#![feature(slicing_syntax)] + fn foo() -> int { 42 } pub fn main() {