From 13eb8adefd937080f3772a2baf290e85879a3b24 Mon Sep 17 00:00:00 2001 From: soruh Date: Fri, 31 Jul 2026 02:12:42 +0200 Subject: [PATCH] Preserve erased vector on conversion failure --- src/lib.rs | 6 +++--- src/tests.rs | 17 +++++++++++------ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 44cc16a..82fbaac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -153,9 +153,9 @@ impl TypeErasedVec { /// /// # Errors /// Returns the original `TypeErasedVec` if `T` does not have the same `Layout`. - pub fn try_into_vec(mut self) -> Result, Self> { - if let Some(mut guard) = self.try_as_type::() { - Ok(guard.take()) + pub fn try_into_vec(self) -> Result, Self> { + if self.layout == Layout::new::() { + Ok(self.into_vec()) } else { Err(self) } diff --git a/src/tests.rs b/src/tests.rs index 7bbaf2a..0a46970 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -352,23 +352,28 @@ fn test_conversion_methods() { #[test] fn test_try_into_vec_failure_and_recovery() { - let vec = Vec::::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::() 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::()); + assert_erased_state(&recovered_erased, 1, Layout::new::()); assert!(recovered_erased.capacity() >= initial_cap); + assert_eq!(drop_count.get(), 0); - let Ok(restored) = recovered_erased.try_into_vec::() 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::() }; + assert_eq!(restored.len(), 1); assert!(restored.capacity() >= initial_cap); + drop(restored); + assert_eq!(drop_count.get(), 1); } #[test]