mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-07-27 07:20:51 +00:00
Compare commits
2 commits
963841f563
...
adf7f503a0
Author | SHA1 | Date | |
---|---|---|---|
|
adf7f503a0 | ||
|
738cff69fe |
|
@ -36,25 +36,50 @@ pub enum BorrowedNPC<'a> {
|
|||
cell: &'a NPCCell,
|
||||
token: &'a mut NPCAccessToken,
|
||||
},
|
||||
/// SAFETY: Constructing the `Unborrowed` variant is **inherently unsafe**.
|
||||
/// Rust doesn't support marking enum variants as unsafe, but if it did, this
|
||||
/// one would be.
|
||||
///
|
||||
/// A `BorrowedNPC` in the `Unborrowed` state must **never** be dereferenced.
|
||||
/// Doing so will invoke `unreachable_unchecked`, leading to immediate Undefined
|
||||
/// Behavior.
|
||||
///
|
||||
/// Never expose a `BorrowedNPC` in the `Unborrowed` state outside this module.
|
||||
Unborrowed,
|
||||
}
|
||||
|
||||
impl BorrowedNPC<'_> {
|
||||
unsafe fn new_unborrowed() -> Self {
|
||||
Self::Unborrowed
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for BorrowedNPC<'_> {
|
||||
type Target = NPC;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
match self {
|
||||
BorrowedNPC::Borrowed { ref_mut, .. } => &*ref_mut,
|
||||
_ => unreachable!()
|
||||
// `unreachable_unchecked` tells the compiler to assume this branch
|
||||
// will never be reached, skipping any checks.
|
||||
// Verified via Godbolt: This significantly improves codegen when
|
||||
// accessing `BorrowedNPC` fields.
|
||||
_ => unsafe { core::hint::unreachable_unchecked() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for BorrowedNPC<'_> {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
match self {
|
||||
BorrowedNPC::Borrowed { ref_mut, .. } => &mut *ref_mut,
|
||||
_ => unreachable!()
|
||||
// `unreachable_unchecked` tells the compiler to assume this branch
|
||||
// will never be reached, skipping any checks.
|
||||
// Verified via Godbolt: This significantly improves codegen when
|
||||
// accessing `BorrowedNPC` fields.
|
||||
_ => unsafe { core::hint::unreachable_unchecked() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,10 +91,10 @@ impl TokenProvider for BorrowedNPC<'_> {
|
|||
{
|
||||
match self {
|
||||
BorrowedNPC::Borrowed { .. } => {
|
||||
let old = std::mem::replace(self, BorrowedNPC::Unborrowed);
|
||||
let old = std::mem::replace(self, unsafe { BorrowedNPC::new_unborrowed() });
|
||||
let (old_ref_mut, token, cell) = match old {
|
||||
BorrowedNPC::Borrowed { ref_mut, token, cell } => (ref_mut, token, cell),
|
||||
_ => unreachable!()
|
||||
_ => unsafe { core::hint::unreachable_unchecked() }
|
||||
};
|
||||
|
||||
drop(old_ref_mut);
|
||||
|
@ -80,7 +105,7 @@ impl TokenProvider for BorrowedNPC<'_> {
|
|||
|
||||
result
|
||||
}
|
||||
_ => unreachable!()
|
||||
_ => unsafe { core::hint::unreachable_unchecked() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue