mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-07-26 23:10:56 +00:00
Compare commits
2 commits
adf7f503a0
...
04c45f2a4e
Author | SHA1 | Date | |
---|---|---|---|
|
04c45f2a4e | ||
|
bd626e9a95 |
|
@ -36,50 +36,25 @@ pub enum BorrowedNPC<'a> {
|
||||||
cell: &'a NPCCell,
|
cell: &'a NPCCell,
|
||||||
token: &'a mut NPCAccessToken,
|
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,
|
Unborrowed,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BorrowedNPC<'_> {
|
|
||||||
unsafe fn new_unborrowed() -> Self {
|
|
||||||
Self::Unborrowed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deref for BorrowedNPC<'_> {
|
impl Deref for BorrowedNPC<'_> {
|
||||||
type Target = NPC;
|
type Target = NPC;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
match self {
|
match self {
|
||||||
BorrowedNPC::Borrowed { ref_mut, .. } => &*ref_mut,
|
BorrowedNPC::Borrowed { ref_mut, .. } => &*ref_mut,
|
||||||
// `unreachable_unchecked` tells the compiler to assume this branch
|
_ => unreachable!()
|
||||||
// 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<'_> {
|
impl DerefMut for BorrowedNPC<'_> {
|
||||||
#[inline]
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
match self {
|
match self {
|
||||||
BorrowedNPC::Borrowed { ref_mut, .. } => &mut *ref_mut,
|
BorrowedNPC::Borrowed { ref_mut, .. } => &mut *ref_mut,
|
||||||
// `unreachable_unchecked` tells the compiler to assume this branch
|
_ => unreachable!()
|
||||||
// will never be reached, skipping any checks.
|
|
||||||
// Verified via Godbolt: This significantly improves codegen when
|
|
||||||
// accessing `BorrowedNPC` fields.
|
|
||||||
_ => unsafe { core::hint::unreachable_unchecked() }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,10 +66,10 @@ impl TokenProvider for BorrowedNPC<'_> {
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
BorrowedNPC::Borrowed { .. } => {
|
BorrowedNPC::Borrowed { .. } => {
|
||||||
let old = std::mem::replace(self, unsafe { BorrowedNPC::new_unborrowed() });
|
let old = std::mem::replace(self, BorrowedNPC::Unborrowed);
|
||||||
let (old_ref_mut, token, cell) = match old {
|
let (old_ref_mut, token, cell) = match old {
|
||||||
BorrowedNPC::Borrowed { ref_mut, token, cell } => (ref_mut, token, cell),
|
BorrowedNPC::Borrowed { ref_mut, token, cell } => (ref_mut, token, cell),
|
||||||
_ => unsafe { core::hint::unreachable_unchecked() }
|
_ => unreachable!()
|
||||||
};
|
};
|
||||||
|
|
||||||
drop(old_ref_mut);
|
drop(old_ref_mut);
|
||||||
|
@ -105,7 +80,7 @@ impl TokenProvider for BorrowedNPC<'_> {
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
_ => unsafe { core::hint::unreachable_unchecked() }
|
_ => unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue