diff --git a/crates/oxc_allocator/src/clone_in.rs b/crates/oxc_allocator/src/clone_in.rs index bc21ed2501a21..0a191136b35bb 100644 --- a/crates/oxc_allocator/src/clone_in.rs +++ b/crates/oxc_allocator/src/clone_in.rs @@ -55,7 +55,7 @@ where } } -impl<'new_alloc, T, C> CloneIn<'new_alloc> for Vec<'_, T> +impl<'new_alloc, T, C: 'new_alloc> CloneIn<'new_alloc> for Vec<'_, T> where T: CloneIn<'new_alloc, Cloned = C>, { diff --git a/crates/oxc_allocator/src/string.rs b/crates/oxc_allocator/src/string.rs index bfe1a1e514100..02aa364ee66e3 100644 --- a/crates/oxc_allocator/src/string.rs +++ b/crates/oxc_allocator/src/string.rs @@ -106,14 +106,23 @@ impl<'alloc> String<'alloc> { // // `#[inline(always)]` because this is a no-op at runtime #[inline(always)] - pub unsafe fn from_utf8_unchecked(bytes: Vec<'alloc, u8>) -> String<'alloc> { + pub unsafe fn from_utf8_unchecked(mut bytes: Vec<'alloc, u8>) -> String<'alloc> { // Cannot use `bumpalo::String::from_utf8_unchecked` because it takes a `bumpalo::collections::Vec`, - // and our inner `Vec` type is `allocator_api2::vec::Vec`. + // and our inner `Vec` type is our own `crate::vec2::Vec`. + // // SAFETY: Conversion is safe because both types store data in arena in same way. // Lifetime of returned `String` is same as lifetime of original `Vec`. + // + // `into_raw_parts_with_alloc` consumed `bytes`, so it wasn't an issue before. + // But `as_mut_ptr` doesn't consume `bytes`, so if `Vec` was `Drop`, it'd get + // dropped at end of this function, which would free the memory which is now + // backing the `String`. Ditto if it was `InnerVec` which is (currently) `Drop`. + unsafe { - let inner = ManuallyDrop::into_inner(bytes.0); - let (ptr, len, capacity, bump) = inner.into_raw_parts_with_alloc(); + let ptr = bytes.as_mut_ptr(); + let len = bytes.len(); + let capacity = bytes.capacity(); + let bump = bytes.bump(); Self(ManuallyDrop::new(BumpaloString::from_raw_parts_in(ptr, len, capacity, bump))) } } diff --git a/crates/oxc_allocator/src/vec.rs b/crates/oxc_allocator/src/vec.rs index 65ffd636f459d..023300f094166 100644 --- a/crates/oxc_allocator/src/vec.rs +++ b/crates/oxc_allocator/src/vec.rs @@ -14,8 +14,7 @@ use std::{ slice::SliceIndex, }; -use allocator_api2::vec::Vec as InnerVec; -use bumpalo::Bump; +use crate::vec2::Vec as InnerVec; #[cfg(any(feature = "serialize", test))] use oxc_estree::{ESTree, Serializer as ESTreeSerializer}; #[cfg(any(feature = "serialize", test))] @@ -36,7 +35,7 @@ use crate::{Allocator, Box}; /// Static checks make this impossible to do. [`Vec::new_in`] and all other methods which create /// a [`Vec`] will refuse to compile if called with a [`Drop`] type. #[derive(PartialEq, Eq)] -pub struct Vec<'alloc, T>(pub(crate) ManuallyDrop>); +pub struct Vec<'alloc, T>(pub(crate) ManuallyDrop>); /// SAFETY: Not actually safe, but for enabling `Send` for downstream crates. unsafe impl Send for Vec<'_, T> {} @@ -169,7 +168,7 @@ impl<'alloc, T> Vec<'alloc, T> { } impl<'alloc, T> ops::Deref for Vec<'alloc, T> { - type Target = InnerVec; + type Target = InnerVec<'alloc, T>; #[inline] fn deref(&self) -> &Self::Target { @@ -179,13 +178,13 @@ impl<'alloc, T> ops::Deref for Vec<'alloc, T> { impl<'alloc, T> ops::DerefMut for Vec<'alloc, T> { #[inline] - fn deref_mut(&mut self) -> &mut InnerVec { + fn deref_mut(&mut self) -> &mut InnerVec<'alloc, T> { &mut self.0 } } impl<'alloc, T> IntoIterator for Vec<'alloc, T> { - type IntoIter = as IntoIterator>::IntoIter; + type IntoIter = as IntoIterator>::IntoIter; type Item = T; #[inline(always)] diff --git a/crates/oxc_allocator/src/vec2/mod.rs b/crates/oxc_allocator/src/vec2/mod.rs index 56f50318e99fa..dc5f0feea7734 100644 --- a/crates/oxc_allocator/src/vec2/mod.rs +++ b/crates/oxc_allocator/src/vec2/mod.rs @@ -870,7 +870,6 @@ impl<'bump, T: 'bump> Vec<'bump, T> { unsafe { let ptr = self.as_ptr(); let len = self.len(); - mem::forget(self); slice::from_raw_parts(ptr, len) } } @@ -895,7 +894,6 @@ impl<'bump, T: 'bump> Vec<'bump, T> { pub fn into_bump_slice_mut(mut self) -> &'bump mut [T] { let ptr = self.as_mut_ptr(); let len = self.len(); - mem::forget(self); unsafe { slice::from_raw_parts_mut(ptr, len) } } @@ -2244,7 +2242,6 @@ impl<'bump, T: 'bump> IntoIterator for Vec<'bump, T> { } else { begin.add(self.len()) as *const T }; - mem::forget(self); IntoIter { phantom: PhantomData, ptr: begin, end } } } @@ -2453,18 +2450,6 @@ impl<'bump, T: 'bump> BorrowMut<[T]> for Vec<'bump, T> { } } -impl<'bump, T> Drop for Vec<'bump, T> { - fn drop(&mut self) { - unsafe { - // use drop for [T] - // use a raw slice to refer to the elements of the vector as weakest necessary type; - // could avoid questions of validity in certain cases - ptr::drop_in_place(ptr::slice_from_raw_parts_mut(self.as_mut_ptr(), self.len)) - } - // RawVec handles deallocation - } -} - //////////////////////////////////////////////////////////////////////////////// // Clone-on-write //////////////////////////////////////////////////////////////////////////////// diff --git a/crates/oxc_allocator/src/vec2/raw_vec.rs b/crates/oxc_allocator/src/vec2/raw_vec.rs index b232791391db5..d272a82c779b6 100644 --- a/crates/oxc_allocator/src/vec2/raw_vec.rs +++ b/crates/oxc_allocator/src/vec2/raw_vec.rs @@ -702,15 +702,6 @@ impl<'a, T> RawVec<'a, T> { } } -impl<'a, T> Drop for RawVec<'a, T> { - /// Frees the memory owned by the RawVec *without* trying to Drop its contents. - fn drop(&mut self) { - unsafe { - self.dealloc_buffer(); - } - } -} - // We need to guarantee the following: // * We don't ever allocate `> isize::MAX` byte-size objects // * We don't overflow `usize::MAX` and actually allocate too little