mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 22:12:15 +00:00
Implement RFC 1058
This commit is contained in:
parent
072d07ce9f
commit
7a90865db5
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
@ -338,6 +357,15 @@ impl<T> SliceExt for [T] {
|
||||
&mut self[.. (len - 1)]
|
||||
}
|
||||
|
||||
#[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 }
|
||||
|
@ -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()) }
|
||||
//! };
|
||||
|
@ -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)]
|
||||
|
@ -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) => {
|
||||
|
@ -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];
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
};
|
||||
|
@ -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<_>>();
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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)]
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user