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)]