@@ -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
@@ -510,10 +510,10 @@ impl<T> [T] {
510510 /// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
511511 /// ```
512512 #[ 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 >
513+ pub fn join < Separator : ?Sized > ( & self , sep : & Separator ) -> < Self as Join < Separator > > :: Output
514+ where Self : Join < Separator >
515515 {
516- SliceConcat :: join ( self , sep)
516+ Join :: join ( self , sep)
517517 }
518518
519519 /// Flattens a slice of `T` into a single value `Self::Output`, placing a
@@ -528,10 +528,10 @@ impl<T> [T] {
528528 /// ```
529529 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
530530 #[ 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 >
531+ pub fn connect < Separator : ?Sized > ( & self , sep : & Separator ) -> < Self as Join < Separator > > :: Output
532+ where Self : Join < Separator >
533533 {
534- SliceConcat :: join ( self , sep)
534+ Join :: join ( self , sep)
535535 }
536536
537537}
@@ -578,37 +578,77 @@ impl [u8] {
578578// Extension traits for slices over specific kinds of data
579579////////////////////////////////////////////////////////////////////////////////
580580
581- /// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat)
582- /// and [`[T]::join`](../../std/primitive.slice.html#method.join)
581+ /// Helper trait for [`[T]::concat`](../../std/primitive.slice.html#method.concat).
582+ ///
583+ /// Note: the `Item` type parameter is not used in this trait,
584+ /// but it allows impls to be more generic.
585+ /// Without it, we get this error:
586+ ///
587+ /// ```error
588+ /// error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predica
589+ /// --> src/liballoc/slice.rs:608:6
590+ /// |
591+ /// 608 | impl<T: Clone, V: Borrow<[T]>> Concat for [V] {
592+ /// | ^ unconstrained type parameter
593+ /// ```
594+ ///
595+ /// This is because there could exist `V` types with multiple `Borrow<[_]>` impls,
596+ /// such that multiple `T` types would apply:
597+ ///
598+ /// ```
599+ /// # #[allow(dead_code)]
600+ /// pub struct Foo(Vec<u32>, Vec<String>);
601+ ///
602+ /// impl std::borrow::Borrow<[u32]> for Foo {
603+ /// fn borrow(&self) -> &[u32] { &self.0 }
604+ /// }
605+ ///
606+ /// impl std::borrow::Borrow<[String]> for Foo {
607+ /// fn borrow(&self) -> &[String] { &self.1 }
608+ /// }
609+ /// ```
583610#[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
584- pub trait SliceConcat < Separator : ?Sized > : Sized {
611+ pub trait Concat < Item : ?Sized > {
585612 #[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
586613 /// The resulting type after concatenation
587614 type Output ;
588615
589616 /// Implementation of [`[T]::concat`](../../std/primitive.slice.html#method.concat)
590617 #[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
591- fn concat ( slice : & [ Self ] ) -> Self :: Output ;
618+ fn concat ( slice : & Self ) -> Self :: Output ;
619+ }
620+
621+ /// Helper trait for [`[T]::join`](../../std/primitive.slice.html#method.join)
622+ #[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
623+ pub trait Join < Separator : ?Sized > {
624+ #[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
625+ /// The resulting type after concatenation
626+ type Output ;
592627
593628 /// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join)
594629 #[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
595- fn join ( slice : & [ Self ] , sep : & Separator ) -> Self :: Output ;
630+ fn join ( slice : & Self , sep : & Separator ) -> Self :: Output ;
596631}
597632
598633#[ unstable( feature = "slice_concat_ext" , issue = "27747" ) ]
599- impl < T : Clone , V : Borrow < [ T ] > > SliceConcat < T > for V {
634+ impl < T : Clone , V : Borrow < [ T ] > > Concat < T > for [ V ] {
600635 type Output = Vec < T > ;
601636
602- fn concat ( slice : & [ Self ] ) -> Vec < T > {
637+ fn concat ( slice : & Self ) -> Vec < T > {
603638 let size = slice. iter ( ) . map ( |slice| slice. borrow ( ) . len ( ) ) . sum ( ) ;
604639 let mut result = Vec :: with_capacity ( size) ;
605640 for v in slice {
606641 result. extend_from_slice ( v. borrow ( ) )
607642 }
608643 result
609644 }
645+ }
646+
647+ #[ unstable( feature = "slice_concat_ext" , issue = "27747" ) ]
648+ impl < T : Clone , V : Borrow < [ T ] > > Join < T > for [ V ] {
649+ type Output = Vec < T > ;
610650
611- fn join ( slice : & [ Self ] , sep : & T ) -> Vec < T > {
651+ fn join ( slice : & Self , sep : & T ) -> Vec < T > {
612652 let mut iter = slice. iter ( ) ;
613653 let first = match iter. next ( ) {
614654 Some ( first) => first,
0 commit comments