@@ -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
@@ -508,12 +508,13 @@ impl<T> [T] {
508
508
/// ```
509
509
/// assert_eq!(["hello", "world"].join(" "), "hello world");
510
510
/// 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]);
511
512
/// ```
512
513
#[ 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 >
515
516
{
516
- SliceConcat :: join ( self , sep)
517
+ Join :: join ( self , sep)
517
518
}
518
519
519
520
/// Flattens a slice of `T` into a single value `Self::Output`, placing a
@@ -528,10 +529,10 @@ impl<T> [T] {
528
529
/// ```
529
530
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
530
531
#[ 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 >
533
534
{
534
- SliceConcat :: join ( self , sep)
535
+ Join :: join ( self , sep)
535
536
}
536
537
537
538
}
@@ -578,45 +579,83 @@ impl [u8] {
578
579
// Extension traits for slices over specific kinds of data
579
580
////////////////////////////////////////////////////////////////////////////////
580
581
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
+ /// ```
583
611
#[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
584
- pub trait SliceConcat < Separator : ?Sized > : Sized {
612
+ pub trait Concat < Item : ?Sized > {
585
613
#[ unstable( feature = "slice_concat_trait" , issue = "27747" ) ]
586
614
/// The resulting type after concatenation
587
615
type Output ;
588
616
589
617
/// Implementation of [`[T]::concat`](../../std/primitive.slice.html#method.concat)
590
618
#[ 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 ;
592
628
593
629
/// Implementation of [`[T]::join`](../../std/primitive.slice.html#method.join)
594
630
#[ 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 ;
596
632
}
597
633
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 ] {
602
636
type Output = Vec < T > ;
603
637
604
- fn concat ( slice : & [ Self ] ) -> Vec < T > {
638
+ fn concat ( slice : & Self ) -> Vec < T > {
605
639
let size = slice. iter ( ) . map ( |slice| slice. borrow ( ) . len ( ) ) . sum ( ) ;
606
640
let mut result = Vec :: with_capacity ( size) ;
607
641
for v in slice {
608
642
result. extend_from_slice ( v. borrow ( ) )
609
643
}
610
644
result
611
645
}
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 > ;
612
651
613
- fn join ( slice : & [ Self ] , sep : & T ) -> Vec < T > {
652
+ fn join ( slice : & Self , sep : & T ) -> Vec < T > {
614
653
let mut iter = slice. iter ( ) ;
615
654
let first = match iter. next ( ) {
616
655
Some ( first) => first,
617
656
None => return vec ! [ ] ,
618
657
} ;
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 ;
620
659
let mut result = Vec :: with_capacity ( size) ;
621
660
result. extend_from_slice ( first. borrow ( ) ) ;
622
661
@@ -628,6 +667,29 @@ impl<T: Clone, V: Borrow<[T]>> SliceConcat<T> for V {
628
667
}
629
668
}
630
669
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
+
631
693
////////////////////////////////////////////////////////////////////////////////
632
694
// Standard trait implementations for slices
633
695
////////////////////////////////////////////////////////////////////////////////
0 commit comments