Skip to content

Commit 3d90740

Browse files
authored
Rollup merge of #136555 - cramertj:split_off, r=dtolnay
Rename `slice::take...` methods to `split_off...` This rename was discussed and recommended in a recent t-libs meeting. cc #62280 There's an additional commit here which modifies internals of unstable `OneSidedRange` APIs in order to implement `split_off` methods in a panic-free way (remove `unreachable!()`) as recommended in https://github.com/rust-lang/rust/pull/88502/files#r760177240. I can split this out into a separate PR if needed.
2 parents d41e33f + 836a989 commit 3d90740

File tree

4 files changed

+134
-95
lines changed

4 files changed

+134
-95
lines changed

library/core/src/ops/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,10 @@ pub use self::function::{Fn, FnMut, FnOnce};
182182
#[stable(feature = "rust1", since = "1.0.0")]
183183
pub use self::index::{Index, IndexMut};
184184
pub(crate) use self::index_range::IndexRange;
185-
#[unstable(feature = "one_sided_range", issue = "69780")]
186-
pub use self::range::OneSidedRange;
187185
#[stable(feature = "inclusive_range", since = "1.26.0")]
188186
pub use self::range::{Bound, RangeBounds, RangeInclusive, RangeToInclusive};
187+
#[unstable(feature = "one_sided_range", issue = "69780")]
188+
pub use self::range::{OneSidedRange, OneSidedRangeBound};
189189
#[stable(feature = "rust1", since = "1.0.0")]
190190
pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
191191
#[unstable(feature = "try_trait_v2_residual", issue = "91285")]

library/core/src/ops/range.rs

+42-4
Original file line numberDiff line numberDiff line change
@@ -979,20 +979,58 @@ impl<T> RangeBounds<T> for RangeToInclusive<&T> {
979979
}
980980
}
981981

982+
/// An internal helper for `split_off` functions indicating
983+
/// which end a `OneSidedRange` is bounded on.
984+
#[unstable(feature = "one_sided_range", issue = "69780")]
985+
#[allow(missing_debug_implementations)]
986+
pub enum OneSidedRangeBound {
987+
/// The range is bounded inclusively from below and is unbounded above.
988+
StartInclusive,
989+
/// The range is bounded exclusively from above and is unbounded below.
990+
End,
991+
/// The range is bounded inclusively from above and is unbounded below.
992+
EndInclusive,
993+
}
994+
982995
/// `OneSidedRange` is implemented for built-in range types that are unbounded
983996
/// on one side. For example, `a..`, `..b` and `..=c` implement `OneSidedRange`,
984997
/// but `..`, `d..e`, and `f..=g` do not.
985998
///
986999
/// Types that implement `OneSidedRange<T>` must return `Bound::Unbounded`
9871000
/// from one of `RangeBounds::start_bound` or `RangeBounds::end_bound`.
9881001
#[unstable(feature = "one_sided_range", issue = "69780")]
989-
pub trait OneSidedRange<T: ?Sized>: RangeBounds<T> {}
1002+
pub trait OneSidedRange<T: ?Sized>: RangeBounds<T> {
1003+
/// An internal-only helper function for `split_off` and
1004+
/// `split_off_mut` that returns the bound of the one-sided range.
1005+
fn bound(self) -> (OneSidedRangeBound, T);
1006+
}
9901007

9911008
#[unstable(feature = "one_sided_range", issue = "69780")]
992-
impl<T> OneSidedRange<T> for RangeTo<T> where Self: RangeBounds<T> {}
1009+
impl<T> OneSidedRange<T> for RangeTo<T>
1010+
where
1011+
Self: RangeBounds<T>,
1012+
{
1013+
fn bound(self) -> (OneSidedRangeBound, T) {
1014+
(OneSidedRangeBound::End, self.end)
1015+
}
1016+
}
9931017

9941018
#[unstable(feature = "one_sided_range", issue = "69780")]
995-
impl<T> OneSidedRange<T> for RangeFrom<T> where Self: RangeBounds<T> {}
1019+
impl<T> OneSidedRange<T> for RangeFrom<T>
1020+
where
1021+
Self: RangeBounds<T>,
1022+
{
1023+
fn bound(self) -> (OneSidedRangeBound, T) {
1024+
(OneSidedRangeBound::StartInclusive, self.start)
1025+
}
1026+
}
9961027

9971028
#[unstable(feature = "one_sided_range", issue = "69780")]
998-
impl<T> OneSidedRange<T> for RangeToInclusive<T> where Self: RangeBounds<T> {}
1029+
impl<T> OneSidedRange<T> for RangeToInclusive<T>
1030+
where
1031+
Self: RangeBounds<T>,
1032+
{
1033+
fn bound(self) -> (OneSidedRangeBound, T) {
1034+
(OneSidedRangeBound::EndInclusive, self.end)
1035+
}
1036+
}

library/core/src/slice/mod.rs

+35-34
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::cmp::Ordering::{self, Equal, Greater, Less};
1010
use crate::intrinsics::{exact_div, unchecked_sub};
1111
use crate::mem::{self, SizedTypeProperties};
1212
use crate::num::NonZero;
13-
use crate::ops::{Bound, OneSidedRange, Range, RangeBounds, RangeInclusive};
13+
use crate::ops::{OneSidedRange, OneSidedRangeBound, Range, RangeBounds, RangeInclusive};
1414
use crate::panic::const_panic;
1515
use crate::simd::{self, Simd};
1616
use crate::ub_checks::assert_unsafe_precondition;
@@ -83,14 +83,12 @@ pub use raw::{from_raw_parts, from_raw_parts_mut};
8383
/// which to split. Returns `None` if the split index would overflow.
8484
#[inline]
8585
fn split_point_of(range: impl OneSidedRange<usize>) -> Option<(Direction, usize)> {
86-
use Bound::*;
87-
88-
Some(match (range.start_bound(), range.end_bound()) {
89-
(Unbounded, Excluded(i)) => (Direction::Front, *i),
90-
(Unbounded, Included(i)) => (Direction::Front, i.checked_add(1)?),
91-
(Excluded(i), Unbounded) => (Direction::Back, i.checked_add(1)?),
92-
(Included(i), Unbounded) => (Direction::Back, *i),
93-
_ => unreachable!(),
86+
use OneSidedRangeBound::{End, EndInclusive, StartInclusive};
87+
88+
Some(match range.bound() {
89+
(StartInclusive, i) => (Direction::Back, i),
90+
(End, i) => (Direction::Front, i),
91+
(EndInclusive, i) => (Direction::Front, i.checked_add(1)?),
9492
})
9593
}
9694

@@ -4294,25 +4292,25 @@ impl<T> [T] {
42944292
///
42954293
/// # Examples
42964294
///
4297-
/// Taking the first three elements of a slice:
4295+
/// Splitting off the first three elements of a slice:
42984296
///
42994297
/// ```
43004298
/// #![feature(slice_take)]
43014299
///
43024300
/// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
4303-
/// let mut first_three = slice.take(..3).unwrap();
4301+
/// let mut first_three = slice.split_off(..3).unwrap();
43044302
///
43054303
/// assert_eq!(slice, &['d']);
43064304
/// assert_eq!(first_three, &['a', 'b', 'c']);
43074305
/// ```
43084306
///
4309-
/// Taking the last two elements of a slice:
4307+
/// Splitting off the last two elements of a slice:
43104308
///
43114309
/// ```
43124310
/// #![feature(slice_take)]
43134311
///
43144312
/// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
4315-
/// let mut tail = slice.take(2..).unwrap();
4313+
/// let mut tail = slice.split_off(2..).unwrap();
43164314
///
43174315
/// assert_eq!(slice, &['a', 'b']);
43184316
/// assert_eq!(tail, &['c', 'd']);
@@ -4325,16 +4323,19 @@ impl<T> [T] {
43254323
///
43264324
/// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
43274325
///
4328-
/// assert_eq!(None, slice.take(5..));
4329-
/// assert_eq!(None, slice.take(..5));
4330-
/// assert_eq!(None, slice.take(..=4));
4326+
/// assert_eq!(None, slice.split_off(5..));
4327+
/// assert_eq!(None, slice.split_off(..5));
4328+
/// assert_eq!(None, slice.split_off(..=4));
43314329
/// let expected: &[char] = &['a', 'b', 'c', 'd'];
4332-
/// assert_eq!(Some(expected), slice.take(..4));
4330+
/// assert_eq!(Some(expected), slice.split_off(..4));
43334331
/// ```
43344332
#[inline]
43354333
#[must_use = "method does not modify the slice if the range is out of bounds"]
43364334
#[unstable(feature = "slice_take", issue = "62280")]
4337-
pub fn take<'a, R: OneSidedRange<usize>>(self: &mut &'a Self, range: R) -> Option<&'a Self> {
4335+
pub fn split_off<'a, R: OneSidedRange<usize>>(
4336+
self: &mut &'a Self,
4337+
range: R,
4338+
) -> Option<&'a Self> {
43384339
let (direction, split_index) = split_point_of(range)?;
43394340
if split_index > self.len() {
43404341
return None;
@@ -4363,13 +4364,13 @@ impl<T> [T] {
43634364
///
43644365
/// # Examples
43654366
///
4366-
/// Taking the first three elements of a slice:
4367+
/// Splitting off the first three elements of a slice:
43674368
///
43684369
/// ```
43694370
/// #![feature(slice_take)]
43704371
///
43714372
/// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
4372-
/// let mut first_three = slice.take_mut(..3).unwrap();
4373+
/// let mut first_three = slice.split_off_mut(..3).unwrap();
43734374
///
43744375
/// assert_eq!(slice, &mut ['d']);
43754376
/// assert_eq!(first_three, &mut ['a', 'b', 'c']);
@@ -4381,7 +4382,7 @@ impl<T> [T] {
43814382
/// #![feature(slice_take)]
43824383
///
43834384
/// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
4384-
/// let mut tail = slice.take_mut(2..).unwrap();
4385+
/// let mut tail = slice.split_off_mut(2..).unwrap();
43854386
///
43864387
/// assert_eq!(slice, &mut ['a', 'b']);
43874388
/// assert_eq!(tail, &mut ['c', 'd']);
@@ -4394,16 +4395,16 @@ impl<T> [T] {
43944395
///
43954396
/// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
43964397
///
4397-
/// assert_eq!(None, slice.take_mut(5..));
4398-
/// assert_eq!(None, slice.take_mut(..5));
4399-
/// assert_eq!(None, slice.take_mut(..=4));
4398+
/// assert_eq!(None, slice.split_off_mut(5..));
4399+
/// assert_eq!(None, slice.split_off_mut(..5));
4400+
/// assert_eq!(None, slice.split_off_mut(..=4));
44004401
/// let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
4401-
/// assert_eq!(Some(expected), slice.take_mut(..4));
4402+
/// assert_eq!(Some(expected), slice.split_off_mut(..4));
44024403
/// ```
44034404
#[inline]
44044405
#[must_use = "method does not modify the slice if the range is out of bounds"]
44054406
#[unstable(feature = "slice_take", issue = "62280")]
4406-
pub fn take_mut<'a, R: OneSidedRange<usize>>(
4407+
pub fn split_off_mut<'a, R: OneSidedRange<usize>>(
44074408
self: &mut &'a mut Self,
44084409
range: R,
44094410
) -> Option<&'a mut Self> {
@@ -4435,14 +4436,14 @@ impl<T> [T] {
44354436
/// #![feature(slice_take)]
44364437
///
44374438
/// let mut slice: &[_] = &['a', 'b', 'c'];
4438-
/// let first = slice.take_first().unwrap();
4439+
/// let first = slice.split_off_first().unwrap();
44394440
///
44404441
/// assert_eq!(slice, &['b', 'c']);
44414442
/// assert_eq!(first, &'a');
44424443
/// ```
44434444
#[inline]
44444445
#[unstable(feature = "slice_take", issue = "62280")]
4445-
pub fn take_first<'a>(self: &mut &'a Self) -> Option<&'a T> {
4446+
pub fn split_off_first<'a>(self: &mut &'a Self) -> Option<&'a T> {
44464447
let (first, rem) = self.split_first()?;
44474448
*self = rem;
44484449
Some(first)
@@ -4459,15 +4460,15 @@ impl<T> [T] {
44594460
/// #![feature(slice_take)]
44604461
///
44614462
/// let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
4462-
/// let first = slice.take_first_mut().unwrap();
4463+
/// let first = slice.split_off_first_mut().unwrap();
44634464
/// *first = 'd';
44644465
///
44654466
/// assert_eq!(slice, &['b', 'c']);
44664467
/// assert_eq!(first, &'d');
44674468
/// ```
44684469
#[inline]
44694470
#[unstable(feature = "slice_take", issue = "62280")]
4470-
pub fn take_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
4471+
pub fn split_off_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
44714472
let (first, rem) = mem::take(self).split_first_mut()?;
44724473
*self = rem;
44734474
Some(first)
@@ -4484,14 +4485,14 @@ impl<T> [T] {
44844485
/// #![feature(slice_take)]
44854486
///
44864487
/// let mut slice: &[_] = &['a', 'b', 'c'];
4487-
/// let last = slice.take_last().unwrap();
4488+
/// let last = slice.split_off_last().unwrap();
44884489
///
44894490
/// assert_eq!(slice, &['a', 'b']);
44904491
/// assert_eq!(last, &'c');
44914492
/// ```
44924493
#[inline]
44934494
#[unstable(feature = "slice_take", issue = "62280")]
4494-
pub fn take_last<'a>(self: &mut &'a Self) -> Option<&'a T> {
4495+
pub fn split_off_last<'a>(self: &mut &'a Self) -> Option<&'a T> {
44954496
let (last, rem) = self.split_last()?;
44964497
*self = rem;
44974498
Some(last)
@@ -4508,15 +4509,15 @@ impl<T> [T] {
45084509
/// #![feature(slice_take)]
45094510
///
45104511
/// let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
4511-
/// let last = slice.take_last_mut().unwrap();
4512+
/// let last = slice.split_off_last_mut().unwrap();
45124513
/// *last = 'd';
45134514
///
45144515
/// assert_eq!(slice, &['a', 'b']);
45154516
/// assert_eq!(last, &'d');
45164517
/// ```
45174518
#[inline]
45184519
#[unstable(feature = "slice_take", issue = "62280")]
4519-
pub fn take_last_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
4520+
pub fn split_off_last_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
45204521
let (last, rem) = mem::take(self).split_last_mut()?;
45214522
*self = rem;
45224523
Some(last)

0 commit comments

Comments
 (0)