Preserve erased vector on conversion failure

This commit is contained in:
2026-07-31 02:12:42 +02:00
parent 5b0d2cab9d
commit 13eb8adefd
2 changed files with 14 additions and 9 deletions
+3 -3
View File
@@ -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
View File
@@ -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]