From 25a66297426965f12f8adf4ae7e105dbe2ef1faa Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Wed, 18 May 2022 10:37:51 +0900 Subject: [PATCH] Add unsafe comments --- vm/src/dictdatatype.rs | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/vm/src/dictdatatype.rs b/vm/src/dictdatatype.rs index 179db0d6d..487207e88 100644 --- a/vm/src/dictdatatype.rs +++ b/vm/src/dictdatatype.rs @@ -45,6 +45,8 @@ impl IndexEntry { const FREE: Self = Self(-1); const DUMMY: Self = Self(-2); + /// # Safety + /// idx must not be one of FREE or DUMMY unsafe fn from_index_unchecked(idx: usize) -> Self { debug_assert!((idx as isize) >= 0); Self(idx as i64) @@ -164,7 +166,9 @@ impl DictInner { loop { let index_index = idxs.next(); unsafe { - // index is always valid here + // Safety: index is always valid here + // index_index is generated by idxs + // entry_idx is saved one let idx = self.indices.get_unchecked_mut(index_index); if *idx == IndexEntry::FREE { *idx = IndexEntry::from_index_unchecked(entry_idx); @@ -196,7 +200,11 @@ impl DictInner { }; let entry_index = self.entries.len(); self.entries.push(Some(entry)); - self.indices[index] = unsafe { IndexEntry::from_index_unchecked(entry_index) }; + self.indices[index] = unsafe { + // SAFETY: entry_index is self.entries.len(). it never can + // grow to `usize-2` because hash tables cannot full its index + IndexEntry::from_index_unchecked(entry_index) + }; self.used += 1; if let IndexEntry::FREE = index_entry { self.filled += 1; @@ -540,7 +548,10 @@ impl Dict { }); loop { let index_index = idxs.next(); - let index_entry = *unsafe { inner.indices.get_unchecked(index_index) }; + let index_entry = *unsafe { + // Safety: index_index is generated + inner.indices.get_unchecked(index_index) + }; match index_entry { IndexEntry::DUMMY => { if free_slot.is_none() { @@ -556,7 +567,7 @@ impl Dict { } idx => { let entry = unsafe { - // DUMMY and FREE are already handled above. + // Safety: DUMMY and FREE are already handled above. // i is always valid and entry always exists. let i = idx.index().unwrap_unchecked(); inner.entries.get_unchecked(i).as_ref().unwrap_unchecked() @@ -619,7 +630,10 @@ impl Dict { // The dict was changed since we did lookup. Let's try again. _ => return Ok(ControlFlow::Continue(())), } - *unsafe { inner.indices.get_unchecked_mut(index_index) } = IndexEntry::DUMMY; + *unsafe { + // index_index is result of lookup + inner.indices.get_unchecked_mut(index_index) + } = IndexEntry::DUMMY; inner.used -= 1; let removed = slot.take(); Ok(ControlFlow::Break(removed)) @@ -647,7 +661,10 @@ impl Dict { } }; inner.used -= 1; - *unsafe { inner.indices.get_unchecked_mut(entry.index) } = IndexEntry::DUMMY; + *unsafe { + // entry.index always refers valid index + inner.indices.get_unchecked_mut(entry.index) + } = IndexEntry::DUMMY; Some((entry.key, entry.value)) }