mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 16:21:33 +11:00
Add safety comments
This commit is contained in:
parent
35061ffb6a
commit
722deafc2f
|
@ -15,6 +15,8 @@
|
||||||
#![deny(rustdoc::private_intra_doc_links)]
|
#![deny(rustdoc::private_intra_doc_links)]
|
||||||
#![deny(rustdoc::invalid_html_tags)]
|
#![deny(rustdoc::invalid_html_tags)]
|
||||||
#![deny(unreachable_pub)]
|
#![deny(unreachable_pub)]
|
||||||
|
#![deny(clippy::missing_safety_doc)]
|
||||||
|
#![deny(clippy::undocumented_unsafe_blocks)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
@ -352,11 +354,14 @@ where
|
||||||
let hash = self.hash(key);
|
let hash = self.hash(key);
|
||||||
|
|
||||||
let location = self.nodes.location(key, hash)?;
|
let location = self.nodes.location(key, hash)?;
|
||||||
Some(unsafe {
|
Some(
|
||||||
self.nodes
|
// SAFETY: we know that a node exists and has a value from the location call above
|
||||||
.node_at_unchecked(location)
|
unsafe {
|
||||||
.key_value_ref_unchecked()
|
self.nodes
|
||||||
})
|
.node_at_unchecked(location)
|
||||||
|
.key_value_ref_unchecked()
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the value corresponding to the key. Returns [`None`] if there is
|
/// Returns a reference to the value corresponding to the key. Returns [`None`] if there is
|
||||||
|
@ -403,11 +408,14 @@ where
|
||||||
let hash = self.hash(key);
|
let hash = self.hash(key);
|
||||||
|
|
||||||
let location = self.nodes.location(key, hash)?;
|
let location = self.nodes.location(key, hash)?;
|
||||||
Some(unsafe {
|
Some(
|
||||||
self.nodes
|
// SAFETY: we know that a node exists and has a value from the location call above
|
||||||
.node_at_unchecked_mut(location)
|
unsafe {
|
||||||
.value_mut_unchecked()
|
self.nodes
|
||||||
})
|
.node_at_unchecked_mut(location)
|
||||||
|
.value_mut_unchecked()
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes the given key from the map. Returns the current value if it existed, or [`None`]
|
/// Removes the given key from the map. Returns the current value if it existed, or [`None`]
|
||||||
|
@ -561,6 +569,15 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a, ALLOCATOR: Allocator> {
|
||||||
location: usize,
|
location: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, K: 'a, V: 'a, ALLOCATOR: Allocator> OccupiedEntry<'a, K, V, ALLOCATOR> {
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// You must call this with a valid location (one where the entry is defined)
|
||||||
|
unsafe fn new(key: K, map: &'a mut HashMap<K, V, ALLOCATOR>, location: usize) -> Self {
|
||||||
|
Self { key, map, location }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, K: 'a, V: 'a, ALLOCATOR: ClonableAllocator> OccupiedEntry<'a, K, V, ALLOCATOR> {
|
impl<'a, K: 'a, V: 'a, ALLOCATOR: ClonableAllocator> OccupiedEntry<'a, K, V, ALLOCATOR> {
|
||||||
/// Gets a reference to the key in the entry.
|
/// Gets a reference to the key in the entry.
|
||||||
pub fn key(&self) -> &K {
|
pub fn key(&self) -> &K {
|
||||||
|
@ -575,6 +592,7 @@ impl<'a, K: 'a, V: 'a, ALLOCATOR: ClonableAllocator> OccupiedEntry<'a, K, V, ALL
|
||||||
|
|
||||||
/// Gets a reference to the value in the entry.
|
/// Gets a reference to the value in the entry.
|
||||||
pub fn get(&self) -> &V {
|
pub fn get(&self) -> &V {
|
||||||
|
// SAFETY: This can only be constructed with valid locations
|
||||||
unsafe {
|
unsafe {
|
||||||
self.map
|
self.map
|
||||||
.nodes
|
.nodes
|
||||||
|
@ -590,6 +608,7 @@ impl<'a, K: 'a, V: 'a, ALLOCATOR: ClonableAllocator> OccupiedEntry<'a, K, V, ALL
|
||||||
///
|
///
|
||||||
/// [`into_mut`]: Self::into_mut
|
/// [`into_mut`]: Self::into_mut
|
||||||
pub fn get_mut(&mut self) -> &mut V {
|
pub fn get_mut(&mut self) -> &mut V {
|
||||||
|
// SAFETY: This can only be constructed with valid locations
|
||||||
unsafe {
|
unsafe {
|
||||||
self.map
|
self.map
|
||||||
.nodes
|
.nodes
|
||||||
|
@ -605,6 +624,7 @@ impl<'a, K: 'a, V: 'a, ALLOCATOR: ClonableAllocator> OccupiedEntry<'a, K, V, ALL
|
||||||
///
|
///
|
||||||
/// [`get_mut`]: Self::get_mut
|
/// [`get_mut`]: Self::get_mut
|
||||||
pub fn into_mut(self) -> &'a mut V {
|
pub fn into_mut(self) -> &'a mut V {
|
||||||
|
// SAFETY: This can only be constructed with valid locations
|
||||||
unsafe {
|
unsafe {
|
||||||
self.map
|
self.map
|
||||||
.nodes
|
.nodes
|
||||||
|
@ -615,6 +635,7 @@ impl<'a, K: 'a, V: 'a, ALLOCATOR: ClonableAllocator> OccupiedEntry<'a, K, V, ALL
|
||||||
|
|
||||||
/// Sets the value of the entry and returns the entry's old value.
|
/// Sets the value of the entry and returns the entry's old value.
|
||||||
pub fn insert(&mut self, value: V) -> V {
|
pub fn insert(&mut self, value: V) -> V {
|
||||||
|
// SAFETY: This can only be constructed with valid locations
|
||||||
unsafe {
|
unsafe {
|
||||||
self.map
|
self.map
|
||||||
.nodes
|
.nodes
|
||||||
|
@ -757,11 +778,10 @@ where
|
||||||
let location = self.nodes.location(&key, hash);
|
let location = self.nodes.location(&key, hash);
|
||||||
|
|
||||||
if let Some(location) = location {
|
if let Some(location) = location {
|
||||||
Entry::Occupied(OccupiedEntry {
|
Entry::Occupied(
|
||||||
key,
|
// SAFETY: location is valid by the call to location above
|
||||||
location,
|
unsafe { OccupiedEntry::new(key, self, location) },
|
||||||
map: self,
|
)
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
Entry::Vacant(VacantEntry { key, map: self })
|
Entry::Vacant(VacantEntry { key, map: self })
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,10 @@ impl<K, V> Node<K, V> {
|
||||||
|
|
||||||
pub(crate) fn value_mut(&mut self) -> Option<&mut V> {
|
pub(crate) fn value_mut(&mut self) -> Option<&mut V> {
|
||||||
if self.has_value() {
|
if self.has_value() {
|
||||||
Some(unsafe { self.value_mut_unchecked() })
|
Some(
|
||||||
|
// SAFETY: has a value
|
||||||
|
unsafe { self.value_mut_unchecked() },
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -52,7 +55,10 @@ impl<K, V> Node<K, V> {
|
||||||
|
|
||||||
pub(crate) fn key_ref(&self) -> Option<&K> {
|
pub(crate) fn key_ref(&self) -> Option<&K> {
|
||||||
if self.distance_to_initial_bucket >= 0 {
|
if self.distance_to_initial_bucket >= 0 {
|
||||||
Some(unsafe { self.key.assume_init_ref() })
|
Some(
|
||||||
|
// SAFETY: has a value
|
||||||
|
unsafe { self.key.assume_init_ref() },
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -60,7 +66,10 @@ impl<K, V> Node<K, V> {
|
||||||
|
|
||||||
pub(crate) fn key_value_ref(&self) -> Option<(&K, &V)> {
|
pub(crate) fn key_value_ref(&self) -> Option<(&K, &V)> {
|
||||||
if self.has_value() {
|
if self.has_value() {
|
||||||
Some(unsafe { self.key_value_ref_unchecked() })
|
Some(
|
||||||
|
// SAFETY: has a value
|
||||||
|
unsafe { self.key_value_ref_unchecked() },
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -72,7 +81,10 @@ impl<K, V> Node<K, V> {
|
||||||
|
|
||||||
pub(crate) fn key_value_mut(&mut self) -> Option<(&K, &mut V)> {
|
pub(crate) fn key_value_mut(&mut self) -> Option<(&K, &mut V)> {
|
||||||
if self.has_value() {
|
if self.has_value() {
|
||||||
Some(unsafe { (self.key.assume_init_ref(), self.value.assume_init_mut()) })
|
Some(
|
||||||
|
// SAFETY: has a value
|
||||||
|
unsafe { (self.key.assume_init_ref(), self.value.assume_init_mut()) },
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -88,7 +100,10 @@ impl<K, V> Node<K, V> {
|
||||||
let value = mem::replace(&mut self.value, MaybeUninit::uninit());
|
let value = mem::replace(&mut self.value, MaybeUninit::uninit());
|
||||||
self.distance_to_initial_bucket = -1;
|
self.distance_to_initial_bucket = -1;
|
||||||
|
|
||||||
Some(unsafe { (key.assume_init(), value.assume_init(), self.hash) })
|
Some(
|
||||||
|
// SAFETY: has a value
|
||||||
|
unsafe { (key.assume_init(), value.assume_init(), self.hash) },
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -104,6 +119,7 @@ impl<K, V> Node<K, V> {
|
||||||
let old_key = mem::replace(&mut self.key, MaybeUninit::new(key));
|
let old_key = mem::replace(&mut self.key, MaybeUninit::new(key));
|
||||||
let old_value = mem::replace(&mut self.value, MaybeUninit::new(value));
|
let old_value = mem::replace(&mut self.value, MaybeUninit::new(value));
|
||||||
|
|
||||||
|
// SAFETY: has a value
|
||||||
unsafe { (old_key.assume_init(), old_value.assume_init()) }
|
unsafe { (old_key.assume_init(), old_value.assume_init()) }
|
||||||
} else {
|
} else {
|
||||||
panic!("Cannot replace an uninitialised node");
|
panic!("Cannot replace an uninitialised node");
|
||||||
|
@ -133,8 +149,11 @@ impl<K, V> Node<K, V> {
|
||||||
impl<K, V> Drop for Node<K, V> {
|
impl<K, V> Drop for Node<K, V> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if self.has_value() {
|
if self.has_value() {
|
||||||
unsafe { ptr::drop_in_place(self.key.as_mut_ptr()) };
|
// SAFETY: has a value
|
||||||
unsafe { ptr::drop_in_place(self.value.as_mut_ptr()) };
|
unsafe {
|
||||||
|
ptr::drop_in_place(self.key.as_mut_ptr());
|
||||||
|
ptr::drop_in_place(self.value.as_mut_ptr());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,8 +174,14 @@ where
|
||||||
Self {
|
Self {
|
||||||
hash: self.hash,
|
hash: self.hash,
|
||||||
distance_to_initial_bucket: self.distance_to_initial_bucket,
|
distance_to_initial_bucket: self.distance_to_initial_bucket,
|
||||||
key: MaybeUninit::new(unsafe { self.key.assume_init_ref() }.clone()),
|
key: MaybeUninit::new(
|
||||||
value: MaybeUninit::new(unsafe { self.value.assume_init_ref() }.clone()),
|
// SAFETY: has a value
|
||||||
|
unsafe { self.key.assume_init_ref() }.clone(),
|
||||||
|
),
|
||||||
|
value: MaybeUninit::new(
|
||||||
|
// SAFETY: has a value
|
||||||
|
unsafe { self.value.assume_init_ref() }.clone(),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Self {
|
Self {
|
||||||
|
|
Loading…
Reference in a new issue