VecDeque: drop remaining items on destructor panic
This commit is contained in:
parent
90b957a17c
commit
189ccf20a2
@ -144,11 +144,21 @@ fn clone_from(&mut self, other: &Self) {
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
unsafe impl<#[may_dangle] T> Drop for VecDeque<T> {
|
unsafe impl<#[may_dangle] T> Drop for VecDeque<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
struct Dropper<'a, T>(&'a mut [T]);
|
||||||
|
|
||||||
|
impl<'a, T> Drop for Dropper<'a, T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
ptr::drop_in_place(self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let (front, back) = self.as_mut_slices();
|
let (front, back) = self.as_mut_slices();
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let _back_dropper = Dropper(back);
|
||||||
// use drop for [T]
|
// use drop for [T]
|
||||||
ptr::drop_in_place(front);
|
ptr::drop_in_place(front);
|
||||||
ptr::drop_in_place(back);
|
|
||||||
}
|
}
|
||||||
// RawVec handles deallocation
|
// RawVec handles deallocation
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
use std::collections::{vec_deque::Drain, VecDeque};
|
use std::collections::{vec_deque::Drain, VecDeque};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
|
use std::panic::catch_unwind;
|
||||||
use std::{isize, usize};
|
use std::{isize, usize};
|
||||||
|
|
||||||
use crate::hash;
|
use crate::hash;
|
||||||
@ -709,6 +710,39 @@ fn drop(&mut self) {
|
|||||||
assert_eq!(unsafe { DROPS }, 4);
|
assert_eq!(unsafe { DROPS }, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_drop_panic() {
|
||||||
|
static mut DROPS: i32 = 0;
|
||||||
|
|
||||||
|
struct D(bool);
|
||||||
|
|
||||||
|
impl Drop for D {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
DROPS += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.0 {
|
||||||
|
panic!("panic in `drop`");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut q = VecDeque::new();
|
||||||
|
q.push_back(D(false));
|
||||||
|
q.push_back(D(false));
|
||||||
|
q.push_back(D(false));
|
||||||
|
q.push_back(D(false));
|
||||||
|
q.push_back(D(false));
|
||||||
|
q.push_front(D(false));
|
||||||
|
q.push_front(D(false));
|
||||||
|
q.push_front(D(true));
|
||||||
|
|
||||||
|
catch_unwind(move || drop(q)).ok();
|
||||||
|
|
||||||
|
assert_eq!(unsafe { DROPS }, 8);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_reserve_grow() {
|
fn test_reserve_grow() {
|
||||||
// test growth path A
|
// test growth path A
|
||||||
|
Loading…
Reference in New Issue
Block a user