@@ -4,6 +4,7 @@ use std::fmt::Debug;
44use std:: iter:: InPlaceIterable ;
55use std:: mem:: size_of;
66use std:: panic:: { catch_unwind, AssertUnwindSafe } ;
7+ use std:: rc:: Rc ;
78use std:: vec:: { Drain , IntoIter } ;
89
910struct DropCounter < ' a > {
@@ -826,6 +827,45 @@ fn test_from_iter_specialization_with_iterator_adapters() {
826827 assert_eq ! ( srcptr, sinkptr) ;
827828}
828829
830+ #[ test]
831+ fn test_from_iter_specialization_head_tail_drop ( ) {
832+ let drop_count: Vec < _ > = ( 0 ..=2 ) . map ( |_| Rc :: new ( ( ) ) ) . collect ( ) ;
833+ let src: Vec < _ > = drop_count. iter ( ) . cloned ( ) . collect ( ) ;
834+ let srcptr = src. as_ptr ( ) ;
835+ let iter = src. into_iter ( ) ;
836+ let sink: Vec < _ > = iter. skip ( 1 ) . take ( 1 ) . collect ( ) ;
837+ let sinkptr = sink. as_ptr ( ) ;
838+ assert_eq ! ( srcptr, sinkptr, "specialization was applied" ) ;
839+ assert_eq ! ( Rc :: strong_count( & drop_count[ 0 ] ) , 1 , "front was dropped" ) ;
840+ assert_eq ! ( Rc :: strong_count( & drop_count[ 1 ] ) , 2 , "one element was collected" ) ;
841+ assert_eq ! ( Rc :: strong_count( & drop_count[ 2 ] ) , 1 , "tail was dropped" ) ;
842+ assert_eq ! ( sink. len( ) , 1 ) ;
843+ }
844+
845+ #[ test]
846+ fn test_from_iter_specialization_panic_drop ( ) {
847+ let drop_count: Vec < _ > = ( 0 ..=2 ) . map ( |_| Rc :: new ( ( ) ) ) . collect ( ) ;
848+ let src: Vec < _ > = drop_count. iter ( ) . cloned ( ) . collect ( ) ;
849+ let iter = src. into_iter ( ) ;
850+
851+ let _ = std:: panic:: catch_unwind ( AssertUnwindSafe ( || {
852+ let _ = iter
853+ . enumerate ( )
854+ . filter_map ( |( i, e) | {
855+ if i == 1 {
856+ std:: panic!( "aborting iteration" ) ;
857+ }
858+ Some ( e)
859+ } )
860+ . collect :: < Vec < _ > > ( ) ;
861+ } ) ) ;
862+
863+ assert ! (
864+ drop_count. iter( ) . map( Rc :: strong_count) . all( |count| count == 1 ) ,
865+ "all items were dropped once"
866+ ) ;
867+ }
868+
829869#[ test]
830870fn test_cow_from ( ) {
831871 let borrowed: & [ _ ] = & [ "borrowed" , "(slice)" ] ;
0 commit comments