1
0
Fork 0
mirror of https://github.com/doukutsu-rs/doukutsu-rs synced 2025-07-27 07:20:51 +00:00

Compare commits

...

2 commits

Author SHA1 Message Date
N.E.C. adf7f503a0
Merge 738cff69fe into 85f4c3f095 2025-07-10 02:33:54 +00:00
N.E.C. 738cff69fe Improve codegen when accessing BorrowedNPC fields 2025-07-09 19:33:53 -07:00

View file

@ -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() }
}
}
}