about summary refs log tree commit diff
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2013-03-03 07:22:40 -0800
committerErick Tryzelaar <erick.tryzelaar@gmail.com>2013-03-05 19:37:04 -0800
commit5ae06ae9dea2f1dac157193b702f640e2216a5a9 (patch)
treea45c10888cbe96393cf51db2439de0fcd8cceb5a
parent359bb3e10bb022aabc5bfc60e48d3dfffc2ee62c (diff)
core: convert vec::{tail,tailn} to return references
-rw-r--r--src/libcore/vec.rs57
-rw-r--r--src/librustc/middle/check_match.rs65
-rw-r--r--src/librustc/middle/trans/cabi.rs8
-rw-r--r--src/librustdoc/unindent_pass.rs2
4 files changed, 84 insertions, 48 deletions
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index 20aadd79d12..98316066fd1 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -223,17 +223,10 @@ pub pure fn head_opt<T>(v: &r/[T]) -> Option<&r/T> {
 }
 
 /// Returns a vector containing all but the first element of a slice
-pub pure fn tail<T:Copy>(v: &[const T]) -> ~[T] {
-    slice(v, 1u, len(v)).to_vec()
-}
+pub pure fn tail<T>(v: &r/[T]) -> &r/[T] { slice(v, 1, v.len()) }
 
-/**
- * Returns a vector containing all but the first `n` \
- * elements of a slice
- */
-pub pure fn tailn<T:Copy>(v: &[const T], n: uint) -> ~[T] {
-    slice(v, n, len(v)).to_vec()
-}
+/// Returns a vector containing all but the first `n` elements of a slice
+pub pure fn tailn<T>(v: &r/[T], n: uint) -> &r/[T] { slice(v, n, v.len()) }
 
 /// Returns a vector containing all but the last element of a slice
 pub pure fn init<T:Copy>(v: &[const T]) -> ~[T] {
@@ -1704,7 +1697,6 @@ pub trait CopyableVector<T> {
     pure fn init(&self) -> ~[T];
     pure fn last(&self) -> T;
     pure fn slice(&self, start: uint, end: uint) -> ~[T];
-    pure fn tail(&self) -> ~[T];
 }
 
 /// Extension methods for vectors
@@ -1722,16 +1714,14 @@ impl<T:Copy> CopyableVector<T> for &[const T] {
     pure fn slice(&self, start: uint, end: uint) -> ~[T] {
         slice(*self, start, end).to_vec()
     }
-
-    /// Returns all but the first element of a vector
-    #[inline]
-    pure fn tail(&self) -> ~[T] { tail(*self) }
 }
 
 pub trait ImmutableVector<T> {
     pure fn view(&self, start: uint, end: uint) -> &self/[T];
     pure fn head(&self) -> &self/T;
     pure fn head_opt(&self) -> Option<&self/T>;
+    pure fn tail(&self) -> &self/[T];
+    pure fn tailn(&self, n: uint) -> &self/[T];
     pure fn foldr<U: Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U;
     pure fn map<U>(&self, f: fn(t: &T) -> U) -> ~[U];
     pure fn mapi<U>(&self, f: fn(uint, t: &T) -> U) -> ~[U];
@@ -1757,6 +1747,14 @@ impl<T> ImmutableVector<T> for &[T] {
     #[inline]
     pure fn head_opt(&self) -> Option<&self/T> { head_opt(*self) }
 
+    /// Returns all but the first element of a vector
+    #[inline]
+    pure fn tail(&self) -> &self/[T] { tail(*self) }
+
+    /// Returns all but the first `n' elements of a vector
+    #[inline]
+    pure fn tailn(&self, n: uint) -> &self/[T] { tailn(*self, n) }
+
     /// Reduce a vector from right to left
     #[inline]
     pure fn foldr<U:Copy>(&self, z: U, p: fn(t: &T, u: U) -> U) -> U {
@@ -2611,10 +2609,33 @@ mod tests {
     #[test]
     fn test_tail() {
         let mut a = ~[11];
-        assert (tail(a) == ~[]);
-
+        assert a.tail() == &[];
         a = ~[11, 12];
-        assert (tail(a) == ~[12]);
+        assert a.tail() == &[12];
+    }
+
+    #[test]
+    #[should_fail]
+    #[ignore(cfg(windows))]
+    fn test_tail_empty() {
+        let a: ~[int] = ~[];
+        a.tail();
+    }
+
+    #[test]
+    fn test_tailn() {
+        let mut a = ~[11, 12, 13];
+        assert a.tailn(0) == &[11, 12, 13];
+        a = ~[11, 12, 13];
+        assert a.tailn(2) == &[13];
+    }
+
+    #[test]
+    #[should_fail]
+    #[ignore(cfg(windows))]
+    fn test_tailn_empty() {
+        let a: ~[int] = ~[];
+        a.tailn(2);
     }
 
     #[test]
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 51cb305ab02..7dd31374fc6 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -265,7 +265,7 @@ pub fn is_useful(cx: @MatchCheckCtxt, +m: matrix, +v: &[@pat]) -> useful {
           Some(ref ctor) => {
             match is_useful(cx,
                             vec::filter_map(m, |r| default(cx, r)),
-                            vec::tail(v)) {
+                            v.tail()) {
               useful_ => useful(left_ty, (/*bad*/copy *ctor)),
               ref u => (/*bad*/copy *u)
             }
@@ -281,7 +281,7 @@ pub fn is_useful(cx: @MatchCheckCtxt, +m: matrix, +v: &[@pat]) -> useful {
 
 pub fn is_useful_specialized(cx: @MatchCheckCtxt,
                              m: matrix,
-                             +v: &[@pat],
+                             v: &[@pat],
                              +ctor: ctor,
                              arity: uint,
                              lty: ty::t)
@@ -475,7 +475,7 @@ pub fn wild() -> @pat {
 }
 
 pub fn specialize(cx: @MatchCheckCtxt,
-                  +r: &[@pat],
+                  r: &[@pat],
                   ctor_id: ctor,
                   arity: uint,
                   left_ty: ty::t)
@@ -485,13 +485,17 @@ pub fn specialize(cx: @MatchCheckCtxt,
     match r0 {
         pat{id: pat_id, node: n, span: pat_span} =>
             match n {
-            pat_wild => Some(vec::append(vec::from_elem(arity, wild()),
-                                         vec::tail(r))),
+            pat_wild => {
+                Some(vec::append(vec::from_elem(arity, wild()), r.tail()))
+            }
             pat_ident(_, _, _) => {
                 match cx.tcx.def_map.find(&pat_id) {
                     Some(def_variant(_, id)) => {
-                        if variant(id) == ctor_id { Some(vec::tail(r)) }
-                        else { None }
+                        if variant(id) == ctor_id {
+                            Some(vec::from_slice(r.tail()))
+                        } else {
+                            None
+                        }
                     }
                     Some(def_const(did)) => {
                         let const_expr =
@@ -506,10 +510,20 @@ pub fn specialize(cx: @MatchCheckCtxt,
                             single => true,
                             _ => fail!(~"type error")
                         };
-                        if match_ { Some(vec::tail(r)) } else { None }
+                        if match_ {
+                            Some(vec::from_slice(r.tail()))
+                        } else {
+                            None
+                        }
+                    }
+                    _ => {
+                        Some(
+                            vec::append(
+                                vec::from_elem(arity, wild()),
+                                r.tail()
+                            )
+                        )
                     }
-                    _ => Some(vec::append(vec::from_elem(arity, wild()),
-                                          vec::tail(r)))
                 }
             }
             pat_enum(_, args) => {
@@ -519,7 +533,7 @@ pub fn specialize(cx: @MatchCheckCtxt,
                             Some(args) => args,
                             None => vec::from_elem(arity, wild())
                         };
-                        Some(vec::append(args, vec::tail(r)))
+                        Some(vec::append(args, vec::from_slice(r.tail())))
                     }
                     def_variant(_, _) => None,
                     def_struct(*) => {
@@ -529,7 +543,7 @@ pub fn specialize(cx: @MatchCheckCtxt,
                             Some(args) => new_args = args,
                             None => new_args = vec::from_elem(arity, wild())
                         }
-                        Some(vec::append(new_args, vec::tail(r)))
+                        Some(vec::append(new_args, vec::from_slice(r.tail())))
                     }
                     _ => None
                 }
@@ -545,7 +559,7 @@ pub fn specialize(cx: @MatchCheckCtxt,
                         _ => wild()
                     }
                 });
-                Some(vec::append(args, vec::tail(r)))
+                Some(vec::append(args, vec::from_slice(r.tail())))
             }
             pat_struct(_, ref flds, _) => {
                 // Is this a struct or an enum variant?
@@ -560,7 +574,7 @@ pub fn specialize(cx: @MatchCheckCtxt,
                                     _ => wild()
                                 }
                             });
-                            Some(vec::append(args, vec::tail(r)))
+                            Some(vec::append(args, vec::from_slice(r.tail())))
                         } else {
                             None
                         }
@@ -587,13 +601,14 @@ pub fn specialize(cx: @MatchCheckCtxt,
                                 _ => wild()
                             }
                         });
-                        Some(vec::append(args, vec::tail(r)))
+                        Some(vec::append(args, vec::from_slice(r.tail())))
                     }
                 }
             }
-            pat_tup(args) => Some(vec::append(args, vec::tail(r))),
-            pat_box(a) | pat_uniq(a) | pat_region(a) =>
-                Some(vec::append(~[a], vec::tail(r))),
+            pat_tup(args) => Some(vec::append(args, r.tail())),
+            pat_box(a) | pat_uniq(a) | pat_region(a) => {
+                Some(vec::append(~[a], r.tail()))
+            }
             pat_lit(expr) => {
                 let e_v = eval_const_expr(cx.tcx, expr);
                 let match_ = match ctor_id {
@@ -605,21 +620,21 @@ pub fn specialize(cx: @MatchCheckCtxt,
                     single => true,
                     _ => fail!(~"type error")
                 };
-                if match_ { Some(vec::tail(r)) } else { None }
+                if match_ { Some(vec::from_slice(r.tail())) } else { None }
             }
             pat_range(lo, hi) => {
                 let (c_lo, c_hi) = match ctor_id {
                     val(ref v) => ((/*bad*/copy *v), (/*bad*/copy *v)),
                     range(ref lo, ref hi) =>
                         ((/*bad*/copy *lo), (/*bad*/copy *hi)),
-                    single => return Some(vec::tail(r)),
+                    single => return Some(vec::from_slice(r.tail())),
                     _ => fail!(~"type error")
                 };
                 let v_lo = eval_const_expr(cx.tcx, lo),
                 v_hi = eval_const_expr(cx.tcx, hi);
                 let match_ = compare_const_vals(c_lo, v_lo) >= 0 &&
                     compare_const_vals(c_hi, v_hi) <= 0;
-          if match_ { Some(vec::tail(r)) } else { None }
+          if match_ { Some(vec::from_slice(r.tail())) } else { None }
       }
             pat_vec(elems, tail) => {
                 match ctor_id {
@@ -630,10 +645,10 @@ pub fn specialize(cx: @MatchCheckCtxt,
                                 vec::append(elems, vec::from_elem(
                                     arity - num_elements, wild()
                                 )),
-                                vec::tail(r)
+                                vec::from_slice(r.tail())
                             ))
                         } else if num_elements == arity {
-                            Some(vec::append(elems, vec::tail(r)))
+                            Some(vec::append(elems, r.tail()))
                         } else {
                             None
                         }
@@ -645,8 +660,8 @@ pub fn specialize(cx: @MatchCheckCtxt,
     }
 }
 
-pub fn default(cx: @MatchCheckCtxt, r: ~[@pat]) -> Option<~[@pat]> {
-    if is_wild(cx, r[0]) { Some(vec::tail(r)) }
+pub fn default(cx: @MatchCheckCtxt, r: &[@pat]) -> Option<~[@pat]> {
+    if is_wild(cx, r[0]) { Some(vec::from_slice(r.tail())) }
     else { None }
 }
 
diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs
index bbc19cf86ea..1d7314f7518 100644
--- a/src/librustc/middle/trans/cabi.rs
+++ b/src/librustc/middle/trans/cabi.rs
@@ -71,8 +71,8 @@ pub impl FnType {
             let llretptr = GEPi(bcx, llargbundle, [0u, n]);
             let llretloc = Load(bcx, llretptr);
                 llargvals = ~[llretloc];
-                atys = vec::tail(atys);
-                attrs = vec::tail(attrs);
+                atys = vec::from_slice(atys.tail());
+                attrs = vec::from_slice(attrs.tail());
         }
 
         while i < n {
@@ -131,8 +131,8 @@ pub impl FnType {
         let mut attrs = /*bad*/copy self.attrs;
         let mut j = 0u;
         let llretptr = if self.sret {
-            atys = vec::tail(atys);
-            attrs = vec::tail(attrs);
+            atys = vec::from_slice(atys.tail());
+            attrs = vec::from_slice(attrs.tail());
             j = 1u;
             get_param(llwrapfn, 0u)
         } else if self.ret_ty.cast {
diff --git a/src/librustdoc/unindent_pass.rs b/src/librustdoc/unindent_pass.rs
index 5fafcf392be..06595a23d96 100644
--- a/src/librustdoc/unindent_pass.rs
+++ b/src/librustdoc/unindent_pass.rs
@@ -79,7 +79,7 @@ fn unindent(s: &str) -> ~str {
 
     if !lines.is_empty() {
         let unindented = ~[lines.head().trim()]
-            + do vec::tail(lines).map |line| {
+            + do lines.tail().map |line| {
             if str::is_whitespace(*line) {
                 copy *line
             } else {