@@ -2,6 +2,8 @@ use std::borrow::Cow;
2
2
use std:: collections:: TryReserveError :: * ;
3
3
use std:: iter:: InPlaceIterable ;
4
4
use std:: mem:: size_of;
5
+ use std:: panic:: AssertUnwindSafe ;
6
+ use std:: rc:: Rc ;
5
7
use std:: vec:: { Drain , IntoIter } ;
6
8
use std:: { isize, usize} ;
7
9
@@ -777,6 +779,45 @@ fn test_from_iter_specialization_with_iterator_adapters() {
777
779
assert_eq ! ( srcptr, sinkptr) ;
778
780
}
779
781
782
+ #[ test]
783
+ fn test_from_iter_specialization_head_tail_drop ( ) {
784
+ let drop_count: Vec < _ > = ( 0 ..=2 ) . map ( |_| Rc :: new ( ( ) ) ) . collect ( ) ;
785
+ let src: Vec < _ > = drop_count. iter ( ) . cloned ( ) . collect ( ) ;
786
+ let srcptr = src. as_ptr ( ) ;
787
+ let iter = src. into_iter ( ) ;
788
+ let sink: Vec < _ > = iter. skip ( 1 ) . take ( 1 ) . collect ( ) ;
789
+ let sinkptr = sink. as_ptr ( ) ;
790
+ assert_eq ! ( srcptr, sinkptr, "specialization was applied" ) ;
791
+ assert_eq ! ( Rc :: strong_count( & drop_count[ 0 ] ) , 1 , "front was dropped" ) ;
792
+ assert_eq ! ( Rc :: strong_count( & drop_count[ 1 ] ) , 2 , "one element was collected" ) ;
793
+ assert_eq ! ( Rc :: strong_count( & drop_count[ 2 ] ) , 1 , "tail was dropped" ) ;
794
+ assert_eq ! ( sink. len( ) , 1 ) ;
795
+ }
796
+
797
+ #[ test]
798
+ fn test_from_iter_specialization_panic_drop ( ) {
799
+ let drop_count: Vec < _ > = ( 0 ..=2 ) . map ( |_| Rc :: new ( ( ) ) ) . collect ( ) ;
800
+ let src: Vec < _ > = drop_count. iter ( ) . cloned ( ) . collect ( ) ;
801
+ let iter = src. into_iter ( ) ;
802
+
803
+ let _ = std:: panic:: catch_unwind ( AssertUnwindSafe ( || {
804
+ let _ = iter
805
+ . enumerate ( )
806
+ . filter_map ( |( i, e) | {
807
+ if i == 1 {
808
+ std:: panic!( "aborting iteration" ) ;
809
+ }
810
+ Some ( e)
811
+ } )
812
+ . collect :: < Vec < _ > > ( ) ;
813
+ } ) ) ;
814
+
815
+ assert ! (
816
+ drop_count. iter( ) . map( Rc :: strong_count) . all( |count| count == 1 ) ,
817
+ "all items were dropped once"
818
+ ) ;
819
+ }
820
+
780
821
#[ test]
781
822
fn test_cow_from ( ) {
782
823
let borrowed: & [ _ ] = & [ "borrowed" , "(slice)" ] ;
0 commit comments