Skip to content

Commit 50d305e

Browse files
committed
Auto merge of #26966 - nagisa:tail-init, r=alexcrichton
Fixes #26906
2 parents 2999003 + 7a90865 commit 50d305e

File tree

20 files changed

+110
-77
lines changed

20 files changed

+110
-77
lines changed

src/compiletest/compiletest.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#![feature(libc)]
1616
#![feature(path_ext)]
1717
#![feature(rustc_private)]
18-
#![feature(slice_extras)]
18+
#![feature(slice_splits)]
1919
#![feature(str_char)]
2020
#![feature(test)]
2121
#![feature(vec_push_all)]
@@ -90,9 +90,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
9090
optopt("", "lldb-python-dir", "directory containing LLDB's python module", "PATH"),
9191
optflag("h", "help", "show this message"));
9292

93-
assert!(!args.is_empty());
94-
let argv0 = args[0].clone();
95-
let args_ = args.tail();
93+
let (argv0, args_) = args.split_first().unwrap();
9694
if args[1] == "-h" || args[1] == "--help" {
9795
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
9896
println!("{}", getopts::usage(&message, &groups));

src/libcollections/slice.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,34 +282,65 @@ impl<T> [T] {
282282

283283
/// Returns all but the first element of a slice.
284284
#[unstable(feature = "slice_extras", reason = "likely to be renamed")]
285+
#[deprecated(since = "1.3.0", reason = "superseded by split_first")]
285286
#[inline]
286287
pub fn tail(&self) -> &[T] {
287288
core_slice::SliceExt::tail(self)
288289
}
289290

291+
/// Returns the first and all the rest of the elements of a slice.
292+
#[unstable(feature = "slice_splits", reason = "new API")]
293+
#[inline]
294+
pub fn split_first(&self) -> Option<(&T, &[T])> {
295+
core_slice::SliceExt::split_first(self)
296+
}
297+
290298
/// Returns all but the first element of a mutable slice
291-
#[unstable(feature = "slice_extras",
292-
reason = "likely to be renamed or removed")]
299+
#[unstable(feature = "slice_extras", reason = "likely to be renamed or removed")]
300+
#[deprecated(since = "1.3.0", reason = "superseded by split_first_mut")]
293301
#[inline]
294302
pub fn tail_mut(&mut self) -> &mut [T] {
295303
core_slice::SliceExt::tail_mut(self)
296304
}
297305

306+
/// Returns the first and all the rest of the elements of a slice.
307+
#[unstable(feature = "slice_splits", reason = "new API")]
308+
#[inline]
309+
pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
310+
core_slice::SliceExt::split_first_mut(self)
311+
}
312+
298313
/// Returns all but the last element of a slice.
299314
#[unstable(feature = "slice_extras", reason = "likely to be renamed")]
315+
#[deprecated(since = "1.3.0", reason = "superseded by split_last")]
300316
#[inline]
301317
pub fn init(&self) -> &[T] {
302318
core_slice::SliceExt::init(self)
303319
}
304320

321+
/// Returns the last and all the rest of the elements of a slice.
322+
#[unstable(feature = "slice_splits", reason = "new API")]
323+
#[inline]
324+
pub fn split_last(&self) -> Option<(&T, &[T])> {
325+
core_slice::SliceExt::split_last(self)
326+
327+
}
328+
305329
/// Returns all but the last element of a mutable slice
306-
#[unstable(feature = "slice_extras",
307-
reason = "likely to be renamed or removed")]
330+
#[unstable(feature = "slice_extras", reason = "likely to be renamed or removed")]
331+
#[deprecated(since = "1.3.0", reason = "superseded by split_last_mut")]
308332
#[inline]
309333
pub fn init_mut(&mut self) -> &mut [T] {
310334
core_slice::SliceExt::init_mut(self)
311335
}
312336

337+
/// Returns the last and all the rest of the elements of a slice.
338+
#[unstable(feature = "slice_splits", since = "1.3.0")]
339+
#[inline]
340+
pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
341+
core_slice::SliceExt::split_last_mut(self)
342+
}
343+
313344
/// Returns the last element of a slice, or `None` if it is empty.
314345
///
315346
/// # Examples

src/libcollectionstest/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
#![feature(rustc_private)]
3737
#![feature(slice_bytes)]
3838
#![feature(slice_chars)]
39-
#![feature(slice_extras)]
39+
#![feature(slice_splits)]
4040
#![feature(slice_position_elem)]
4141
#![feature(split_off)]
4242
#![feature(step_by)]
@@ -52,9 +52,10 @@
5252
#![feature(vec_deque_retain)]
5353
#![feature(vec_from_raw_buf)]
5454
#![feature(vec_push_all)]
55-
#![feature(vec_split_off)]
5655
#![feature(vecmap)]
5756

57+
#![allow(deprecated)]
58+
5859
#[macro_use] extern crate log;
5960

6061
extern crate collections;

src/libcollectionstest/slice.rs

Lines changed: 17 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -119,71 +119,48 @@ fn test_first_mut() {
119119
}
120120

121121
#[test]
122-
fn test_tail() {
122+
fn test_split_first() {
123123
let mut a = vec![11];
124124
let b: &[i32] = &[];
125-
assert_eq!(a.tail(), b);
125+
assert!(b.split_first().is_none());
126+
assert_eq!(a.split_first(), Some((&11, b)));
126127
a = vec![11, 12];
127128
let b: &[i32] = &[12];
128-
assert_eq!(a.tail(), b);
129+
assert_eq!(a.split_first(), Some((&11, b)));
129130
}
130131

131132
#[test]
132-
fn test_tail_mut() {
133+
fn test_split_first_mut() {
133134
let mut a = vec![11];
134135
let b: &mut [i32] = &mut [];
135-
assert!(a.tail_mut() == b);
136+
assert!(b.split_first_mut().is_none());
137+
assert!(a.split_first_mut() == Some((&mut 11, b)));
136138
a = vec![11, 12];
137139
let b: &mut [_] = &mut [12];
138-
assert!(a.tail_mut() == b);
140+
assert!(a.split_first_mut() == Some((&mut 11, b)));
139141
}
140142

141143
#[test]
142-
#[should_panic]
143-
fn test_tail_empty() {
144-
let a = Vec::<i32>::new();
145-
a.tail();
146-
}
147-
148-
#[test]
149-
#[should_panic]
150-
fn test_tail_mut_empty() {
151-
let mut a = Vec::<i32>::new();
152-
a.tail_mut();
153-
}
154-
155-
#[test]
156-
fn test_init() {
144+
fn test_split_last() {
157145
let mut a = vec![11];
158146
let b: &[i32] = &[];
159-
assert_eq!(a.init(), b);
147+
assert!(b.split_last().is_none());
148+
assert_eq!(a.split_last(), Some((&11, b)));
160149
a = vec![11, 12];
161150
let b: &[_] = &[11];
162-
assert_eq!(a.init(), b);
151+
assert_eq!(a.split_last(), Some((&12, b)));
163152
}
164153

165154
#[test]
166-
fn test_init_mut() {
155+
fn test_split_last_mut() {
167156
let mut a = vec![11];
168157
let b: &mut [i32] = &mut [];
169-
assert!(a.init_mut() == b);
158+
assert!(b.split_last_mut().is_none());
159+
assert!(a.split_last_mut() == Some((&mut 11, b)));
160+
170161
a = vec![11, 12];
171162
let b: &mut [_] = &mut [11];
172-
assert!(a.init_mut() == b);
173-
}
174-
175-
#[test]
176-
#[should_panic]
177-
fn test_init_empty() {
178-
let a = Vec::<i32>::new();
179-
a.init();
180-
}
181-
182-
#[test]
183-
#[should_panic]
184-
fn test_init_mut_empty() {
185-
let mut a = Vec::<i32>::new();
186-
a.init_mut();
163+
assert!(a.split_last_mut() == Some((&mut 12, b)));
187164
}
188165

189166
#[test]

src/libcore/slice.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ pub trait SliceExt {
8383
fn first<'a>(&'a self) -> Option<&'a Self::Item>;
8484
fn tail<'a>(&'a self) -> &'a [Self::Item];
8585
fn init<'a>(&'a self) -> &'a [Self::Item];
86+
fn split_first<'a>(&'a self) -> Option<(&'a Self::Item, &'a [Self::Item])>;
87+
fn split_last<'a>(&'a self) -> Option<(&'a Self::Item, &'a [Self::Item])>;
8688
fn last<'a>(&'a self) -> Option<&'a Self::Item>;
8789
unsafe fn get_unchecked<'a>(&'a self, index: usize) -> &'a Self::Item;
8890
fn as_ptr(&self) -> *const Self::Item;
@@ -95,6 +97,8 @@ pub trait SliceExt {
9597
fn first_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>;
9698
fn tail_mut<'a>(&'a mut self) -> &'a mut [Self::Item];
9799
fn init_mut<'a>(&'a mut self) -> &'a mut [Self::Item];
100+
fn split_first_mut<'a>(&'a mut self) -> Option<(&'a mut Self::Item, &'a mut [Self::Item])>;
101+
fn split_last_mut<'a>(&'a mut self) -> Option<(&'a mut Self::Item, &'a mut [Self::Item])>;
98102
fn last_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>;
99103
fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, Self::Item, P>
100104
where P: FnMut(&Self::Item) -> bool;
@@ -238,8 +242,17 @@ impl<T> SliceExt for [T] {
238242
fn tail(&self) -> &[T] { &self[1..] }
239243

240244
#[inline]
241-
fn init(&self) -> &[T] {
242-
&self[..self.len() - 1]
245+
fn split_first(&self) -> Option<(&T, &[T])> {
246+
if self.is_empty() { None } else { Some((&self[0], &self[1..])) }
247+
}
248+
249+
#[inline]
250+
fn init(&self) -> &[T] { &self[..self.len() - 1] }
251+
252+
#[inline]
253+
fn split_last(&self) -> Option<(&T, &[T])> {
254+
let len = self.len();
255+
if len == 0 { None } else { Some((&self[len - 1], &self[..(len - 1)])) }
243256
}
244257

245258
#[inline]
@@ -328,8 +341,14 @@ impl<T> SliceExt for [T] {
328341
}
329342

330343
#[inline]
331-
fn tail_mut(&mut self) -> &mut [T] {
332-
&mut self[1 ..]
344+
fn tail_mut(&mut self) -> &mut [T] { &mut self[1 ..] }
345+
346+
#[inline]
347+
fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
348+
if self.is_empty() { None } else {
349+
let split = self.split_at_mut(1);
350+
Some((&mut split.0[0], split.1))
351+
}
333352
}
334353

335354
#[inline]
@@ -338,6 +357,15 @@ impl<T> SliceExt for [T] {
338357
&mut self[.. (len - 1)]
339358
}
340359

360+
#[inline]
361+
fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
362+
let len = self.len();
363+
if len == 0 { None } else {
364+
let split = self.split_at_mut(len - 1);
365+
Some((&mut split.1[0], split.0))
366+
}
367+
}
368+
341369
#[inline]
342370
fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, T, P> where P: FnMut(&T) -> bool {
343371
SplitMut { v: self, pred: pred, finished: false }

src/libgetopts/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
//! optopt("o", "", "set output file name", "NAME"),
5757
//! optflag("h", "help", "print this help menu")
5858
//! ];
59-
//! let matches = match getopts(args.tail(), opts) {
59+
//! let matches = match getopts(args[1..], opts) {
6060
//! Ok(m) => { m }
6161
//! Err(f) => { panic!(f.to_string()) }
6262
//! };

src/librustc/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
#![feature(rustc_private)]
5454
#![feature(scoped_tls)]
5555
#![feature(slice_bytes)]
56-
#![feature(slice_extras)]
56+
#![feature(slice_splits)]
5757
#![feature(slice_patterns)]
5858
#![feature(slice_position_elem)]
5959
#![feature(staged_api)]

src/librustc/metadata/decoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeI
688688
-> csearch::FoundAst<'tcx> {
689689
debug!("Looking up item: {}", id);
690690
let item_doc = lookup_item(id, cdata.data());
691-
let path = item_path(item_doc).init().to_vec();
691+
let path = item_path(item_doc).split_last().unwrap().1.to_vec();
692692
match decode_inlined_item(cdata, tcx, path, item_doc) {
693693
Ok(ii) => csearch::FoundAst::Found(ii),
694694
Err(path) => {

src/librustc/middle/check_match.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -696,12 +696,12 @@ fn is_useful(cx: &MatchCheckCtxt,
696696
Some(constructor) => {
697697
let matrix = rows.iter().filter_map(|r| {
698698
if pat_is_binding_or_wild(&cx.tcx.def_map, raw_pat(r[0])) {
699-
Some(r.tail().to_vec())
699+
Some(r[1..].to_vec())
700700
} else {
701701
None
702702
}
703703
}).collect();
704-
match is_useful(cx, &matrix, v.tail(), witness) {
704+
match is_useful(cx, &matrix, &v[1..], witness) {
705705
UsefulWithWitness(pats) => {
706706
let arity = constructor_arity(cx, &constructor, left_ty);
707707
let wild_pats = vec![DUMMY_WILD_PAT; arity];

src/librustc/middle/infer/error_reporting.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1495,7 +1495,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
14951495
parameters: new_parameters
14961496
};
14971497
let mut new_segs = Vec::new();
1498-
new_segs.push_all(path.segments.init());
1498+
new_segs.push_all(path.segments.split_last().unwrap().1);
14991499
new_segs.push(new_seg);
15001500
ast::Path {
15011501
span: path.span,

src/librustc/middle/traits/select.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2571,7 +2571,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
25712571
for &i in &ty_params {
25722572
new_substs.types.get_mut_slice(TypeSpace)[i] = tcx.types.err;
25732573
}
2574-
for &ty in fields.init() {
2574+
for &ty in fields.split_last().unwrap().1 {
25752575
if ty.subst(tcx, &new_substs).references_error() {
25762576
return Err(Unimplemented);
25772577
}

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
276276
let module_path = match view_path.node {
277277
ViewPathSimple(_, ref full_path) => {
278278
full_path.segments
279-
.init()
279+
.split_last().unwrap().1
280280
.iter().map(|ident| ident.identifier.name)
281281
.collect()
282282
}
@@ -347,7 +347,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
347347
continue;
348348
}
349349
};
350-
let module_path = module_path.init();
350+
let module_path = module_path.split_last().unwrap().1;
351351
(module_path.to_vec(), name)
352352
}
353353
};

src/librustc_resolve/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#![feature(rc_weak)]
2424
#![feature(rustc_diagnostic_macros)]
2525
#![feature(rustc_private)]
26-
#![feature(slice_extras)]
26+
#![feature(slice_splits)]
2727
#![feature(staged_api)]
2828

2929
#[macro_use] extern crate log;
@@ -2881,7 +2881,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
28812881
segments: &[ast::PathSegment],
28822882
namespace: Namespace)
28832883
-> Option<(Def, LastPrivate)> {
2884-
let module_path = segments.init().iter()
2884+
let module_path = segments.split_last().unwrap().1.iter()
28852885
.map(|ps| ps.identifier.name)
28862886
.collect::<Vec<_>>();
28872887

@@ -2939,7 +2939,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
29392939
segments: &[ast::PathSegment],
29402940
namespace: Namespace)
29412941
-> Option<(Def, LastPrivate)> {
2942-
let module_path = segments.init().iter()
2942+
let module_path = segments.split_last().unwrap().1.iter()
29432943
.map(|ps| ps.identifier.name)
29442944
.collect::<Vec<_>>();
29452945

src/librustc_typeck/astconv.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,7 +1402,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
14021402
base_segments.last().unwrap(),
14031403
&mut projection_bounds);
14041404

1405-
check_path_args(tcx, base_segments.init(), NO_TPS | NO_REGIONS);
1405+
check_path_args(tcx, base_segments.split_last().unwrap().1, NO_TPS | NO_REGIONS);
14061406
trait_ref_to_object_type(this,
14071407
rscope,
14081408
span,
@@ -1411,7 +1411,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
14111411
&[])
14121412
}
14131413
def::DefTy(did, _) | def::DefStruct(did) => {
1414-
check_path_args(tcx, base_segments.init(), NO_TPS | NO_REGIONS);
1414+
check_path_args(tcx, base_segments.split_last().unwrap().1, NO_TPS | NO_REGIONS);
14151415
ast_path_to_ty(this,
14161416
rscope,
14171417
span,

0 commit comments

Comments
 (0)