diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 20aadd79d12e..98316066fd17 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -223,17 +223,10 @@ pub pure fn head_opt(v: &r/[T]) -> Option<&r/T> { } /// Returns a vector containing all but the first element of a slice -pub pure fn tail(v: &[const T]) -> ~[T] { - slice(v, 1u, len(v)).to_vec() -} +pub pure fn tail(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(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(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(v: &[const T]) -> ~[T] { @@ -1704,7 +1697,6 @@ pub trait CopyableVector { 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 CopyableVector 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 { 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(&self, z: U, p: fn(t: &T, u: U) -> U) -> U; pure fn map(&self, f: fn(t: &T) -> U) -> ~[U]; pure fn mapi(&self, f: fn(uint, t: &T) -> U) -> ~[U]; @@ -1757,6 +1747,14 @@ impl ImmutableVector 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(&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 51cb305ab028..7dd31374fc67 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 bbc19cf86eaa..1d7314f75187 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 5fafcf392bec..06595a23d961 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 {