diff options
| author | Jonas Schievink <jonasschievink@gmail.com> | 2019-12-13 17:54:26 +0100 |
|---|---|---|
| committer | Jonas Schievink <jonasschievink@gmail.com> | 2020-01-19 20:23:41 +0100 |
| commit | 5d04790dd2e73f3faf08d528e3675e131585ec01 (patch) | |
| tree | 5aa4271596ae881762bf2d636979512a622a9b9a /src/liballoc/tests | |
| parent | 3e5eb2634cbb356b626e028a4be1305d4a44a023 (diff) | |
| download | rust-5d04790dd2e73f3faf08d528e3675e131585ec01.tar.gz rust-5d04790dd2e73f3faf08d528e3675e131585ec01.zip | |
Avoid leak in `vec::Drain` when item drop panics
Diffstat (limited to 'src/liballoc/tests')
| -rw-r--r-- | src/liballoc/tests/vec.rs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 2a9bfefc713..80acba0a3a1 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -1,6 +1,7 @@ use std::borrow::Cow; use std::collections::TryReserveError::*; use std::mem::size_of; +use std::panic::{catch_unwind, AssertUnwindSafe}; use std::vec::{Drain, IntoIter}; use std::{isize, usize}; @@ -586,6 +587,44 @@ fn test_drain_inclusive_out_of_bounds() { } #[test] +fn test_drain_leak() { + static mut DROPS: i32 = 0; + + #[derive(Debug, PartialEq)] + struct D(u32, bool); + + impl Drop for D { + fn drop(&mut self) { + unsafe { + DROPS += 1; + } + + if self.1 { + panic!("panic in `drop`"); + } + } + } + + let mut v = vec![ + D(0, false), + D(1, false), + D(2, false), + D(3, false), + D(4, true), + D(5, false), + D(6, false), + ]; + + catch_unwind(AssertUnwindSafe(|| { + v.drain(2..=5); + })) + .ok(); + + assert_eq!(unsafe { DROPS }, 4); + assert_eq!(v, vec![D(0, false), D(1, false), D(6, false),]); +} + +#[test] fn test_splice() { let mut v = vec![1, 2, 3, 4, 5]; let a = [10, 11, 12]; |
