diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 98316066fd17..2884d4486107 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -229,9 +229,11 @@ pub pure fn tail(v: &r/[T]) -> &r/[T] { slice(v, 1, v.len()) } 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] { - assert len(v) != 0u; - slice(v, 0u, len(v) - 1u).to_vec() +pub pure fn init(v: &r/[T]) -> &r/[T] { slice(v, 0, v.len() - 1) } + +/// Returns a vector containing all but the last `n' elements of a slice +pub pure fn initn(v: &r/[T], n: uint) -> &r/[T] { + slice(v, 0, v.len() - n) } /// Returns the last element of the slice `v`, failing if the slice is empty. @@ -1694,17 +1696,12 @@ impl Container for &[const T] { } pub trait CopyableVector { - pure fn init(&self) -> ~[T]; pure fn last(&self) -> T; pure fn slice(&self, start: uint, end: uint) -> ~[T]; } /// Extension methods for vectors -impl CopyableVector for &[const T] { - /// Returns all but the last elemnt of a vector - #[inline] - pure fn init(&self) -> ~[T] { init(*self) } - +impl CopyableVector for &[const T] { /// Returns the last element of a `v`, failing if the vector is empty. #[inline] pure fn last(&self) -> T { last(*self) } @@ -1722,6 +1719,8 @@ pub trait ImmutableVector { pure fn head_opt(&self) -> Option<&self/T>; pure fn tail(&self) -> &self/[T]; pure fn tailn(&self, n: uint) -> &self/[T]; + pure fn init(&self) -> &self/[T]; + pure fn initn(&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]; @@ -1755,6 +1754,14 @@ impl ImmutableVector for &[T] { #[inline] pure fn tailn(&self, n: uint) -> &self/[T] { tailn(*self, n) } + /// Returns all but the last elemnt of a vector + #[inline] + pure fn init(&self) -> &self/[T] { init(*self) } + + /// Returns all but the last `n' elemnts of a vector + #[inline] + pure fn initn(&self, n: uint) -> &self/[T] { initn(*self, n) } + /// Reduce a vector from right to left #[inline] pure fn foldr(&self, z: U, p: fn(t: &T, u: U) -> U) -> U { @@ -2638,6 +2645,38 @@ mod tests { a.tailn(2); } + #[test] + fn test_init() { + let mut a = ~[11]; + assert a.init() == &[]; + a = ~[11, 12]; + assert a.init() == &[11]; + } + + #[init] + #[should_fail] + #[ignore(cfg(windows))] + fn test_init_empty() { + let a: ~[int] = ~[]; + a.init(); + } + + #[test] + fn test_initn() { + let mut a = ~[11, 12, 13]; + assert a.initn(0) == &[11, 12, 13]; + a = ~[11, 12, 13]; + assert a.initn(2) == &[11]; + } + + #[init] + #[should_fail] + #[ignore(cfg(windows))] + fn test_initn_empty() { + let a: ~[int] = ~[]; + a.initn(2); + } + #[test] fn test_last() { let mut n = last_opt(~[]); @@ -3317,12 +3356,6 @@ mod tests { assert (v2[1] == 10); } - #[test] - fn test_init() { - let v = init(~[1, 2, 3]); - assert v == ~[1, 2]; - } - #[test] fn test_split() { fn f(x: &int) -> bool { *x == 3 } @@ -3387,13 +3420,6 @@ mod tests { (~[], ~[1, 2, 3]); } - #[test] - #[should_fail] - #[ignore(cfg(windows))] - fn test_init_empty() { - init::(~[]); - } - #[test] fn test_concat() { assert concat(~[~[1], ~[2,3]]) == ~[1, 2, 3]; diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index aa18c1eb450b..0bf1fc387044 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -558,7 +558,10 @@ pub fn maybe_get_item_ast(intr: @ident_interner, cdata: cmd, tcx: ty::ctxt, -> csearch::found_ast { debug!("Looking up item: %d", id); let item_doc = lookup_item(id, cdata.data); - let path = vec::init(item_path(intr, item_doc)); + let path = { + let item_path = item_path(intr, item_doc); + vec::from_slice(item_path.init()) + }; match decode_inlined_item(cdata, tcx, path, item_doc) { Some(ref ii) => csearch::found((/*bad*/copy *ii)), None => { @@ -566,8 +569,7 @@ pub fn maybe_get_item_ast(intr: @ident_interner, cdata: cmd, tcx: ty::ctxt, Some(did) => { let did = translate_def_id(cdata, did); let parent_item = lookup_item(did.node, cdata.data); - match decode_inlined_item(cdata, tcx, path, - parent_item) { + match decode_inlined_item(cdata, tcx, path, parent_item) { Some(ref ii) => csearch::found_parent(did, (/*bad*/copy *ii)), None => csearch::not_found } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 644b2c514544..12a2011ad256 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3815,7 +3815,7 @@ pub fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path { } ast_map::node_variant(ref variant, _, path) => { - vec::append_one(vec::init(*path), + vec::append_one(vec::from_slice(vec::init(*path)), ast_map::path_name((*variant).node.name)) }