From 21c99d3ad9ca533a2c4fe2a6bff19b7f74fd07f5 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 29 Jan 2026 18:00:33 +1100 Subject: [PATCH 1/2] Fix some typos of "similarity" --- compiler/rustc_arena/src/lib.rs | 4 ++-- typos.toml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 5e81ec28ee35..cc18cf38ef4c 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -208,7 +208,7 @@ impl TypedArena { &self, iter: impl IntoIterator>, ) -> Result<&mut [T], E> { - // Despite the similarlty with `DroplessArena`, we cannot reuse their fast case. The reason + // Despite the similarity with `DroplessArena`, we cannot reuse their fast case. The reason // is subtle: these arenas are reentrant. In other words, `iter` may very well be holding a // reference to `self` and adding elements to the arena during iteration. // @@ -584,7 +584,7 @@ impl DroplessArena { &self, iter: impl IntoIterator>, ) -> Result<&mut [T], E> { - // Despite the similarlty with `alloc_from_iter`, we cannot reuse their fast case, as we + // Despite the similarity with `alloc_from_iter`, we cannot reuse their fast case, as we // cannot know the minimum length of the iterator in this case. assert!(size_of::() != 0); diff --git a/typos.toml b/typos.toml index 25083174cb8f..e486a7c1722c 100644 --- a/typos.toml +++ b/typos.toml @@ -46,6 +46,7 @@ unstalled = "unstalled" # short for un-stalled # # tidy-alphabetical-start definitinon = "definition" +similarlty = "similarity" # tidy-alphabetical-end [default.extend-identifiers] From 363d3ac4382e3f46a7472bed796aebc34f76deab Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 29 Jan 2026 18:05:40 +1100 Subject: [PATCH 2/2] Document a safety condition for `TypedArena::alloc_raw_slice` --- compiler/rustc_arena/src/lib.rs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index cc18cf38ef4c..524baf5b07fe 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -172,8 +172,22 @@ impl TypedArena { available_bytes >= additional_bytes } + /// Allocates storage for `len >= 1` values in this arena, and returns a + /// raw pointer to the first value's storage. + /// + /// # Safety + /// + /// Caller must initialize each of the `len` slots to a droppable value + /// before the arena is dropped. + /// + /// In practice, this typically means that the caller must be able to + /// raw-copy `len` already-initialized values into the slice without any + /// possibility of panicking. + /// + /// FIXME(Zalathar): This is *very* fragile; perhaps we need a different + /// approach to arena-allocating slices of droppable values. #[inline] - fn alloc_raw_slice(&self, len: usize) -> *mut T { + unsafe fn alloc_raw_slice(&self, len: usize) -> *mut T { assert!(size_of::() != 0); assert!(len != 0); @@ -229,9 +243,15 @@ impl TypedArena { } // Move the content to the arena by copying and then forgetting it. let len = vec.len(); - let start_ptr = self.alloc_raw_slice(len); + + // SAFETY: After allocating raw storage for exactly `len` values, we + // must fully initialize the storage without panicking, and we must + // also prevent the stale values in the vec from being dropped. Ok(unsafe { + let start_ptr = self.alloc_raw_slice(len); + // Initialize the newly-allocated storage without panicking. vec.as_ptr().copy_to_nonoverlapping(start_ptr, len); + // Prevent the stale values in the vec from being dropped. vec.set_len(0); slice::from_raw_parts_mut(start_ptr, len) })