diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index f468bad635a9b..159cc83da055d 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -136,51 +136,39 @@ where impl IterExt for std::array::IntoIter { #[inline] fn alloc_from_iter(self, arena: &TypedArena) -> &mut [T] { - let len = self.len(); - if len == 0 { - return &mut []; - } - // Move the content to the arena by copying and then forgetting it - unsafe { - let start_ptr = arena.alloc_raw_slice(len); - self.as_slice().as_ptr().copy_to_nonoverlapping(start_ptr, len); - mem::forget(self); - slice::from_raw_parts_mut(start_ptr, len) - } + alloc_from_iter(arena, self.len(), self.as_slice().as_ptr(), || mem::forget(self)) } } impl IterExt for Vec { #[inline] fn alloc_from_iter(mut self, arena: &TypedArena) -> &mut [T] { - let len = self.len(); - if len == 0 { - return &mut []; - } - // Move the content to the arena by copying and then forgetting it - unsafe { - let start_ptr = arena.alloc_raw_slice(len); - self.as_ptr().copy_to_nonoverlapping(start_ptr, len); - self.set_len(0); - slice::from_raw_parts_mut(start_ptr, len) - } + alloc_from_iter(arena, self.len(), self.as_ptr(), || unsafe { self.set_len(0) }) } } impl IterExt for SmallVec { #[inline] fn alloc_from_iter(mut self, arena: &TypedArena) -> &mut [A::Item] { - let len = self.len(); - if len == 0 { - return &mut []; - } - // Move the content to the arena by copying and then forgetting it - unsafe { - let start_ptr = arena.alloc_raw_slice(len); - self.as_ptr().copy_to_nonoverlapping(start_ptr, len); - self.set_len(0); - slice::from_raw_parts_mut(start_ptr, len) - } + alloc_from_iter(arena, self.len(), self.as_ptr(), || unsafe { self.set_len(0) }) + } +} + +/// Reduce duplication for multiple specializations of alloc_from_iter. +#[inline] +fn alloc_from_iter(arena: &TypedArena, len: usize, ptr: *const T, clean: F) -> &mut [T] +where + F: FnOnce(), +{ + if len == 0 { + return &mut []; + } + // Move the content to the arena by copying and then forgetting it + unsafe { + let start_ptr = arena.alloc_raw_slice(len); + ptr.copy_to_nonoverlapping(start_ptr, len); + clean(); + slice::from_raw_parts_mut(start_ptr, len) } }