Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace slice methods tail(), init() with pop_first(), pop_last() #24184

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/compiletest/compiletest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
optflag("h", "help", "show this message"));

assert!(!args.is_empty());
let argv0 = args[0].clone();
let args_ = args.tail();
let (argv0, args_) = args.pop_first().unwrap();
if args[1] == "-h" || args[1] == "--help" {
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
println!("{}", getopts::usage(&message, &groups));
Expand Down
78 changes: 50 additions & 28 deletions src/libcollections/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,20 +460,6 @@ impl<T> [T] {
core_slice::SliceExt::first(self)
}

/// Returns all but the first element of a slice.
#[unstable(feature = "collections", reason = "likely to be renamed")]
#[inline]
pub fn tail(&self) -> &[T] {
core_slice::SliceExt::tail(self)
}

/// Returns all but the last element of a slice.
#[unstable(feature = "collections", reason = "likely to be renamed")]
#[inline]
pub fn init(&self) -> &[T] {
core_slice::SliceExt::init(self)
}

/// Returns the last element of a slice, or `None` if it is empty.
///
/// # Examples
Expand All @@ -491,6 +477,42 @@ impl<T> [T] {
core_slice::SliceExt::last(self)
}

/// Removes the first element of the slice and returns it, along with the
/// remainder, or `None` if the slice is empty.
///
/// # Examples
///
/// ```
/// let v = [10, 40, 30];
/// assert!(v.pop_first() == Some((&10, &[40, 30])));
///
/// let w: &[i32] = &[];
/// assert!(w.pop_first() == None);
/// ```
#[unstable(feature = "collections", reason = "brand new")]
#[inline]
pub fn pop_first(&self) -> Option<(&T, &[T])> {
core_slice::SliceExt::pop_first(self)
}

/// Removes the last element of the slice and returns it, along with the
/// remainder, or `None` if the slice is empty.
///
/// # Examples
///
/// ```
/// let v = [10, 40, 30];
/// assert!(v.pop_last() == Some((&30, &[10, 40])));
///
/// let w: &[i32] = &[];
/// assert!(w.pop_last() == None);
/// ```
#[unstable(feature = "collections", reason = "brand new")]
#[inline]
pub fn pop_last(&self) -> Option<(&T, &[T])> {
core_slice::SliceExt::pop_last(self)
}

/// Returns a pointer to the element at the given index, without doing
/// bounds checking.
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -600,27 +622,27 @@ impl<T> [T] {
core_slice::SliceExt::first_mut(self)
}

/// Returns all but the first element of a mutable slice
#[unstable(feature = "collections",
reason = "likely to be renamed or removed")]
/// Returns a mutable pointer to the last item in the slice.
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn tail_mut(&mut self) -> &mut [T] {
core_slice::SliceExt::tail_mut(self)
pub fn last_mut(&mut self) -> Option<&mut T> {
core_slice::SliceExt::last_mut(self)
}

/// Returns all but the last element of a mutable slice
#[unstable(feature = "collections",
reason = "likely to be renamed or removed")]
/// Removes the first element from a mutable slice and returns it, along
/// with the remainder of the slice.
#[unstable(feature = "collections", reason = "brand new")]
#[inline]
pub fn init_mut(&mut self) -> &mut [T] {
core_slice::SliceExt::init_mut(self)
pub fn pop_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
core_slice::SliceExt::pop_first_mut(self)
}

/// Returns a mutable pointer to the last item in the slice.
#[stable(feature = "rust1", since = "1.0.0")]
/// Removes the last element from a mutable slice and returns it, along
/// with the remainder of the slice.
#[unstable(feature = "collections", reason = "brand new")]
#[inline]
pub fn last_mut(&mut self) -> Option<&mut T> {
core_slice::SliceExt::last_mut(self)
pub fn pop_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
core_slice::SliceExt::pop_last_mut(self)
}

/// Returns an iterator over mutable subslices separated by elements that
Expand Down
108 changes: 40 additions & 68 deletions src/libcollectionstest/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,74 +118,6 @@ fn test_first_mut() {
assert_eq!(*a.first_mut().unwrap(), 11);
}

#[test]
fn test_tail() {
let mut a = vec![11];
let b: &[i32] = &[];
assert_eq!(a.tail(), b);
a = vec![11, 12];
let b: &[i32] = &[12];
assert_eq!(a.tail(), b);
}

#[test]
fn test_tail_mut() {
let mut a = vec![11];
let b: &mut [i32] = &mut [];
assert!(a.tail_mut() == b);
a = vec![11, 12];
let b: &mut [_] = &mut [12];
assert!(a.tail_mut() == 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() {
let mut a = vec![11];
let b: &[i32] = &[];
assert_eq!(a.init(), b);
a = vec![11, 12];
let b: &[_] = &[11];
assert_eq!(a.init(), b);
}

#[test]
fn test_init_mut() {
let mut a = vec![11];
let b: &mut [i32] = &mut [];
assert!(a.init_mut() == 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();
}

#[test]
fn test_last() {
let mut a = vec![];
Expand All @@ -206,6 +138,46 @@ fn test_last_mut() {
assert_eq!(*a.last_mut().unwrap(), 12);
}

#[test]
fn test_pop_first() {
let a: &[i32] = &[];
assert_eq!(a.pop_first(), None);
let b: &[i32] = &[11];
assert_eq!(b.pop_first(), Some((&11, &[][..])));
let c: &[i32] = &[11, 12];
assert_eq!(c.pop_first(), Some((&11, &[12][..])));
}

#[test]
fn test_pop_first_mut() {
let a: &mut [i32] = &mut [];
assert_eq!(a.pop_first_mut(), None);
let b: &mut [i32] = &mut [11];
assert_eq!(b.pop_first_mut(), Some((&mut 11, &mut [][..])));
let c: &mut [i32] = &mut [11, 12];
assert_eq!(c.pop_first_mut(), Some((&mut 11, &mut [12][..])));
}

#[test]
fn test_pop_last() {
let a: &[i32] = &[];
assert_eq!(a.pop_last(), None);
let b: &[i32] = &[11];
assert_eq!(b.pop_last(), Some((&11, &[][..])));
let c: &[i32] = &[11, 12];
assert_eq!(c.pop_last(), Some((&12, &[11][..])));
}

#[test]
fn test_pop_last_mut() {
let a: &mut [i32] = &mut [];
assert_eq!(a.pop_last_mut(), None);
let b: &mut [i32] = &mut [11];
assert_eq!(b.pop_last_mut(), Some((&mut 11, &mut [][..])));
let c: &mut [i32] = &mut [11, 12];
assert_eq!(c.pop_last_mut(), Some((&mut 12, &mut [11][..])));
}

#[test]
fn test_slice() {
// Test fixed length vector.
Expand Down
43 changes: 29 additions & 14 deletions src/libcore/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ pub trait SliceExt {
fn chunks<'a>(&'a self, size: usize) -> Chunks<'a, Self::Item>;
fn get<'a>(&'a self, index: usize) -> Option<&'a Self::Item>;
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 last<'a>(&'a self) -> Option<&'a Self::Item>;
fn pop_first(&self) -> Option<(&Self::Item, &[Self::Item])>;
fn pop_last(&self) -> Option<(&Self::Item, &[Self::Item])>;
unsafe fn get_unchecked<'a>(&'a self, index: usize) -> &'a Self::Item;
fn as_ptr(&self) -> *const Self::Item;
fn binary_search_by<F>(&self, f: F) -> Result<usize, usize> where
Expand All @@ -90,9 +90,9 @@ pub trait SliceExt {
fn get_mut<'a>(&'a mut self, index: usize) -> Option<&'a mut Self::Item>;
fn iter_mut<'a>(&'a mut self) -> IterMut<'a, Self::Item>;
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 last_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>;
fn pop_first_mut(&mut self) -> Option<(&mut Self::Item, &mut [Self::Item])>;
fn pop_last_mut(&mut self) -> Option<(&mut Self::Item, &mut [Self::Item])>;
fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, Self::Item, P>
where P: FnMut(&Self::Item) -> bool;
fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<Self::Item, P>
Expand Down Expand Up @@ -207,16 +207,21 @@ impl<T> SliceExt for [T] {
}

#[inline]
fn tail(&self) -> &[T] { &self[1..] }
fn last(&self) -> Option<&T> {
if self.len() == 0 { None } else { Some(&self[self.len() - 1]) }
}

#[inline]
fn init(&self) -> &[T] {
&self[..self.len() - 1]
fn pop_first(&self) -> Option<(&T, &[T])> {
if self.len() == 0 { None } else { Some((&self[0], &self[1..])) }
}

#[inline]
fn last(&self) -> Option<&T> {
if self.len() == 0 { None } else { Some(&self[self.len() - 1]) }
fn pop_last(&self) -> Option<(&T, &[T])> {
match self.len() {
0 => None,
n => Some((&self[n-1], &self[..(n-1)]))
}
}

#[inline]
Expand Down Expand Up @@ -299,14 +304,24 @@ impl<T> SliceExt for [T] {
}

#[inline]
fn tail_mut(&mut self) -> &mut [T] {
&mut self[1 ..]
fn pop_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
if self.len() == 0 {
None
} else {
let (head, tail) = self.split_at_mut(1);
Some((&mut head[0], tail))
}
}

#[inline]
fn init_mut(&mut self) -> &mut [T] {
let len = self.len();
&mut self[.. (len - 1)]
fn pop_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
match self.len() {
0 => None,
n => {
let (init, last) = self.split_at_mut(n-1);
Some((&mut last[0], init))
}
}
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,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).pop_last().unwrap().1.to_vec();
match decode_inlined_item(cdata, tcx, path, item_doc) {
Ok(ii) => csearch::FoundAst::Found(ii),
Err(path) => {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,12 +693,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<_> = repeat(DUMMY_WILD_PAT).take(arity).collect();
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/infer/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1352,7 +1352,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
region_names,
} = rebuild_info;

let last_seg = path.segments.last().unwrap();
let (last_seg, init_seg) = path.segments.pop_last().unwrap();
let new_parameters = match last_seg.parameters {
ast::ParenthesizedParameters(..) => {
last_seg.parameters.clone()
Expand Down Expand Up @@ -1409,7 +1409,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(init_seg);
new_segs.push(new_seg);
ast::Path {
span: path.span,
Expand Down
7 changes: 3 additions & 4 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,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()
.pop_last().unwrap().1
.iter().map(|ident| ident.identifier.name)
.collect()
}
Expand Down Expand Up @@ -334,16 +334,15 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
PathListIdent { name, .. } =>
(module_path.clone(), name.name),
PathListMod { .. } => {
let name = match module_path.last() {
Some(name) => *name,
let (name, module_path) = match module_path.pop_last() {
Some((name, module_path)) => (*name, module_path),
None => {
self.resolve_error(source_item.span,
"`self` import can only appear in an import list \
with a non-empty prefix");
continue;
}
};
let module_path = module_path.init();
(module_path.to_vec(), name)
}
};
Expand Down
Loading