diff options
| author | Laurențiu Nicola <lnicola@users.noreply.github.com> | 2024-12-04 03:44:01 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-04 03:44:01 +0000 |
| commit | 01870ba9d7da99e7e4e6bedc7a67e5dc7d811bd5 (patch) | |
| tree | 0ee8ece6b63b6d48790416186d9ee19d0c479f76 /src | |
| parent | fef7ca07bfd5a75da9716a861707fa8abe95fa5f (diff) | |
| parent | 0d328a81ec0543ffbe63906f0e0b88bb2179ecc2 (diff) | |
| download | rust-01870ba9d7da99e7e4e6bedc7a67e5dc7d811bd5.tar.gz rust-01870ba9d7da99e7e4e6bedc7a67e5dc7d811bd5.zip | |
Merge pull request #18606 from ChayimFriedman2/improve-soundness-just-a-bit
minor: Improve soundness a bit by making `TaggedArcPtr::try_as_arc_owned()` unsafe
Diffstat (limited to 'src')
| -rw-r--r-- | src/tools/rust-analyzer/crates/intern/src/symbol.rs | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol.rs b/src/tools/rust-analyzer/crates/intern/src/symbol.rs index ef76192ba83..200b14027f8 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol.rs @@ -77,8 +77,12 @@ impl TaggedArcPtr { } /// Retrieves the tag. + /// + /// # Safety + /// + /// You can only drop the `Arc` if the instance is dropped. #[inline] - pub(crate) fn try_as_arc_owned(self) -> Option<ManuallyDrop<Arc<Box<str>>>> { + pub(crate) unsafe fn try_as_arc_owned(self) -> Option<ManuallyDrop<Arc<Box<str>>>> { // Unpack the tag from the alignment niche let tag = Strict::addr(self.packed.as_ptr()) & Self::BOOL_BITS; if tag != 0 { @@ -245,16 +249,14 @@ impl Symbol { } } - ManuallyDrop::into_inner( - match shard.raw_entry_mut().from_key_hashed_nocheck::<str>(hash, arc.as_ref()) { - RawEntryMut::Occupied(occ) => occ.remove_entry(), - RawEntryMut::Vacant(_) => unreachable!(), - } - .0 - .0 - .try_as_arc_owned() - .unwrap(), - ); + let ptr = match shard.raw_entry_mut().from_key_hashed_nocheck::<str>(hash, arc.as_ref()) { + RawEntryMut::Occupied(occ) => occ.remove_entry(), + RawEntryMut::Vacant(_) => unreachable!(), + } + .0 + .0; + // SAFETY: We're dropping, we have ownership. + ManuallyDrop::into_inner(unsafe { ptr.try_as_arc_owned().unwrap() }); debug_assert_eq!(Arc::count(arc), 1); // Shrink the backing storage if the shard is less than 50% occupied. @@ -267,7 +269,8 @@ impl Symbol { impl Drop for Symbol { #[inline] fn drop(&mut self) { - let Some(arc) = self.repr.try_as_arc_owned() else { + // SAFETY: We're dropping, we have ownership. + let Some(arc) = (unsafe { self.repr.try_as_arc_owned() }) else { return; }; // When the last `Ref` is dropped, remove the object from the global map. @@ -288,7 +291,8 @@ impl Clone for Symbol { } fn increase_arc_refcount(repr: TaggedArcPtr) -> TaggedArcPtr { - let Some(arc) = repr.try_as_arc_owned() else { + // SAFETY: We're not dropping the `Arc`. + let Some(arc) = (unsafe { repr.try_as_arc_owned() }) else { return repr; }; // increase the ref count |
