diff --git a/src/liballoc/prelude/v1.rs b/src/liballoc/prelude/v1.rs index b6b01395ad6..3cb285bf049 100644 --- a/src/liballoc/prelude/v1.rs +++ b/src/liballoc/prelude/v1.rs @@ -6,6 +6,5 @@ #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned; #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box; -#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::slice::SliceConcatExt; #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString}; #[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec; diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index f7b0a5e703c..bc4ae167984 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -484,6 +484,56 @@ impl [T] { } buf } + + /// Flattens a slice of `T` into a single value `Self::Output`. + /// + /// # Examples + /// + /// ``` + /// assert_eq!(["hello", "world"].concat(), "helloworld"); + /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + pub fn concat(&self) -> T::Output + where T: SliceConcat + { + SliceConcat::concat(self) + } + + /// Flattens a slice of `T` into a single value `Self::Output`, placing a + /// given separator between each. + /// + /// # Examples + /// + /// ``` + /// assert_eq!(["hello", "world"].join(" "), "hello world"); + /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); + /// ``` + #[stable(feature = "rename_connect_to_join", since = "1.3.0")] + pub fn join(&self, sep: &Separator) -> T::Output + where T: SliceConcat + { + SliceConcat::join(self, sep) + } + + /// Flattens a slice of `T` into a single value `Self::Output`, placing a + /// given separator between each. + /// + /// # Examples + /// + /// ``` + /// # #![allow(deprecated)] + /// assert_eq!(["hello", "world"].connect(" "), "hello world"); + /// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")] + pub fn connect(&self, sep: &Separator) -> T::Output + where T: SliceConcat + { + SliceConcat::join(self, sep) + } + } #[lang = "slice_u8_alloc"] @@ -527,87 +577,46 @@ impl [u8] { //////////////////////////////////////////////////////////////////////////////// // Extension traits for slices over specific kinds of data //////////////////////////////////////////////////////////////////////////////// -#[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] -/// An extension trait for concatenating slices -/// -/// While this trait is unstable, the methods are stable. `SliceConcatExt` is -/// included in the [standard library prelude], so you can use [`join()`] and -/// [`concat()`] as if they existed on `[T]` itself. -/// -/// [standard library prelude]: ../../std/prelude/index.html -/// [`join()`]: #tymethod.join -/// [`concat()`]: #tymethod.concat -pub trait SliceConcatExt { - #[unstable(feature = "slice_concat_ext", - reason = "trait should not have to exist", - issue = "27747")] + +/// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat) +/// and [`[T]::join`](../../std/primitive.slice.html#method.join) +#[unstable(feature = "slice_concat_trait", issue = "27747")] +pub trait SliceConcat: Sized { + #[unstable(feature = "slice_concat_trait", issue = "27747")] /// The resulting type after concatenation type Output; - /// Flattens a slice of `T` into a single value `Self::Output`. - /// - /// # Examples - /// - /// ``` - /// assert_eq!(["hello", "world"].concat(), "helloworld"); - /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn concat(&self) -> Self::Output; + /// Implementation of [`[T]::concat`](../../std/primitive.slice.html#method.concat) + #[unstable(feature = "slice_concat_trait", issue = "27747")] + fn concat(slice: &[Self]) -> Self::Output; - /// Flattens a slice of `T` into a single value `Self::Output`, placing a - /// given separator between each. - /// - /// # Examples - /// - /// ``` - /// assert_eq!(["hello", "world"].join(" "), "hello world"); - /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]); - /// ``` - #[stable(feature = "rename_connect_to_join", since = "1.3.0")] - fn join(&self, sep: &T) -> Self::Output; - - /// Flattens a slice of `T` into a single value `Self::Output`, placing a - /// given separator between each. - /// - /// # Examples - /// - /// ``` - /// # #![allow(deprecated)] - /// assert_eq!(["hello", "world"].connect(" "), "hello world"); - /// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_deprecated(since = "1.3.0", reason = "renamed to join")] - fn connect(&self, sep: &T) -> Self::Output { - self.join(sep) - } + /// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join) + #[unstable(feature = "slice_concat_trait", issue = "27747")] + fn join(slice: &[Self], sep: &Separator) -> Self::Output; } #[unstable(feature = "slice_concat_ext", reason = "trait should not have to exist", issue = "27747")] -impl> SliceConcatExt for [V] { +impl> SliceConcat for V { type Output = Vec; - fn concat(&self) -> Vec { - let size = self.iter().map(|slice| slice.borrow().len()).sum(); + fn concat(slice: &[Self]) -> Vec { + let size = slice.iter().map(|slice| slice.borrow().len()).sum(); let mut result = Vec::with_capacity(size); - for v in self { + for v in slice { result.extend_from_slice(v.borrow()) } result } - fn join(&self, sep: &T) -> Vec { - let mut iter = self.iter(); + fn join(slice: &[Self], sep: &T) -> Vec { + let mut iter = slice.iter(); let first = match iter.next() { Some(first) => first, None => return vec![], }; - let size = self.iter().map(|slice| slice.borrow().len()).sum::() + self.len() - 1; + let size = slice.iter().map(|slice| slice.borrow().len()).sum::() + slice.len() - 1; let mut result = Vec::with_capacity(size); result.extend_from_slice(first.borrow()); diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 70a93157c9e..37a1046d094 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -37,7 +37,7 @@ use core::unicode::conversions; use crate::borrow::ToOwned; use crate::boxed::Box; -use crate::slice::{SliceConcatExt, SliceIndex}; +use crate::slice::{SliceConcat, SliceIndex}; use crate::string::String; use crate::vec::Vec; @@ -74,16 +74,16 @@ pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode}; #[unstable(feature = "slice_concat_ext", reason = "trait should not have to exist", issue = "27747")] -impl> SliceConcatExt for [S] { +impl> SliceConcat for S { type Output = String; - fn concat(&self) -> String { - self.join("") + fn concat(slice: &[Self]) -> String { + Self::join(slice, "") } - fn join(&self, sep: &str) -> String { + fn join(slice: &[Self], sep: &str) -> String { unsafe { - String::from_utf8_unchecked( join_generic_copy(self, sep.as_bytes()) ) + String::from_utf8_unchecked( join_generic_copy(slice, sep.as_bytes()) ) } } } @@ -126,7 +126,7 @@ macro_rules! copy_slice_and_advance { // Optimized join implementation that works for both Vec (T: Copy) and String's inner vec // Currently (2018-05-13) there is a bug with type inference and specialization (see issue #36262) -// For this reason SliceConcatExt is not specialized for T: Copy and SliceConcatExt is the +// For this reason SliceConcat is not specialized for T: Copy and SliceConcat is the // only user of this function. It is left in place for the time when that is fixed. // // the bounds for String-join are S: Borrow and for Vec-join Borrow<[T]> diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs index 551e982a3c6..3085c3d8296 100644 --- a/src/libstd/prelude/mod.rs +++ b/src/libstd/prelude/mod.rs @@ -71,9 +71,6 @@ //! * [`std::result`]::[`Result`]::{`self`, `Ok`, `Err`}. A type for functions //! that may succeed or fail. Like [`Option`], its variants are exported as //! well. -//! * [`std::slice`]::[`SliceConcatExt`], a trait that exists for technical -//! reasons, but shouldn't have to exist. It provides a few useful methods on -//! slices. //! * [`std::string`]::{[`String`], [`ToString`]}, heap allocated strings. //! * [`std::vec`]::[`Vec`](../vec/struct.Vec.html), a growable, heap-allocated //! vector. diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs index ce1e8e3319c..a863bebf4a2 100644 --- a/src/libstd/prelude/v1.rs +++ b/src/libstd/prelude/v1.rs @@ -60,9 +60,6 @@ pub use crate::boxed::Box; pub use crate::borrow::ToOwned; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] -pub use crate::slice::SliceConcatExt; -#[stable(feature = "rust1", since = "1.0.0")] -#[doc(no_inline)] pub use crate::string::{String, ToString}; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)]