@@ -2,6 +2,8 @@ use std::borrow::Cow;
22use std:: collections:: TryReserveError :: * ;
33use std:: iter:: InPlaceIterable ;
44use std:: mem:: size_of;
5+ use std:: panic:: AssertUnwindSafe ;
6+ use std:: rc:: Rc ;
57use std:: vec:: { Drain , IntoIter } ;
68use std:: { isize, usize} ;
79
@@ -777,6 +779,45 @@ fn test_from_iter_specialization_with_iterator_adapters() {
777779 assert_eq ! ( srcptr, sinkptr) ;
778780}
779781
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+
780821#[ test]
781822fn test_cow_from ( ) {
782823 let borrowed: & [ _ ] = & [ "borrowed" , "(slice)" ] ;
0 commit comments