Preserve erased vector on conversion failure
This commit is contained in:
+3
-3
@@ -153,9 +153,9 @@ impl TypeErasedVec {
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns the original `TypeErasedVec` if `T` does not have the same `Layout`.
|
||||
pub fn try_into_vec<T>(mut self) -> Result<Vec<T>, Self> {
|
||||
if let Some(mut guard) = self.try_as_type::<T>() {
|
||||
Ok(guard.take())
|
||||
pub fn try_into_vec<T>(self) -> Result<Vec<T>, Self> {
|
||||
if self.layout == Layout::new::<T>() {
|
||||
Ok(self.into_vec())
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
|
||||
+11
-6
@@ -352,23 +352,28 @@ fn test_conversion_methods() {
|
||||
|
||||
#[test]
|
||||
fn test_try_into_vec_failure_and_recovery() {
|
||||
let vec = Vec::<u32>::with_capacity(5);
|
||||
let drop_count = Rc::new(Cell::new(0));
|
||||
let mut vec = Vec::with_capacity(5);
|
||||
vec.push(DropTracker::new(drop_count.clone()));
|
||||
let initial_cap = vec.capacity();
|
||||
|
||||
let erased = TypeErasedVec::new(vec);
|
||||
|
||||
let Err(recovered_erased) = erased.try_into_vec::<u64>() else {
|
||||
let Err(recovered_erased) = erased.try_into_vec::<()>() else {
|
||||
panic!("try_into_vec succeeded with mismatched layout");
|
||||
};
|
||||
|
||||
assert_erased_state(&recovered_erased, 0, Layout::new::<u32>());
|
||||
assert_erased_state(&recovered_erased, 1, Layout::new::<DropTracker>());
|
||||
assert!(recovered_erased.capacity() >= initial_cap);
|
||||
assert_eq!(drop_count.get(), 0);
|
||||
|
||||
let Ok(restored) = recovered_erased.try_into_vec::<u32>() else {
|
||||
panic!("try_into_vec failed after recovery");
|
||||
};
|
||||
// SAFETY: The failed conversion preserved the original `DropTracker` elements.
|
||||
let restored = unsafe { recovered_erased.cast_into_vec::<DropTracker>() };
|
||||
|
||||
assert_eq!(restored.len(), 1);
|
||||
assert!(restored.capacity() >= initial_cap);
|
||||
drop(restored);
|
||||
assert_eq!(drop_count.get(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user