From 837b550238aa671a591ccf282dddeab29cadb206 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 04:49:42 +0200 Subject: Merging upstream version 1.71.1+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_arena/src/lib.rs | 48 +++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 14 deletions(-) (limited to 'compiler/rustc_arena/src') diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 345e058e1..6e15f06a7 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -20,6 +20,7 @@ #![feature(rustc_attrs)] #![cfg_attr(test, feature(test))] #![feature(strict_provenance)] +#![deny(unsafe_op_in_unsafe_fn)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] #![allow(clippy::mut_from_ref)] // Arena allocators are one of the places where this pattern is fine. @@ -74,19 +75,27 @@ impl ArenaChunk { #[inline] unsafe fn new(capacity: usize) -> ArenaChunk { ArenaChunk { - storage: NonNull::new(Box::into_raw(Box::new_uninit_slice(capacity))).unwrap(), + storage: NonNull::from(Box::leak(Box::new_uninit_slice(capacity))), entries: 0, } } /// Destroys this arena chunk. + /// + /// # Safety + /// + /// The caller must ensure that `len` elements of this chunk have been initialized. #[inline] unsafe fn destroy(&mut self, len: usize) { // The branch on needs_drop() is an -O1 performance optimization. - // Without the branch, dropping TypedArena takes linear time. + // Without the branch, dropping TypedArena takes linear time. if mem::needs_drop::() { - let slice = &mut *(self.storage.as_mut()); - ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len])); + // SAFETY: The caller must ensure that `len` elements of this chunk have + // been initialized. + unsafe { + let slice = self.storage.as_mut(); + ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len])); + } } } @@ -104,7 +113,7 @@ impl ArenaChunk { // A pointer as large as possible for zero-sized elements. ptr::invalid_mut(!0) } else { - self.start().add((*self.storage.as_ptr()).len()) + self.start().add(self.storage.len()) } } } @@ -255,7 +264,9 @@ impl TypedArena { self.ensure_capacity(len); let start_ptr = self.ptr.get(); - self.ptr.set(start_ptr.add(len)); + // SAFETY: `self.ensure_capacity` makes sure that there is enough space + // for `len` elements. + unsafe { self.ptr.set(start_ptr.add(len)) }; start_ptr } @@ -288,7 +299,7 @@ impl TypedArena { // If the previous chunk's len is less than HUGE_PAGE // bytes, then this chunk will be least double the previous // chunk's size. - new_cap = (*last_chunk.storage.as_ptr()).len().min(HUGE_PAGE / elem_size / 2); + new_cap = last_chunk.storage.len().min(HUGE_PAGE / elem_size / 2); new_cap *= 2; } else { new_cap = PAGE / elem_size; @@ -396,7 +407,7 @@ impl DroplessArena { // If the previous chunk's len is less than HUGE_PAGE // bytes, then this chunk will be least double the previous // chunk's size. - new_cap = (*last_chunk.storage.as_ptr()).len().min(HUGE_PAGE / 2); + new_cap = last_chunk.storage.len().min(HUGE_PAGE / 2); new_cap *= 2; } else { new_cap = PAGE; @@ -483,6 +494,10 @@ impl DroplessArena { } } + /// # Safety + /// + /// The caller must ensure that `mem` is valid for writes up to + /// `size_of::() * len`. #[inline] unsafe fn write_from_iter>( &self, @@ -494,13 +509,18 @@ impl DroplessArena { // Use a manual loop since LLVM manages to optimize it better for // slice iterators loop { - let value = iter.next(); - if i >= len || value.is_none() { - // We only return as many items as the iterator gave us, even - // though it was supposed to give us `len` - return slice::from_raw_parts_mut(mem, i); + // SAFETY: The caller must ensure that `mem` is valid for writes up to + // `size_of::() * len`. + unsafe { + match iter.next() { + Some(value) if i < len => mem.add(i).write(value), + Some(_) | None => { + // We only return as many items as the iterator gave us, even + // though it was supposed to give us `len` + return slice::from_raw_parts_mut(mem, i); + } + } } - ptr::write(mem.add(i), value.unwrap()); i += 1; } } -- cgit v1.2.3