Skip to content

Commit 470bf54

Browse files
committed
test drops during in-place iteration
1 parent fe350dd commit 470bf54

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

library/alloc/tests/vec.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::fmt::Debug;
44
use std::iter::InPlaceIterable;
55
use std::mem::size_of;
66
use std::panic::{catch_unwind, AssertUnwindSafe};
7+
use std::rc::Rc;
78
use std::vec::{Drain, IntoIter};
89

910
struct 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]
830870
fn test_cow_from() {
831871
let borrowed: &[_] = &["borrowed", "(slice)"];

0 commit comments

Comments
 (0)