@@ -494,10 +494,10 @@ impl<T> [T] {
494
494
/// assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
495
495
/// ```
496
496
#[ 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 >
499
499
{
500
- SliceConcat :: concat ( self )
500
+ Concat :: concat ( self )
501
501
}
502
502
503
503
/// Flattens a slice of `T` into a single value `Self::Output`, placing a
@@ -510,10 +510,10 @@ impl<T> [T] {
510
510
/// assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
511
511
/// ```
512
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 >
513
+ pub fn join < Separator : ?Sized > ( & self , sep : & Separator ) -> < Self as Join < Separator > > :: Output
514
+ where Self : Join < Separator >
515
515
{
516
- SliceConcat :: join ( self , sep)
516
+ Join :: join ( self , sep)
517
517
}
518
518
519
519
/// Flattens a slice of `T` into a single value `Self::Output`, placing a
@@ -528,10 +528,10 @@ impl<T> [T] {
528
528
/// ```
529
529
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
530
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 >
531
+ pub fn connect < Separator : ?Sized > ( & self , sep : & Separator ) -> < Self as Join < Separator > > :: Output
532
+ where Self : Join < Separator >
533
533
{
534
- SliceConcat :: join ( self , sep)
534
+ Join :: join ( self , sep)
535
535
}
536
536
537
537
}
@@ -578,37 +578,77 @@ impl [u8] {
578
578
// Extension traits for slices over specific kinds of data
579
579
////////////////////////////////////////////////////////////////////////////////
580
580
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
+ /// ```
583
610
#[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
584
- pub trait SliceConcat < Separator : ?Sized > : Sized {
611
+ pub trait Concat < Item : ?Sized > {
585
612
#[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
586
613
/// The resulting type after concatenation
587
614
type Output ;
588
615
589
616
/// Implementation of [`[T]::concat`](../../std/primitive.slice.html#method.concat)
590
617
#[ 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 ;
592
627
593
628
/// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join)
594
629
#[ 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 ;
596
631
}
597
632
598
633
#[ 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 ] {
600
635
type Output = Vec < T > ;
601
636
602
- fn concat ( slice : & [ Self ] ) -> Vec < T > {
637
+ fn concat ( slice : & Self ) -> Vec < T > {
603
638
let size = slice. iter ( ) . map ( |slice| slice. borrow ( ) . len ( ) ) . sum ( ) ;
604
639
let mut result = Vec :: with_capacity ( size) ;
605
640
for v in slice {
606
641
result. extend_from_slice ( v. borrow ( ) )
607
642
}
608
643
result
609
644
}
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 > ;
610
650
611
- fn join ( slice : & [ Self ] , sep : & T ) -> Vec < T > {
651
+ fn join ( slice : & Self , sep : & T ) -> Vec < T > {
612
652
let mut iter = slice. iter ( ) ;
613
653
let first = match iter. next ( ) {
614
654
Some ( first) => first,
0 commit comments