Skip to content

Commit e808d92

Browse files
committed
Replace SliceConcatExt trait with inherent methods and SliceConcat helper trait
Before this change `SliceConcatExt` was an unstable extension trait with stable methods. It was in the libstd prelude, so that its methods could be used on the stable channel. This replaces it with inherent methods, which can be used without any addition to the prelude. Since the methods are stable and very generic (with for example a return type that depends on the types of parameters), an helper trait is still needed. But now that trait does not need to be in scope for the methods to be used. Removing this depedency on the libstd prelude allows the methods to be used in `#![no_std]` crate that use liballoc, which does not have its own implicitly-imported prelude.
1 parent baab191 commit e808d92

File tree

5 files changed

+76
-74
lines changed

5 files changed

+76
-74
lines changed

src/liballoc/prelude/v1.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,5 @@
66

77
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned;
88
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box;
9-
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::slice::SliceConcatExt;
109
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString};
1110
#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec;

src/liballoc/slice.rs

+69-60
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,56 @@ impl<T> [T] {
484484
}
485485
buf
486486
}
487+
488+
/// Flattens a slice of `T` into a single value `Self::Output`.
489+
///
490+
/// # Examples
491+
///
492+
/// ```
493+
/// assert_eq!(["hello", "world"].concat(), "helloworld");
494+
/// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
495+
/// ```
496+
#[stable(feature = "rust1", since = "1.0.0")]
497+
pub fn concat<Separator: ?Sized>(&self) -> T::Output
498+
where T: SliceConcat<Separator>
499+
{
500+
SliceConcat::concat(self)
501+
}
502+
503+
/// Flattens a slice of `T` into a single value `Self::Output`, placing a
504+
/// given separator between each.
505+
///
506+
/// # Examples
507+
///
508+
/// ```
509+
/// assert_eq!(["hello", "world"].join(" "), "hello world");
510+
/// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
511+
/// ```
512+
#[stable(feature = "rename_connect_to_join", since = "1.3.0")]
513+
pub fn join<Separator: ?Sized>(&self, sep: &Separator) -> T::Output
514+
where T: SliceConcat<Separator>
515+
{
516+
SliceConcat::join(self, sep)
517+
}
518+
519+
/// Flattens a slice of `T` into a single value `Self::Output`, placing a
520+
/// given separator between each.
521+
///
522+
/// # Examples
523+
///
524+
/// ```
525+
/// # #![allow(deprecated)]
526+
/// assert_eq!(["hello", "world"].connect(" "), "hello world");
527+
/// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
528+
/// ```
529+
#[stable(feature = "rust1", since = "1.0.0")]
530+
#[rustc_deprecated(since = "1.3.0", reason = "renamed to join")]
531+
pub fn connect<Separator: ?Sized>(&self, sep: &Separator) -> T::Output
532+
where T: SliceConcat<Separator>
533+
{
534+
SliceConcat::join(self, sep)
535+
}
536+
487537
}
488538

489539
#[lang = "slice_u8_alloc"]
@@ -527,87 +577,46 @@ impl [u8] {
527577
////////////////////////////////////////////////////////////////////////////////
528578
// Extension traits for slices over specific kinds of data
529579
////////////////////////////////////////////////////////////////////////////////
530-
#[unstable(feature = "slice_concat_ext",
531-
reason = "trait should not have to exist",
532-
issue = "27747")]
533-
/// An extension trait for concatenating slices
534-
///
535-
/// While this trait is unstable, the methods are stable. `SliceConcatExt` is
536-
/// included in the [standard library prelude], so you can use [`join()`] and
537-
/// [`concat()`] as if they existed on `[T]` itself.
538-
///
539-
/// [standard library prelude]: ../../std/prelude/index.html
540-
/// [`join()`]: #tymethod.join
541-
/// [`concat()`]: #tymethod.concat
542-
pub trait SliceConcatExt<T: ?Sized> {
543-
#[unstable(feature = "slice_concat_ext",
544-
reason = "trait should not have to exist",
545-
issue = "27747")]
580+
581+
/// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat)
582+
/// and [`[T]::join`](../../std/primitive.slice.html#method.join)
583+
#[unstable(feature = "slice_concat_trait", issue = "27747")]
584+
pub trait SliceConcat<Separator: ?Sized>: Sized {
585+
#[unstable(feature = "slice_concat_trait", issue = "27747")]
546586
/// The resulting type after concatenation
547587
type Output;
548588

549-
/// Flattens a slice of `T` into a single value `Self::Output`.
550-
///
551-
/// # Examples
552-
///
553-
/// ```
554-
/// assert_eq!(["hello", "world"].concat(), "helloworld");
555-
/// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
556-
/// ```
557-
#[stable(feature = "rust1", since = "1.0.0")]
558-
fn concat(&self) -> Self::Output;
559-
560-
/// Flattens a slice of `T` into a single value `Self::Output`, placing a
561-
/// given separator between each.
562-
///
563-
/// # Examples
564-
///
565-
/// ```
566-
/// assert_eq!(["hello", "world"].join(" "), "hello world");
567-
/// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
568-
/// ```
569-
#[stable(feature = "rename_connect_to_join", since = "1.3.0")]
570-
fn join(&self, sep: &T) -> Self::Output;
589+
/// Implementation of [`[T]::concat`](../../std/primitive.slice.html#method.concat)
590+
#[unstable(feature = "slice_concat_trait", issue = "27747")]
591+
fn concat(slice: &[Self]) -> Self::Output;
571592

572-
/// Flattens a slice of `T` into a single value `Self::Output`, placing a
573-
/// given separator between each.
574-
///
575-
/// # Examples
576-
///
577-
/// ```
578-
/// # #![allow(deprecated)]
579-
/// assert_eq!(["hello", "world"].connect(" "), "hello world");
580-
/// assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
581-
/// ```
582-
#[stable(feature = "rust1", since = "1.0.0")]
583-
#[rustc_deprecated(since = "1.3.0", reason = "renamed to join")]
584-
fn connect(&self, sep: &T) -> Self::Output {
585-
self.join(sep)
586-
}
593+
/// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join)
594+
#[unstable(feature = "slice_concat_trait", issue = "27747")]
595+
fn join(slice: &[Self], sep: &Separator) -> Self::Output;
587596
}
588597

589598
#[unstable(feature = "slice_concat_ext",
590599
reason = "trait should not have to exist",
591600
issue = "27747")]
592-
impl<T: Clone, V: Borrow<[T]>> SliceConcatExt<T> for [V] {
601+
impl<T: Clone, V: Borrow<[T]>> SliceConcat<T> for V {
593602
type Output = Vec<T>;
594603

595-
fn concat(&self) -> Vec<T> {
596-
let size = self.iter().map(|slice| slice.borrow().len()).sum();
604+
fn concat(slice: &[Self]) -> Vec<T> {
605+
let size = slice.iter().map(|slice| slice.borrow().len()).sum();
597606
let mut result = Vec::with_capacity(size);
598-
for v in self {
607+
for v in slice {
599608
result.extend_from_slice(v.borrow())
600609
}
601610
result
602611
}
603612

604-
fn join(&self, sep: &T) -> Vec<T> {
605-
let mut iter = self.iter();
613+
fn join(slice: &[Self], sep: &T) -> Vec<T> {
614+
let mut iter = slice.iter();
606615
let first = match iter.next() {
607616
Some(first) => first,
608617
None => return vec![],
609618
};
610-
let size = self.iter().map(|slice| slice.borrow().len()).sum::<usize>() + self.len() - 1;
619+
let size = slice.iter().map(|slice| slice.borrow().len()).sum::<usize>() + slice.len() - 1;
611620
let mut result = Vec::with_capacity(size);
612621
result.extend_from_slice(first.borrow());
613622

src/liballoc/str.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use core::unicode::conversions;
3737

3838
use crate::borrow::ToOwned;
3939
use crate::boxed::Box;
40-
use crate::slice::{SliceConcatExt, SliceIndex};
40+
use crate::slice::{SliceConcat, SliceIndex};
4141
use crate::string::String;
4242
use crate::vec::Vec;
4343

@@ -74,16 +74,16 @@ pub use core::str::{EscapeDebug, EscapeDefault, EscapeUnicode};
7474
#[unstable(feature = "slice_concat_ext",
7575
reason = "trait should not have to exist",
7676
issue = "27747")]
77-
impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
77+
impl<S: Borrow<str>> SliceConcat<str> for S {
7878
type Output = String;
7979

80-
fn concat(&self) -> String {
81-
self.join("")
80+
fn concat(slice: &[Self]) -> String {
81+
Self::join(slice, "")
8282
}
8383

84-
fn join(&self, sep: &str) -> String {
84+
fn join(slice: &[Self], sep: &str) -> String {
8585
unsafe {
86-
String::from_utf8_unchecked( join_generic_copy(self, sep.as_bytes()) )
86+
String::from_utf8_unchecked( join_generic_copy(slice, sep.as_bytes()) )
8787
}
8888
}
8989
}
@@ -126,7 +126,7 @@ macro_rules! copy_slice_and_advance {
126126

127127
// Optimized join implementation that works for both Vec<T> (T: Copy) and String's inner vec
128128
// Currently (2018-05-13) there is a bug with type inference and specialization (see issue #36262)
129-
// For this reason SliceConcatExt<T> is not specialized for T: Copy and SliceConcatExt<str> is the
129+
// For this reason SliceConcat<T> is not specialized for T: Copy and SliceConcat<str> is the
130130
// only user of this function. It is left in place for the time when that is fixed.
131131
//
132132
// the bounds for String-join are S: Borrow<str> and for Vec-join Borrow<[T]>

src/libstd/prelude/mod.rs

-3
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,6 @@
7171
//! * [`std::result`]::[`Result`]::{`self`, `Ok`, `Err`}. A type for functions
7272
//! that may succeed or fail. Like [`Option`], its variants are exported as
7373
//! well.
74-
//! * [`std::slice`]::[`SliceConcatExt`], a trait that exists for technical
75-
//! reasons, but shouldn't have to exist. It provides a few useful methods on
76-
//! slices.
7774
//! * [`std::string`]::{[`String`], [`ToString`]}, heap allocated strings.
7875
//! * [`std::vec`]::[`Vec`](../vec/struct.Vec.html), a growable, heap-allocated
7976
//! vector.

src/libstd/prelude/v1.rs

-3
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,6 @@ pub use crate::boxed::Box;
6060
pub use crate::borrow::ToOwned;
6161
#[stable(feature = "rust1", since = "1.0.0")]
6262
#[doc(no_inline)]
63-
pub use crate::slice::SliceConcatExt;
64-
#[stable(feature = "rust1", since = "1.0.0")]
65-
#[doc(no_inline)]
6663
pub use crate::string::{String, ToString};
6764
#[stable(feature = "rust1", since = "1.0.0")]
6865
#[doc(no_inline)]

0 commit comments

Comments
 (0)