@@ -4,6 +4,7 @@ use std::fmt::Debug;
4
4
use std:: iter:: InPlaceIterable ;
5
5
use std:: mem:: size_of;
6
6
use std:: panic:: { catch_unwind, AssertUnwindSafe } ;
7
+ use std:: rc:: Rc ;
7
8
use std:: vec:: { Drain , IntoIter } ;
8
9
9
10
struct DropCounter < ' a > {
@@ -826,6 +827,45 @@ fn test_from_iter_specialization_with_iterator_adapters() {
826
827
assert_eq ! ( srcptr, sinkptr) ;
827
828
}
828
829
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
+
829
869
#[ test]
830
870
fn test_cow_from ( ) {
831
871
let borrowed: & [ _ ] = & [ "borrowed" , "(slice)" ] ;
0 commit comments