Skip to content

Commit 8f0b945

Browse files
committed
Auto merge of rust-lang#77853 - ijackson:slice-strip-stab, r=Amanieu
Stabilize slice::strip_prefix and slice::strip_suffix These two methods are useful. The corresponding methods on `str` are already stable. I believe that stablising these now would not get in the way of, in the future, extending these to take a richer pattern API a la `str`'s patterns. Tracking PR: rust-lang#73413. I also have an outstanding PR to improve the docs for these two functions and the corresponding ones on `str`: rust-lang#75078 I have tried to follow the [instructions in the dev guide](https://rustc-dev-guide.rust-lang.org/stabilization_guide.html#stabilization-pr). The part to do with `compiler/rustc_feature` did not seem applicable. I assume that's because these are just library features, so there is no corresponding machinery in rustc.
2 parents b5c496d + 8b2e79d commit 8f0b945

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

library/core/src/slice/mod.rs

+44-6
Original file line numberDiff line numberDiff line change
@@ -1872,19 +1872,24 @@ impl<T> [T] {
18721872
/// # Examples
18731873
///
18741874
/// ```
1875-
/// #![feature(slice_strip)]
18761875
/// let v = &[10, 40, 30];
18771876
/// assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
18781877
/// assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
18791878
/// assert_eq!(v.strip_prefix(&[50]), None);
18801879
/// assert_eq!(v.strip_prefix(&[10, 50]), None);
1880+
///
1881+
/// let prefix : &str = "he";
1882+
/// assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
1883+
/// Some(b"llo".as_ref()));
18811884
/// ```
18821885
#[must_use = "returns the subslice without modifying the original"]
1883-
#[unstable(feature = "slice_strip", issue = "73413")]
1884-
pub fn strip_prefix(&self, prefix: &[T]) -> Option<&[T]>
1886+
#[stable(feature = "slice_strip", since = "1.50.0")]
1887+
pub fn strip_prefix<P: SlicePattern<Item = T> + ?Sized>(&self, prefix: &P) -> Option<&[T]>
18851888
where
18861889
T: PartialEq,
18871890
{
1891+
// This function will need rewriting if and when SlicePattern becomes more sophisticated.
1892+
let prefix = prefix.as_slice();
18881893
let n = prefix.len();
18891894
if n <= self.len() {
18901895
let (head, tail) = self.split_at(n);
@@ -1905,19 +1910,20 @@ impl<T> [T] {
19051910
/// # Examples
19061911
///
19071912
/// ```
1908-
/// #![feature(slice_strip)]
19091913
/// let v = &[10, 40, 30];
19101914
/// assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
19111915
/// assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
19121916
/// assert_eq!(v.strip_suffix(&[50]), None);
19131917
/// assert_eq!(v.strip_suffix(&[50, 30]), None);
19141918
/// ```
19151919
#[must_use = "returns the subslice without modifying the original"]
1916-
#[unstable(feature = "slice_strip", issue = "73413")]
1917-
pub fn strip_suffix(&self, suffix: &[T]) -> Option<&[T]>
1920+
#[stable(feature = "slice_strip", since = "1.50.0")]
1921+
pub fn strip_suffix<P: SlicePattern<Item = T> + ?Sized>(&self, suffix: &P) -> Option<&[T]>
19181922
where
19191923
T: PartialEq,
19201924
{
1925+
// This function will need rewriting if and when SlicePattern becomes more sophisticated.
1926+
let suffix = suffix.as_slice();
19211927
let (len, n) = (self.len(), suffix.len());
19221928
if n <= len {
19231929
let (head, tail) = self.split_at(len - n);
@@ -3310,3 +3316,35 @@ impl<T> Default for &mut [T] {
33103316
&mut []
33113317
}
33123318
}
3319+
3320+
#[unstable(feature = "slice_pattern", reason = "stopgap trait for slice patterns", issue = "56345")]
3321+
/// Patterns in slices - currently, only used by `strip_prefix` and `strip_suffix`. At a future
3322+
/// point, we hope to generalise `core::str::Pattern` (which at the time of writing is limited to
3323+
/// `str`) to slices, and then this trait will be replaced or abolished.
3324+
pub trait SlicePattern {
3325+
/// The element type of the slice being matched on.
3326+
type Item;
3327+
3328+
/// Currently, the consumers of `SlicePattern` need a slice.
3329+
fn as_slice(&self) -> &[Self::Item];
3330+
}
3331+
3332+
#[stable(feature = "slice_strip", since = "1.50.0")]
3333+
impl<T> SlicePattern for [T] {
3334+
type Item = T;
3335+
3336+
#[inline]
3337+
fn as_slice(&self) -> &[Self::Item] {
3338+
self
3339+
}
3340+
}
3341+
3342+
#[stable(feature = "slice_strip", since = "1.50.0")]
3343+
impl<T, const N: usize> SlicePattern for [T; N] {
3344+
type Item = T;
3345+
3346+
#[inline]
3347+
fn as_slice(&self) -> &[Self::Item] {
3348+
self
3349+
}
3350+
}

library/std/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,6 @@
307307
#![feature(slice_internals)]
308308
#![feature(slice_ptr_get)]
309309
#![feature(slice_ptr_len)]
310-
#![feature(slice_strip)]
311310
#![feature(staged_api)]
312311
#![feature(std_internals)]
313312
#![feature(stdsimd)]

0 commit comments

Comments
 (0)