@@ -494,10 +494,10 @@ impl<T> [T] {
494494 /// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
495495 /// ```
496496 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
497- pub fn concat < Separator : ?Sized > ( & self ) -> T :: Output
498- where T : SliceConcat < Separator >
497+ pub fn concat < Item : ?Sized > ( & self ) -> < Self as Concat < Item > > :: Output
498+ where Self : Concat < Item >
499499 {
500- SliceConcat :: concat ( self )
500+ Concat :: concat ( self )
501501 }
502502
503503 /// Flattens a slice of `T` into a single value `Self::Output`, placing a
@@ -508,12 +508,13 @@ impl<T> [T] {
508508 /// ```
509509 /// assert_eq!(["hello", "world"].join(" "), "hello world");
510510 /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
511+ /// assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
511512 /// ```
512513 #[ 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 >
514+ pub fn join < Separator > ( & self , sep : Separator ) -> < Self as Join < Separator > > :: Output
515+ where Self : Join < Separator >
515516 {
516- SliceConcat :: join ( self , sep)
517+ Join :: join ( self , sep)
517518 }
518519
519520 /// Flattens a slice of `T` into a single value `Self::Output`, placing a
@@ -528,10 +529,10 @@ impl<T> [T] {
528529 /// ```
529530 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
530531 #[ 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 >
532+ pub fn connect < Separator > ( & self , sep : Separator ) -> < Self as Join < Separator > > :: Output
533+ where Self : Join < Separator >
533534 {
534- SliceConcat :: join ( self , sep)
535+ Join :: join ( self , sep)
535536 }
536537
537538}
@@ -578,45 +579,83 @@ impl [u8] {
578579// Extension traits for slices over specific kinds of data
579580////////////////////////////////////////////////////////////////////////////////
580581
581- /// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat)
582- /// and [`[T]::join`](../../std/primitive.slice.html#method.join)
582+ /// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat).
583+ ///
584+ /// Note: the `Item` type parameter is not used in this trait,
585+ /// but it allows impls to be more generic.
586+ /// Without it, we get this error:
587+ ///
588+ /// ```error
589+ /// error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predica
590+ /// --> src/liballoc/slice.rs:608:6
591+ /// |
592+ /// 608 | impl<T: Clone, V: Borrow<[T]>> Concat for [V] {
593+ /// | ^ unconstrained type parameter
594+ /// ```
595+ ///
596+ /// This is because there could exist `V` types with multiple `Borrow<[_]>` impls,
597+ /// such that multiple `T` types would apply:
598+ ///
599+ /// ```
600+ /// # #[allow(dead_code)]
601+ /// pub struct Foo(Vec<u32>, Vec<String>);
602+ ///
603+ /// impl std::borrow::Borrow<[u32]> for Foo {
604+ /// fn borrow(&self) -> &[u32] { &self.0 }
605+ /// }
606+ ///
607+ /// impl std::borrow::Borrow<[String]> for Foo {
608+ /// fn borrow(&self) -> &[String] { &self.1 }
609+ /// }
610+ /// ```
583611#[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
584- pub trait SliceConcat < Separator : ?Sized > : Sized {
612+ pub trait Concat < Item : ?Sized > {
585613 #[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
586614 /// The resulting type after concatenation
587615 type Output ;
588616
589617 /// Implementation of [`[T]::concat`](../../std/primitive.slice.html#method.concat)
590618 #[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
591- fn concat ( slice : & [ Self ] ) -> Self :: Output ;
619+ fn concat ( slice : & Self ) -> Self :: Output ;
620+ }
621+
622+ /// Helper trait for [`[T]::join`](../../std/primitive.slice.html#method.join)
623+ #[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
624+ pub trait Join < Separator > {
625+ #[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
626+ /// The resulting type after concatenation
627+ type Output ;
592628
593629 /// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join)
594630 #[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
595- fn join ( slice : & [ Self ] , sep : & Separator ) -> Self :: Output ;
631+ fn join ( slice : & Self , sep : Separator ) -> Self :: Output ;
596632}
597633
598- #[ unstable( feature = "slice_concat_ext" ,
599- reason = "trait should not have to exist" ,
600- issue = "27747" ) ]
601- impl < T : Clone , V : Borrow < [ T ] > > SliceConcat < T > for V {
634+ #[ unstable( feature = "slice_concat_ext" , issue = "27747" ) ]
635+ impl < T : Clone , V : Borrow < [ T ] > > Concat < T > for [ V ] {
602636 type Output = Vec < T > ;
603637
604- fn concat ( slice : & [ Self ] ) -> Vec < T > {
638+ fn concat ( slice : & Self ) -> Vec < T > {
605639 let size = slice. iter ( ) . map ( |slice| slice. borrow ( ) . len ( ) ) . sum ( ) ;
606640 let mut result = Vec :: with_capacity ( size) ;
607641 for v in slice {
608642 result. extend_from_slice ( v. borrow ( ) )
609643 }
610644 result
611645 }
646+ }
647+
648+ #[ unstable( feature = "slice_concat_ext" , issue = "27747" ) ]
649+ impl < T : Clone , V : Borrow < [ T ] > > Join < & T > for [ V ] {
650+ type Output = Vec < T > ;
612651
613- fn join ( slice : & [ Self ] , sep : & T ) -> Vec < T > {
652+ fn join ( slice : & Self , sep : & T ) -> Vec < T > {
614653 let mut iter = slice. iter ( ) ;
615654 let first = match iter. next ( ) {
616655 Some ( first) => first,
617656 None => return vec ! [ ] ,
618657 } ;
619- let size = slice. iter ( ) . map ( |slice| slice . borrow ( ) . len ( ) ) . sum :: < usize > ( ) + slice. len ( ) - 1 ;
658+ let size = slice. iter ( ) . map ( |v| v . borrow ( ) . len ( ) ) . sum :: < usize > ( ) + slice. len ( ) - 1 ;
620659 let mut result = Vec :: with_capacity ( size) ;
621660 result. extend_from_slice ( first. borrow ( ) ) ;
622661
@@ -628,6 +667,29 @@ impl<T: Clone, V: Borrow<[T]>> SliceConcat<T> for V {
628667 }
629668}
630669
670+ #[ unstable( feature = "slice_concat_ext" , issue = "27747" ) ]
671+ impl < T : Clone , V : Borrow < [ T ] > > Join < & [ T ] > for [ V ] {
672+ type Output = Vec < T > ;
673+
674+ fn join ( slice : & Self , sep : & [ T ] ) -> Vec < T > {
675+ let mut iter = slice. iter ( ) ;
676+ let first = match iter. next ( ) {
677+ Some ( first) => first,
678+ None => return vec ! [ ] ,
679+ } ;
680+ let size = slice. iter ( ) . map ( |v| v. borrow ( ) . len ( ) ) . sum :: < usize > ( ) +
681+ sep. len ( ) * ( slice. len ( ) - 1 ) ;
682+ let mut result = Vec :: with_capacity ( size) ;
683+ result. extend_from_slice ( first. borrow ( ) ) ;
684+
685+ for v in iter {
686+ result. extend_from_slice ( sep) ;
687+ result. extend_from_slice ( v. borrow ( ) )
688+ }
689+ result
690+ }
691+ }
692+
631693////////////////////////////////////////////////////////////////////////////////
632694// Standard trait implementations for slices
633695////////////////////////////////////////////////////////////////////////////////
0 commit comments