From 7f641c97d8df6120ea248e7fdf6e2200f8b9d7c9 Mon Sep 17 00:00:00 2001 From: Dunqing Date: Fri, 13 Dec 2024 23:32:05 +0800 Subject: [PATCH] feat(ast): add AstBuilder::vec_convert --- crates/oxc_ast/src/ast_builder_impl.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/crates/oxc_ast/src/ast_builder_impl.rs b/crates/oxc_ast/src/ast_builder_impl.rs index 8cbefde5f77a5..70b94627f9147 100644 --- a/crates/oxc_ast/src/ast_builder_impl.rs +++ b/crates/oxc_ast/src/ast_builder_impl.rs @@ -75,6 +75,26 @@ impl<'a> AstBuilder<'a> { Vec::from_array_in(array, self.allocator) } + /// Convert a [`Vec`] of one type to a [`Vec`] of another type. + /// + /// This method is useful where the `Src` is inherited from `Dst` or vice versa, so that you can it + /// without any runtime overhead. For example, you can convert a `Vec<'a, Expression>` to a + /// `Vec<'a, Argument>` + #[inline] + pub fn vec_convert(&self, vec: Vec<'a, Src>) -> Vec<'a, Dst> + where + Src: 'a, + Dst: 'a, + { + // Verify types are layout-compatible + debug_assert!(std::mem::size_of::() == std::mem::size_of::()); + debug_assert!(std::mem::align_of::() == std::mem::align_of::()); + + // SAFETY: Vec and Vec have the same layout when Src and Dst have + // the same size and alignment. The lifetimes and allocator remain the same. + unsafe { std::mem::transmute(vec) } + } + /// Move a string slice into the memory arena, returning a reference to the slice /// in the heap. #[inline]