about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-12-30 00:42:13 +0000
committerbors <bors@rust-lang.org>2014-12-30 00:42:13 +0000
commitfea5aa656ff4349f4d3e1fea1447d26986762ae1 (patch)
tree3736614e84499fcde1623619b6e1336f2b2221d6 /src
parent71123902e17ad339649f33423995eac78da40e3c (diff)
parent113f8aa86b64c0be1981a69d110e42d22460b33c (diff)
downloadrust-fea5aa656ff4349f4d3e1fea1447d26986762ae1.tar.gz
rust-fea5aa656ff4349f4d3e1fea1447d26986762ae1.zip
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)
Diffstat (limited to 'src')
-rw-r--r--src/libcollections/ring_buf.rs2
-rw-r--r--src/libcollections/slice.rs14
-rw-r--r--src/libcore/fmt/float.rs4
-rw-r--r--src/libcore/ops.rs8
-rw-r--r--src/libcore/slice.rs23
-rw-r--r--src/libcore/str/mod.rs1
-rw-r--r--src/libcoretest/ops.rs8
-rw-r--r--src/libgraphviz/lib.rs4
-rw-r--r--src/librbml/io.rs2
-rw-r--r--src/librustc/middle/cfg/construct.rs9
-rw-r--r--src/librustc/middle/expr_use_visitor.rs39
-rw-r--r--src/librustc/middle/lang_items.rs1
-rw-r--r--src/librustc/middle/liveness.rs12
-rw-r--r--src/librustc/middle/mem_categorization.rs37
-rw-r--r--src/librustc/middle/region.rs1
-rw-r--r--src/librustc/middle/ty.rs6
-rw-r--r--src/librustc_back/sha2.rs28
-rw-r--r--src/librustc_back/svh.rs2
-rw-r--r--src/librustc_trans/trans/cleanup.rs8
-rw-r--r--src/librustc_trans/trans/debuginfo.rs10
-rw-r--r--src/librustc_trans/trans/expr.rs94
-rw-r--r--src/librustc_typeck/check/method/confirm.rs1
-rw-r--r--src/librustc_typeck/check/mod.rs431
-rw-r--r--src/libstd/io/buffered.rs4
-rw-r--r--src/libstd/io/comm_adapters.rs2
-rw-r--r--src/libstd/io/fs.rs4
-rw-r--r--src/libstd/io/mem.rs10
-rw-r--r--src/libstd/io/mod.rs6
-rw-r--r--src/libstd/io/net/ip.rs2
-rw-r--r--src/libstd/io/net/udp.rs2
-rw-r--r--src/libstd/io/util.rs2
-rw-r--r--src/libstd/rand/os.rs2
-rw-r--r--src/libstd/rt/util.rs2
-rw-r--r--src/libsyntax/ast.rs3
-rw-r--r--src/libsyntax/feature_gate.rs4
-rw-r--r--src/libsyntax/fold.rs8
-rw-r--r--src/libsyntax/parse/parser.rs17
-rw-r--r--src/libsyntax/print/pprust.rs18
-rw-r--r--src/libsyntax/visit.rs7
-rw-r--r--src/libunicode/u_str.rs2
-rw-r--r--src/test/bench/shootout-fannkuch-redux.rs4
-rw-r--r--src/test/bench/shootout-fasta-redux.rs2
-rw-r--r--src/test/bench/shootout-reverse-complement.rs2
-rw-r--r--src/test/compile-fail/range-1.rs1
-rw-r--r--src/test/compile-fail/range-2.rs1
-rw-r--r--src/test/compile-fail/slice-2.rs4
-rw-r--r--src/test/compile-fail/slice-mut-2.rs3
-rw-r--r--src/test/compile-fail/slice-mut.rs5
-rw-r--r--src/test/run-pass/range.rs2
49 files changed, 421 insertions, 443 deletions
diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs
index 2715ff0678a..df8e08f07a3 100644
--- a/src/libcollections/ring_buf.rs
+++ b/src/libcollections/ring_buf.rs
@@ -453,7 +453,7 @@ impl<T> RingBuf<T> {
 
             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 d6d94f57acf..404804cd91d 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<T> SliceExt<T> for [T] {
 
     #[inline]
     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);
         }
         cmp::min(self.len(), end-start)
@@ -1326,7 +1326,7 @@ impl<T> BorrowFrom<Vec<T>> for [T] {
 
 #[unstable = "trait is unstable"]
 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"]
@@ -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 47701ab8ffd..329fe7c7b49 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -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.
     // 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> {
                 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 0cd8c1d69d1..f6b79ccc42b 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -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
 /// operations like `*v`.
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 26684864c4c..d25f96ac15f 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -264,24 +264,26 @@ impl<T> SliceExt<T> 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<T> SliceExt<T> 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<T: Ord> OrdSliceExt<T> 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<T: Ord> OrdSliceExt<T> 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 1e7fe8f060c..1fc5f90028d 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 a8889ce9e34..430188c7e43 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
 
@@ -56,6 +56,12 @@ fn test_range_from() {
 }
 
 #[test]
+fn test_range_to() {
+    // Not much to test.
+    let _ = RangeTo { end: 42u };
+}
+
+#[test]
 fn test_full_range() {
     // Not much to test.
     let _ = FullRange;
diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs
index ce3df1090bd..7dd0649e483 100644
--- a/src/libgraphviz/lib.rs
+++ b/src/libgraphviz/lib.rs
@@ -735,7 +735,7 @@ mod tests {
     fn test_input(g: LabelledGraph) -> IoResult<String> {
         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 b46b977d701..cbe69295050 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 f50790f7e9b..92aa70548c8 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 1dfd602794f..b7cfb22b85f 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 90e3e2bb34a..2aef4307199 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 f59a67e2e80..d3859ca12a9 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 87841c7675b..5d3134b9629 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 8df78281cc2..392724bc9a1 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 398e52cf043..232646f64a7 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 074341ccff4..e1f0168d86b 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 c68e9055269..2374e8b340b 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 c1bb21c496a..f96aa484ffc 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 ea2d42bebdf..56c42c7afde 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 60b5a08c7c5..f49769ba0d9 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<T>`
@@ -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 8ce7a7edb46..cf6715e2d73 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 68cf139338a..fb23ad8e340 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<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,
 /// 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<P<ast::Expr>>,
                                        end_expr: &Option<P<ast::Expr>>)
-                                       // result type is type of method being called
-                                       -> Option<Ty<'tcx>>
+                                       -> 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 c26450310a9..fdbce101c1d 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -104,7 +104,7 @@ impl<R: Reader> BufferedReader<R> {
 impl<R: Reader> Buffer for BufferedReader<R> {
     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<W: Writer> Writer for BufferedWriter<W> {
         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 3a18b0dc1b5..5f68bbef932 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 4e736908c37..f2db2875ebf 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 01151059530..20b1162d859 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 b6f8bb25b65..e1f5efae79f 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 add986387da..4830b15a843 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 a36703172c3..5bf47dceb5a 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 18fabcbd1a2..43893ca0126 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -51,7 +51,7 @@ impl<R: Reader> Reader for LimitReader<R> {
         }
 
         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 68c99b12758..46c3a4f622a 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 26dadfd9fb1..6b007056a51 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 d4932fbb5f1..debcbcd2154 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -723,8 +723,7 @@ pub enum Expr_ {
     ExprField(P<Expr>, SpannedIdent),
     ExprTupField(P<Expr>, Spanned<uint>),
     ExprIndex(P<Expr>, P<Expr>),
-    ExprSlice(P<Expr>, Option<P<Expr>>, Option<P<Expr>>, Mutability),
-    ExprRange(P<Expr>, Option<P<Expr>>),
+    ExprRange(Option<P<Expr>>, Option<P<Expr>>),
 
     /// Variable reference, possibly containing `::` and/or
     /// type parameters, e.g. foo::bar::<baz>
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 28f7a78ddd0..4607520655e 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 c58901701f5..11a9fdee0b9 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -1384,14 +1384,8 @@ pub fn noop_fold_expr<T: Folder>(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 a2e2abab03e..2f43661eebe 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<Expr>,
                     start: Option<P<Expr>>,
                     end: Option<P<Expr>>,
-                    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<Expr>,
                     end: Option<P<Expr>>)
                     -> ast::Expr_ {
-        ExprRange(start, end)
+        ExprRange(Some(start), end)
     }
 
     pub fn mk_field(&mut self, expr: P<Expr>, ident: ast::SpannedIdent) -> ast::Expr_ {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 623f20bccd2..accffbc35ba 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 714339d0f0a..22cfea86251 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 3b0cc1443f0..398728bb516 100644
--- a/src/libunicode/u_str.rs
+++ b/src/libunicode/u_str.rs
@@ -521,7 +521,7 @@ impl<I> Iterator<u16> for Utf16Encoder<I> where I: Iterator<char> {
 
         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 723b2b722d7..ef38f5ef743 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 eb18cfdaed3..178d6777939 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 66965110f73..6ee2233f168 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 ca7401dc26c..4af748661fd 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 40690bd844b..74c304884a0 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 63f79c808ae..24f710d2ae3 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 6778ed88ff7..8970bcfd153 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 cbfa3ed85fd..ad6b384d747 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 027121dd422..864cee03f24 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() {