about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSimonas Kazlauskas <git@kazlauskas.me>2015-07-11 14:34:57 +0300
committerSimonas Kazlauskas <git@kazlauskas.me>2015-07-12 00:47:56 +0300
commit7a90865db5b9bbf4e94580a886e3ab187d91c83c (patch)
tree5067055c232e186de7204566d2b56eceda674227
parent072d07ce9fc85728a62664ce674e26c54a759da5 (diff)
downloadrust-7a90865db5b9bbf4e94580a886e3ab187d91c83c.tar.gz
rust-7a90865db5b9bbf4e94580a886e3ab187d91c83c.zip
Implement RFC 1058
-rw-r--r--src/compiletest/compiletest.rs6
-rw-r--r--src/libcollections/slice.rs39
-rw-r--r--src/libcollectionstest/lib.rs5
-rw-r--r--src/libcollectionstest/slice.rs57
-rw-r--r--src/libcore/slice.rs36
-rw-r--r--src/libgetopts/lib.rs2
-rw-r--r--src/librustc/lib.rs2
-rw-r--r--src/librustc/metadata/decoder.rs2
-rw-r--r--src/librustc/middle/check_match.rs4
-rw-r--r--src/librustc/middle/infer/error_reporting.rs2
-rw-r--r--src/librustc/middle/traits/select.rs2
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs4
-rw-r--r--src/librustc_resolve/lib.rs6
-rw-r--r--src/librustc_typeck/astconv.rs4
-rw-r--r--src/librustc_typeck/check/mod.rs2
-rw-r--r--src/librustc_typeck/check/wf.rs4
-rw-r--r--src/librustc_typeck/lib.rs2
-rw-r--r--src/librustdoc/lib.rs3
-rw-r--r--src/librustdoc/passes.rs2
-rw-r--r--src/libtest/lib.rs3
20 files changed, 110 insertions, 77 deletions
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
index 92a94d23f08..36c67639101 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/compiletest/compiletest.rs
@@ -15,7 +15,7 @@
 #![feature(libc)]
 #![feature(path_ext)]
 #![feature(rustc_private)]
-#![feature(slice_extras)]
+#![feature(slice_splits)]
 #![feature(str_char)]
 #![feature(test)]
 #![feature(vec_push_all)]
@@ -90,9 +90,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
           optopt("", "lldb-python-dir", "directory containing LLDB's python module", "PATH"),
           optflag("h", "help", "show this message"));
 
-    assert!(!args.is_empty());
-    let argv0 = args[0].clone();
-    let args_ = args.tail();
+    let (argv0, args_) = args.split_first().unwrap();
     if args[1] == "-h" || args[1] == "--help" {
         let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
         println!("{}", getopts::usage(&message, &groups));
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index d49463911e6..0933734ee38 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -282,34 +282,65 @@ impl<T> [T] {
 
     /// Returns all but the first element of a slice.
     #[unstable(feature = "slice_extras", reason = "likely to be renamed")]
+    #[deprecated(since = "1.3.0", reason = "superseded by split_first")]
     #[inline]
     pub fn tail(&self) -> &[T] {
         core_slice::SliceExt::tail(self)
     }
 
+    /// Returns the first and all the rest of the elements of a slice.
+    #[unstable(feature = "slice_splits", reason = "new API")]
+    #[inline]
+    pub fn split_first(&self) -> Option<(&T, &[T])> {
+        core_slice::SliceExt::split_first(self)
+    }
+
     /// Returns all but the first element of a mutable slice
-    #[unstable(feature = "slice_extras",
-               reason = "likely to be renamed or removed")]
+    #[unstable(feature = "slice_extras", reason = "likely to be renamed or removed")]
+    #[deprecated(since = "1.3.0", reason = "superseded by split_first_mut")]
     #[inline]
     pub fn tail_mut(&mut self) -> &mut [T] {
         core_slice::SliceExt::tail_mut(self)
     }
 
+    /// Returns the first and all the rest of the elements of a slice.
+    #[unstable(feature = "slice_splits", reason = "new API")]
+    #[inline]
+    pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
+        core_slice::SliceExt::split_first_mut(self)
+    }
+
     /// Returns all but the last element of a slice.
     #[unstable(feature = "slice_extras", reason = "likely to be renamed")]
+    #[deprecated(since = "1.3.0", reason = "superseded by split_last")]
     #[inline]
     pub fn init(&self) -> &[T] {
         core_slice::SliceExt::init(self)
     }
 
+    /// Returns the last and all the rest of the elements of a slice.
+    #[unstable(feature = "slice_splits", reason = "new API")]
+    #[inline]
+    pub fn split_last(&self) -> Option<(&T, &[T])> {
+        core_slice::SliceExt::split_last(self)
+
+    }
+
     /// Returns all but the last element of a mutable slice
-    #[unstable(feature = "slice_extras",
-               reason = "likely to be renamed or removed")]
+    #[unstable(feature = "slice_extras", reason = "likely to be renamed or removed")]
+    #[deprecated(since = "1.3.0", reason = "superseded by split_last_mut")]
     #[inline]
     pub fn init_mut(&mut self) -> &mut [T] {
         core_slice::SliceExt::init_mut(self)
     }
 
+    /// Returns the last and all the rest of the elements of a slice.
+    #[unstable(feature = "slice_splits", since = "1.3.0")]
+    #[inline]
+    pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
+        core_slice::SliceExt::split_last_mut(self)
+    }
+
     /// Returns the last element of a slice, or `None` if it is empty.
     ///
     /// # Examples
diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs
index ba1b4964b49..de6dcc9adcb 100644
--- a/src/libcollectionstest/lib.rs
+++ b/src/libcollectionstest/lib.rs
@@ -36,7 +36,7 @@
 #![feature(rustc_private)]
 #![feature(slice_bytes)]
 #![feature(slice_chars)]
-#![feature(slice_extras)]
+#![feature(slice_splits)]
 #![feature(slice_position_elem)]
 #![feature(split_off)]
 #![feature(step_by)]
@@ -51,9 +51,10 @@
 #![feature(vec_deque_retain)]
 #![feature(vec_from_raw_buf)]
 #![feature(vec_push_all)]
-#![feature(vec_split_off)]
 #![feature(vecmap)]
 
+#![allow(deprecated)]
+
 #[macro_use] extern crate log;
 
 extern crate collections;
diff --git a/src/libcollectionstest/slice.rs b/src/libcollectionstest/slice.rs
index d88d8b8e4a0..d39abc63336 100644
--- a/src/libcollectionstest/slice.rs
+++ b/src/libcollectionstest/slice.rs
@@ -119,71 +119,48 @@ fn test_first_mut() {
 }
 
 #[test]
-fn test_tail() {
+fn test_split_first() {
     let mut a = vec![11];
     let b: &[i32] = &[];
-    assert_eq!(a.tail(), b);
+    assert!(b.split_first().is_none());
+    assert_eq!(a.split_first(), Some((&11, b)));
     a = vec![11, 12];
     let b: &[i32] = &[12];
-    assert_eq!(a.tail(), b);
+    assert_eq!(a.split_first(), Some((&11, b)));
 }
 
 #[test]
-fn test_tail_mut() {
+fn test_split_first_mut() {
     let mut a = vec![11];
     let b: &mut [i32] = &mut [];
-    assert!(a.tail_mut() == b);
+    assert!(b.split_first_mut().is_none());
+    assert!(a.split_first_mut() == Some((&mut 11, b)));
     a = vec![11, 12];
     let b: &mut [_] = &mut [12];
-    assert!(a.tail_mut() == b);
+    assert!(a.split_first_mut() == Some((&mut 11, b)));
 }
 
 #[test]
-#[should_panic]
-fn test_tail_empty() {
-    let a = Vec::<i32>::new();
-    a.tail();
-}
-
-#[test]
-#[should_panic]
-fn test_tail_mut_empty() {
-    let mut a = Vec::<i32>::new();
-    a.tail_mut();
-}
-
-#[test]
-fn test_init() {
+fn test_split_last() {
     let mut a = vec![11];
     let b: &[i32] = &[];
-    assert_eq!(a.init(), b);
+    assert!(b.split_last().is_none());
+    assert_eq!(a.split_last(), Some((&11, b)));
     a = vec![11, 12];
     let b: &[_] = &[11];
-    assert_eq!(a.init(), b);
+    assert_eq!(a.split_last(), Some((&12, b)));
 }
 
 #[test]
-fn test_init_mut() {
+fn test_split_last_mut() {
     let mut a = vec![11];
     let b: &mut [i32] = &mut [];
-    assert!(a.init_mut() == b);
+    assert!(b.split_last_mut().is_none());
+    assert!(a.split_last_mut() == Some((&mut 11, b)));
+
     a = vec![11, 12];
     let b: &mut [_] = &mut [11];
-    assert!(a.init_mut() == b);
-}
-
-#[test]
-#[should_panic]
-fn test_init_empty() {
-    let a = Vec::<i32>::new();
-    a.init();
-}
-
-#[test]
-#[should_panic]
-fn test_init_mut_empty() {
-    let mut a = Vec::<i32>::new();
-    a.init_mut();
+    assert!(a.split_last_mut() == Some((&mut 12, b)));
 }
 
 #[test]
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 00e7ff3c4df..2c6acbf9157 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -83,6 +83,8 @@ pub trait SliceExt {
     fn first<'a>(&'a self) -> Option<&'a Self::Item>;
     fn tail<'a>(&'a self) -> &'a [Self::Item];
     fn init<'a>(&'a self) -> &'a [Self::Item];
+    fn split_first<'a>(&'a self) -> Option<(&'a Self::Item, &'a [Self::Item])>;
+    fn split_last<'a>(&'a self) -> Option<(&'a Self::Item, &'a [Self::Item])>;
     fn last<'a>(&'a self) -> Option<&'a Self::Item>;
     unsafe fn get_unchecked<'a>(&'a self, index: usize) -> &'a Self::Item;
     fn as_ptr(&self) -> *const Self::Item;
@@ -95,6 +97,8 @@ pub trait SliceExt {
     fn first_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>;
     fn tail_mut<'a>(&'a mut self) -> &'a mut [Self::Item];
     fn init_mut<'a>(&'a mut self) -> &'a mut [Self::Item];
+    fn split_first_mut<'a>(&'a mut self) -> Option<(&'a mut Self::Item, &'a mut [Self::Item])>;
+    fn split_last_mut<'a>(&'a mut self) -> Option<(&'a mut Self::Item, &'a mut [Self::Item])>;
     fn last_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>;
     fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, Self::Item, P>
                         where P: FnMut(&Self::Item) -> bool;
@@ -238,8 +242,17 @@ impl<T> SliceExt for [T] {
     fn tail(&self) -> &[T] { &self[1..] }
 
     #[inline]
-    fn init(&self) -> &[T] {
-        &self[..self.len() - 1]
+    fn split_first(&self) -> Option<(&T, &[T])> {
+        if self.is_empty() { None } else { Some((&self[0], &self[1..])) }
+    }
+
+    #[inline]
+    fn init(&self) -> &[T] { &self[..self.len() - 1] }
+
+    #[inline]
+    fn split_last(&self) -> Option<(&T, &[T])> {
+        let len = self.len();
+        if len == 0 { None } else { Some((&self[len - 1], &self[..(len - 1)])) }
     }
 
     #[inline]
@@ -328,8 +341,14 @@ impl<T> SliceExt for [T] {
     }
 
     #[inline]
-    fn tail_mut(&mut self) -> &mut [T] {
-        &mut self[1 ..]
+    fn tail_mut(&mut self) -> &mut [T] { &mut self[1 ..] }
+
+    #[inline]
+    fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
+        if self.is_empty() { None } else {
+            let split = self.split_at_mut(1);
+            Some((&mut split.0[0], split.1))
+        }
     }
 
     #[inline]
@@ -339,6 +358,15 @@ impl<T> SliceExt for [T] {
     }
 
     #[inline]
+    fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
+        let len = self.len();
+        if len == 0 { None } else {
+            let split = self.split_at_mut(len - 1);
+            Some((&mut split.1[0], split.0))
+        }
+    }
+
+    #[inline]
     fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, T, P> where P: FnMut(&T) -> bool {
         SplitMut { v: self, pred: pred, finished: false }
     }
diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs
index 0d15f584d64..8ee0b10e174 100644
--- a/src/libgetopts/lib.rs
+++ b/src/libgetopts/lib.rs
@@ -56,7 +56,7 @@
 //!         optopt("o", "", "set output file name", "NAME"),
 //!         optflag("h", "help", "print this help menu")
 //!     ];
-//!     let matches = match getopts(args.tail(), opts) {
+//!     let matches = match getopts(args[1..], opts) {
 //!         Ok(m) => { m }
 //!         Err(f) => { panic!(f.to_string()) }
 //!     };
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 732b77a626e..f1984708b66 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -53,7 +53,7 @@
 #![feature(rustc_private)]
 #![feature(scoped_tls)]
 #![feature(slice_bytes)]
-#![feature(slice_extras)]
+#![feature(slice_splits)]
 #![feature(slice_patterns)]
 #![feature(slice_position_elem)]
 #![feature(staged_api)]
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 5a79ef203b4..95fe2d87c94 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -688,7 +688,7 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeI
                                 -> csearch::FoundAst<'tcx> {
     debug!("Looking up item: {}", id);
     let item_doc = lookup_item(id, cdata.data());
-    let path = item_path(item_doc).init().to_vec();
+    let path = item_path(item_doc).split_last().unwrap().1.to_vec();
     match decode_inlined_item(cdata, tcx, path, item_doc) {
         Ok(ii) => csearch::FoundAst::Found(ii),
         Err(path) => {
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 444192b7913..b7955290f91 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -696,12 +696,12 @@ fn is_useful(cx: &MatchCheckCtxt,
             Some(constructor) => {
                 let matrix = rows.iter().filter_map(|r| {
                     if pat_is_binding_or_wild(&cx.tcx.def_map, raw_pat(r[0])) {
-                        Some(r.tail().to_vec())
+                        Some(r[1..].to_vec())
                     } else {
                         None
                     }
                 }).collect();
-                match is_useful(cx, &matrix, v.tail(), witness) {
+                match is_useful(cx, &matrix, &v[1..], witness) {
                     UsefulWithWitness(pats) => {
                         let arity = constructor_arity(cx, &constructor, left_ty);
                         let wild_pats = vec![DUMMY_WILD_PAT; arity];
diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs
index 8d226739e16..4a6cc019eb2 100644
--- a/src/librustc/middle/infer/error_reporting.rs
+++ b/src/librustc/middle/infer/error_reporting.rs
@@ -1495,7 +1495,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
             parameters: new_parameters
         };
         let mut new_segs = Vec::new();
-        new_segs.push_all(path.segments.init());
+        new_segs.push_all(path.segments.split_last().unwrap().1);
         new_segs.push(new_seg);
         ast::Path {
             span: path.span,
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index ad91f664af2..21f9e417acb 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -2571,7 +2571,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 for &i in &ty_params {
                     new_substs.types.get_mut_slice(TypeSpace)[i] = tcx.types.err;
                 }
-                for &ty in fields.init() {
+                for &ty in fields.split_last().unwrap().1 {
                     if ty.subst(tcx, &new_substs).references_error() {
                         return Err(Unimplemented);
                     }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 30d5a4f111b..dd26fd25215 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -276,7 +276,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 let module_path = match view_path.node {
                     ViewPathSimple(_, ref full_path) => {
                         full_path.segments
-                            .init()
+                            .split_last().unwrap().1
                             .iter().map(|ident| ident.identifier.name)
                             .collect()
                     }
@@ -347,7 +347,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                             continue;
                                         }
                                     };
-                                    let module_path = module_path.init();
+                                    let module_path = module_path.split_last().unwrap().1;
                                     (module_path.to_vec(), name)
                                 }
                             };
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 0ec3979ccfb..1093d2ef318 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -23,7 +23,7 @@
 #![feature(rc_weak)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
-#![feature(slice_extras)]
+#![feature(slice_splits)]
 #![feature(staged_api)]
 
 #[macro_use] extern crate log;
@@ -2881,7 +2881,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     segments: &[ast::PathSegment],
                                     namespace: Namespace)
                                     -> Option<(Def, LastPrivate)> {
-        let module_path = segments.init().iter()
+        let module_path = segments.split_last().unwrap().1.iter()
                                          .map(|ps| ps.identifier.name)
                                          .collect::<Vec<_>>();
 
@@ -2939,7 +2939,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                    segments: &[ast::PathSegment],
                                    namespace: Namespace)
                                        -> Option<(Def, LastPrivate)> {
-        let module_path = segments.init().iter()
+        let module_path = segments.split_last().unwrap().1.iter()
                                          .map(|ps| ps.identifier.name)
                                          .collect::<Vec<_>>();
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index ef3c858bed5..0f2506dc301 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1402,7 +1402,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                                                           base_segments.last().unwrap(),
                                                           &mut projection_bounds);
 
-            check_path_args(tcx, base_segments.init(), NO_TPS | NO_REGIONS);
+            check_path_args(tcx, base_segments.split_last().unwrap().1, NO_TPS | NO_REGIONS);
             trait_ref_to_object_type(this,
                                      rscope,
                                      span,
@@ -1411,7 +1411,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
                                      &[])
         }
         def::DefTy(did, _) | def::DefStruct(did) => {
-            check_path_args(tcx, base_segments.init(), NO_TPS | NO_REGIONS);
+            check_path_args(tcx, base_segments.split_last().unwrap().1, NO_TPS | NO_REGIONS);
             ast_path_to_ty(this,
                            rscope,
                            span,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 638cc868527..e6c79cfd30e 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3668,7 +3668,7 @@ pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
         Some((opt_self_ty, &path.segments, path_res.base_def))
     } else {
         let mut def = path_res.base_def;
-        let ty_segments = path.segments.init();
+        let ty_segments = path.segments.split_last().unwrap().1;
         let base_ty_end = path.segments.len() - path_res.depth;
         let ty = astconv::finish_resolving_def_to_ty(fcx, fcx, span,
                                                      PathParamMode::Optional,
diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
index 7cf7d73a566..6083a2735c5 100644
--- a/src/librustc_typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -170,8 +170,8 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
                 }
 
                 // For DST, all intermediate types must be sized.
-                if !variant.fields.is_empty() {
-                    for field in variant.fields.init() {
+                if let Some((_, fields)) = variant.fields.split_last() {
+                    for field in fields {
                         fcx.register_builtin_bound(
                             field.ty,
                             ty::BoundSized,
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 8c3ef4ae631..4260791e384 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -85,7 +85,7 @@ This API is completely unstable and subject to change.
 #![feature(ref_slice)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
-#![feature(slice_extras)]
+#![feature(slice_splits)]
 #![feature(staged_api)]
 #![feature(vec_push_all)]
 #![feature(cell_extras)]
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 17d912dd4cb..9ea22ced927 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -29,7 +29,6 @@
 #![feature(path_relative_from)]
 #![feature(rustc_private)]
 #![feature(set_stdio)]
-#![feature(slice_extras)]
 #![feature(slice_patterns)]
 #![feature(staged_api)]
 #![feature(subslice_offset)]
@@ -192,7 +191,7 @@ pub fn usage(argv0: &str) {
 }
 
 pub fn main_args(args: &[String]) -> isize {
-    let matches = match getopts::getopts(args.tail(), &opts()) {
+    let matches = match getopts::getopts(&args[1..], &opts()) {
         Ok(m) => m,
         Err(err) => {
             println!("{}", err);
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index 74c16127f41..72391ea51dd 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -353,7 +353,7 @@ pub fn unindent(s: &str) -> String {
 
     if !lines.is_empty() {
         let mut unindented = vec![ lines[0].trim().to_string() ];
-        unindented.push_all(&lines.tail().iter().map(|&line| {
+        unindented.push_all(&lines[1..].iter().map(|&line| {
             if line.chars().all(|c| c.is_whitespace()) {
                 line.to_string()
             } else {
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 724c0b2a892..382b7495af5 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -44,7 +44,6 @@
 #![feature(rt)]
 #![feature(rustc_private)]
 #![feature(set_stdio)]
-#![feature(slice_extras)]
 #![feature(staged_api)]
 
 extern crate getopts;
@@ -359,7 +358,7 @@ Test Attributes:
 
 // Parses command line arguments into test options
 pub fn parse_opts(args: &[String]) -> Option<OptRes> {
-    let args_ = args.tail();
+    let args_ = &args[1..];
     let matches =
         match getopts::getopts(args_, &optgroups()) {
           Ok(m) => m,