+2
-0
@@ -6,2 +6,3 @@ language: rust | ||
| - rust: stable | ||
| - rust: beta | ||
| - rust: nightly | ||
@@ -15,2 +16,3 @@ - rust: nightly | ||
| [ -z "$NODROP_FEATURES" ] && cargo test --verbose --features "$FEATURES" | ||
| [ -z "$NODROP_FEATURES" ] && cargo test --release --verbose --features "$FEATURES" | ||
| [ -z "$NODROP_FEATURES" ] && cargo bench --verbose --features "$FEATURES" -- --test | ||
@@ -17,0 +19,0 @@ [ -z "$NODROP_FEATURES" ] && cargo doc --verbose --features "$FEATURES" |
+4
-4
| [package] | ||
| name = "arrayvec" | ||
| version = "0.3.9" | ||
| version = "0.3.10" | ||
| authors = ["bluss"] | ||
@@ -16,4 +16,4 @@ license = "MIT/Apache-2.0" | ||
| [dev-dependencies] | ||
| nodrop = "0.1" | ||
| [dependencies.nodrop] | ||
| version = "0.1.4" | ||
| path = "nodrop" |
+0
-1
@@ -25,3 +25,2 @@ DOCCRATES = arrayvec nodrop odds | ||
| cargo doc --features=$(FEATURES) | ||
| cargo doc -p nodrop | ||
| rm -rf ./doc | ||
@@ -28,0 +27,0 @@ cp -r ./target/doc ./doc |
+4
-0
@@ -25,2 +25,6 @@ | ||
| - 0.3.10 | ||
| - Go back to using external NoDrop, fixing a panic safety bug (issue #3) | ||
| - 0.3.8 | ||
@@ -27,0 +31,0 @@ |
+20
-43
| extern crate odds; | ||
| extern crate nodrop; | ||
@@ -12,2 +13,4 @@ use std::iter; | ||
| use nodrop::NoDrop; | ||
| // extra traits | ||
@@ -18,4 +21,2 @@ use std::borrow::{Borrow, BorrowMut}; | ||
| use odds::debug_assert_unreachable; | ||
| mod array; | ||
@@ -35,9 +36,2 @@ pub use array::Array; | ||
| /// repr(u8) - Make sure the non-nullable pointer optimization does not occur! | ||
| #[repr(u8)] | ||
| enum NoDrop<T> { | ||
| Alive(T), | ||
| Dropped, | ||
| } | ||
| /// A vector with a fixed capacity. | ||
@@ -63,8 +57,8 @@ /// | ||
| // clear all elements | ||
| while let Some(_) = self.pop() { } | ||
| while let Some(_) = self.pop() { | ||
| } | ||
| // inhibit drop | ||
| unsafe { | ||
| ptr::write(&mut self.xs, NoDrop::Dropped); | ||
| } | ||
| // NoDrop inhibits array's drop | ||
| // panic safety: NoDrop::drop will trigger on panic, so the inner | ||
| // array will not drop even after panic. | ||
| } | ||
@@ -91,3 +85,3 @@ } | ||
| unsafe { | ||
| ArrayVec { xs: NoDrop::Alive(new_array()), len: Index::zero() } | ||
| ArrayVec { xs: NoDrop::new(new_array()), len: Index::zero() } | ||
| } | ||
@@ -383,27 +377,2 @@ } | ||
| impl<T> Deref for NoDrop<T> { | ||
| type Target = T; | ||
| // Use type invariant, always Alive. | ||
| #[inline] | ||
| fn deref(&self) -> &T { | ||
| match *self { | ||
| NoDrop::Alive(ref inner) => inner, | ||
| _ => unsafe { debug_assert_unreachable() } | ||
| } | ||
| } | ||
| } | ||
| impl<T> DerefMut for NoDrop<T> { | ||
| // Use type invariant, always Alive. | ||
| #[inline] | ||
| fn deref_mut(&mut self) -> &mut T { | ||
| match *self { | ||
| NoDrop::Alive(ref mut inner) => inner, | ||
| _ => unsafe { debug_assert_unreachable() } | ||
| } | ||
| } | ||
| } | ||
| /// Create an **ArrayVec** from an array. | ||
@@ -421,3 +390,3 @@ /// | ||
| fn from(array: A) -> Self { | ||
| ArrayVec { xs: NoDrop::Alive(array), len: Index::from(A::capacity()) } | ||
| ArrayVec { xs: NoDrop::new(array), len: Index::from(A::capacity()) } | ||
| } | ||
@@ -534,6 +503,12 @@ } | ||
| fn drop(&mut self) { | ||
| // exhaust iterator and clear the vector | ||
| while let Some(_) = self.next() { } | ||
| // panic safety: Set length to 0 before dropping elements. | ||
| let index = self.index.to_usize(); | ||
| let len = self.v.len(); | ||
| unsafe { | ||
| self.v.set_len(0); | ||
| let elements = slice::from_raw_parts(self.v.get_unchecked_mut(index), | ||
| len - index); | ||
| for elt in elements { | ||
| ptr::read(elt); | ||
| } | ||
| } | ||
@@ -599,2 +574,4 @@ } | ||
| fn drop(&mut self) { | ||
| // len is currently 0 so panicking while dropping will not cause a double drop. | ||
| // exhaust self first | ||
@@ -601,0 +578,0 @@ while let Some(_) = self.next() { } |
+33
-2
@@ -133,3 +133,3 @@ extern crate arrayvec; | ||
| println!("{}", mem::size_of::<ByteArray>()); | ||
| assert!(mem::size_of::<ByteArray>() <= 7); | ||
| assert!(mem::size_of::<ByteArray>() <= 8); | ||
@@ -139,3 +139,3 @@ // 12 element size + 1 enum tag + 3 padding + 1 len + 1 drop flag + 2 padding | ||
| println!("{}", mem::size_of::<QuadArray>()); | ||
| assert!(mem::size_of::<QuadArray>() <= 20); | ||
| assert!(mem::size_of::<QuadArray>() <= 24); | ||
| } | ||
@@ -169,2 +169,33 @@ | ||
| #[test] | ||
| #[should_panic] | ||
| fn test_drop_panic() { | ||
| struct DropPanic; | ||
| impl Drop for DropPanic { | ||
| fn drop(&mut self) { | ||
| panic!("drop"); | ||
| } | ||
| } | ||
| let mut array = ArrayVec::<[DropPanic; 1]>::new(); | ||
| array.push(DropPanic); | ||
| } | ||
| #[test] | ||
| #[should_panic] | ||
| fn test_drop_panic_into_iter() { | ||
| struct DropPanic; | ||
| impl Drop for DropPanic { | ||
| fn drop(&mut self) { | ||
| panic!("drop"); | ||
| } | ||
| } | ||
| let mut array = ArrayVec::<[DropPanic; 1]>::new(); | ||
| array.push(DropPanic); | ||
| array.into_iter(); | ||
| } | ||
| #[test] | ||
| fn test_insert() { | ||
@@ -171,0 +202,0 @@ let mut v = ArrayVec::from([]); |