midenc_hir/ir/
entity.rs

1mod group;
2mod list;
3mod storage;
4
5use core::{
6    alloc::{AllocError, Layout},
7    any::Any,
8    cell::{Cell, UnsafeCell},
9    fmt,
10    hash::Hash,
11    mem::MaybeUninit,
12    ops::{Deref, DerefMut},
13    ptr::NonNull,
14};
15
16pub use self::{
17    group::EntityGroup,
18    list::{EntityCursor, EntityCursorMut, EntityIter, EntityList, MaybeDefaultEntityIter},
19    storage::{EntityRange, EntityRangeMut, EntityStorage},
20};
21use crate::any::*;
22
23/// A trait implemented by an IR entity
24pub trait Entity: Any {}
25
26/// A trait implemented by any [Entity] that is storeable in an [EntityList].
27///
28/// This trait defines callbacks that are executed any time the entity is added, removed, or
29/// transferred between lists.
30///
31/// By default, these callbacks are no-ops.
32#[allow(unused_variables)]
33pub trait EntityListItem: Sized + Entity {
34    /// Invoked when this entity type is inserted into an intrusive list
35    #[inline]
36    fn on_inserted(this: UnsafeIntrusiveEntityRef<Self>, cursor: &mut EntityCursorMut<'_, Self>) {}
37    /// Invoked when this entity type is removed from an intrusive list
38    #[inline]
39    fn on_removed(this: UnsafeIntrusiveEntityRef<Self>, list: &mut EntityCursorMut<'_, Self>) {}
40    /// Invoked when a set of entities is moved from one intrusive list to another
41    #[inline]
42    fn on_transfer(
43        this: UnsafeIntrusiveEntityRef<Self>,
44        from: &mut EntityList<Self>,
45        to: &mut EntityList<Self>,
46    ) {
47    }
48}
49
50impl<T: Sized + Entity> EntityListItem for T {
51    default fn on_inserted(
52        _this: UnsafeIntrusiveEntityRef<Self>,
53        _list: &mut EntityCursorMut<'_, Self>,
54    ) {
55    }
56
57    default fn on_removed(
58        _this: UnsafeIntrusiveEntityRef<Self>,
59        _list: &mut EntityCursorMut<'_, Self>,
60    ) {
61    }
62
63    default fn on_transfer(
64        _this: UnsafeIntrusiveEntityRef<Self>,
65        _from: &mut EntityList<Self>,
66        _to: &mut EntityList<Self>,
67    ) {
68    }
69}
70
71/// A trait implemented by an [Entity] that is a parent to one or more other [Entity] types.
72///
73/// Parents must implement this trait for each unique [EntityList] they contain.
74pub trait EntityParent<Child: ?Sized>: Entity {
75    /// Statically compute the offset of the [EntityList] within `Self` that is used to store
76    /// children of type `Child`.
77    fn offset() -> usize;
78}
79
80/// A trait implemented by an [Entity] that is a logical child of another entity type, and is stored
81/// in the parent using an [EntityList].
82///
83/// This trait defines callbacks that are executed any time the entity is modified in relation to its
84/// parent entity, i.e. inserted in a parent, removed from a parent, or moved from one to another.
85///
86/// By default, these callbacks are no-ops.
87pub trait EntityWithParent: Entity {
88    /// The parent entity that this entity logically belongs to.
89    type Parent: EntityParent<Self>;
90}
91
92/// A trait implemented by an [Entity] that has a unique identifier
93///
94/// Currently, this is used only for [Value]s and [Block]s.
95pub trait EntityWithId: Entity {
96    type Id: EntityId;
97
98    fn id(&self) -> Self::Id;
99}
100
101/// A trait implemented by an IR entity that can be stored in [EntityStorage].
102pub trait StorableEntity {
103    /// Get the absolute index of this entity in its container.
104    fn index(&self) -> usize;
105    /// Set the absolute index of this entity in its container.
106    ///
107    /// # Safety
108    ///
109    /// This is intended to be called only by the [EntityStorage] implementation, as it is
110    /// responsible for maintaining indices of all items it is storing. However, entities commonly
111    /// want to know their own index in storage, so this trait allows them to conceptually own the
112    /// index, but delegate maintenance to [EntityStorage].
113    unsafe fn set_index(&mut self, index: usize);
114    /// Called when this entity is removed from [EntityStorage]
115    #[inline(always)]
116    fn unlink(&mut self) {}
117}
118
119/// A trait that must be implemented by the unique identifier for an [Entity]
120pub trait EntityId: Copy + Clone + PartialEq + Eq + PartialOrd + Ord + Hash + fmt::Display {
121    fn as_usize(&self) -> usize;
122}
123
124/// An error raised when an aliasing violation is detected in the use of [EntityHandle]
125#[non_exhaustive]
126pub struct AliasingViolationError {
127    #[cfg(debug_assertions)]
128    location: &'static core::panic::Location<'static>,
129    kind: AliasingViolationKind,
130}
131
132#[derive(Debug)]
133enum AliasingViolationKind {
134    /// Attempted to create an immutable alias for an entity that was mutably borrowed
135    Immutable,
136    /// Attempted to create a mutable alias for an entity that was immutably borrowed
137    Mutable,
138}
139
140impl fmt::Display for AliasingViolationKind {
141    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142        match self {
143            Self::Immutable => f.write_str("already mutably borrowed"),
144            Self::Mutable => f.write_str("already borrowed"),
145        }
146    }
147}
148
149impl fmt::Debug for AliasingViolationError {
150    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151        let mut builder = f.debug_struct("AliasingViolationError");
152        builder.field("kind", &self.kind);
153        #[cfg(debug_assertions)]
154        builder.field("location", &self.location);
155        builder.finish()
156    }
157}
158impl fmt::Display for AliasingViolationError {
159    #[cfg(debug_assertions)]
160    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161        write!(
162            f,
163            "{} in file '{}' at line {} and column {}",
164            &self.kind,
165            self.location.file(),
166            self.location.line(),
167            self.location.column()
168        )
169    }
170
171    #[cfg(not(debug_assertions))]
172    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173        write!(f, "{}", &self.kind)
174    }
175}
176
177/// A raw pointer to an IR entity that has no associated metadata
178pub type UnsafeEntityRef<T> = RawEntityRef<T, ()>;
179
180/// A raw pointer to an IR entity that has an intrusive linked-list link as its metadata
181pub type UnsafeIntrusiveEntityRef<T> = RawEntityRef<T, IntrusiveLink>;
182
183pub struct IntrusiveLink {
184    link: intrusive_collections::LinkedListLink,
185    parent: Cell<*const ()>,
186}
187
188impl Default for IntrusiveLink {
189    fn default() -> Self {
190        Self {
191            link: Default::default(),
192            parent: Cell::new(core::ptr::null()),
193        }
194    }
195}
196
197impl IntrusiveLink {
198    #[inline]
199    pub fn is_linked(&self) -> bool {
200        self.link.is_linked()
201    }
202}
203
204impl IntrusiveLink {
205    pub(self) fn set_parent<T>(&self, parent: Option<UnsafeIntrusiveEntityRef<T>>) {
206        if let Some(parent) = parent {
207            assert!(
208                self.link.is_linked(),
209                "must add entity to parent entity list before setting parent"
210            );
211            self.parent.set(UnsafeIntrusiveEntityRef::as_ptr(&parent).cast());
212        } else if self.parent.get().is_null() {
213            panic!("no parent previously set");
214        } else {
215            self.parent.set(core::ptr::null());
216        }
217    }
218
219    pub fn parent<T>(&self) -> Option<UnsafeIntrusiveEntityRef<T>> {
220        let parent = self.parent.get();
221        if parent.is_null() {
222            // EntityList is orphaned
223            None
224        } else {
225            Some(unsafe { UnsafeIntrusiveEntityRef::from_raw(parent.cast()) })
226        }
227    }
228}
229
230/// A [RawEntityRef] is an unsafe smart pointer type for IR entities allocated in a [Context].
231///
232/// Along with the type of entity referenced, it can be instantiated with extra metadata of any
233/// type. For example, [UnsafeIntrusiveEntityRef] stores an intrusive link in the entity metadata,
234/// so that the entity can be added to an intrusive linked list without the entity needing to
235/// know about the link - and without violating aliasing rules when navigating the list.
236///
237/// Unlike regular references, no reference to the underlying `T` is constructed until one is
238/// needed, at which point the borrow (whether mutable or immutable) is dynamically checked to
239/// ensure that it is valid according to Rust's aliasing rules.
240///
241/// As a result, a [RawEntityRef] is not considered an alias, and it is possible to acquire a
242/// mutable reference to the underlying data even while other copies of the handle exist. Any
243/// attempt to construct invalid aliases (immutable reference while a mutable reference exists, or
244/// vice versa), will result in a runtime panic.
245///
246/// This is a tradeoff, as we do not get compile-time guarantees that such panics will not occur,
247/// but in exchange we get a much more flexible and powerful IR structure.
248///
249/// # SAFETY
250///
251/// Unlike most smart-pointer types, e.g. `Rc`, [RAwEntityRef] does not provide any protection
252/// against the underlying allocation being deallocated (i.e. the arena it points into is dropped).
253/// This is by design, as the type is meant to be stored in objects inside the arena, and
254/// _not_ dropped when the arena is dropped. This requires care when using it however, to ensure
255/// that no [RawEntityRef] lives longer than the arena that allocated it.
256///
257/// For a safe entity reference, see [EntityRef], which binds a [RawEntityRef] to the lifetime
258/// of the arena.
259pub struct RawEntityRef<T: ?Sized, Metadata = ()> {
260    inner: NonNull<RawEntityMetadata<T, Metadata>>,
261}
262impl<T: ?Sized, Metadata> Copy for RawEntityRef<T, Metadata> {}
263impl<T: ?Sized, Metadata> Clone for RawEntityRef<T, Metadata> {
264    fn clone(&self) -> Self {
265        *self
266    }
267}
268impl<T: ?Sized, Metadata> RawEntityRef<T, Metadata> {
269    /// Create a new [EntityHandle] from a raw pointer to the underlying [EntityObj].
270    ///
271    /// # SAFETY
272    ///
273    /// [EntityHandle] is designed to operate like an owned smart-pointer type, ala `Rc`. As a
274    /// result, it expects that the underlying data _never moves_ after it is allocated, for as
275    /// long as any outstanding [EntityHandle]s exist that might be used to access that data.
276    ///
277    /// Additionally, it is expected that all accesses to the underlying data flow through an
278    /// [EntityHandle], as it is the foundation on which the soundness of [EntityHandle] is built.
279    /// You must ensure that there no other references to the underlying data exist, or can be
280    /// created, _except_ via [EntityHandle].
281    ///
282    /// You should generally not be using this API, as it is meant solely for constructing an
283    /// [EntityHandle] immediately after allocating the underlying [EntityObj].
284    #[inline]
285    unsafe fn from_inner(inner: NonNull<RawEntityMetadata<T, Metadata>>) -> Self {
286        Self { inner }
287    }
288
289    #[inline]
290    unsafe fn from_ptr(ptr: *mut RawEntityMetadata<T, Metadata>) -> Self {
291        debug_assert!(!ptr.is_null());
292        Self::from_inner(NonNull::new_unchecked(ptr))
293    }
294
295    #[inline]
296    fn into_inner(this: Self) -> NonNull<RawEntityMetadata<T, Metadata>> {
297        this.inner
298    }
299}
300
301impl<T: 'static, Metadata: 'static> RawEntityRef<T, Metadata> {
302    /// Create a new [RawEntityRef] by allocating `value` with `metadata` in the given arena
303    /// allocator.
304    ///
305    /// # SAFETY
306    ///
307    /// The resulting [RawEntityRef] must not outlive the arena. This is not enforced statically,
308    /// it is up to the caller to uphold the invariants of this type.
309    pub fn new_with_metadata(value: T, metadata: Metadata, arena: &blink_alloc::Blink) -> Self {
310        unsafe {
311            Self::from_inner(NonNull::new_unchecked(
312                arena.put(RawEntityMetadata::new(value, metadata)),
313            ))
314        }
315    }
316
317    /// Create a [RawEntityRef] for an entity which may not be fully initialized, using the provided
318    /// arena.
319    ///
320    /// # SAFETY
321    ///
322    /// The safety rules are much the same as [RawEntityRef::new], with the main difference
323    /// being that the `T` does not have to be initialized yet. No references to the `T` will
324    /// be created directly until [RawEntityRef::assume_init] is called.
325    pub fn new_uninit_with_metadata(
326        metadata: Metadata,
327        arena: &blink_alloc::Blink,
328    ) -> RawEntityRef<MaybeUninit<T>, Metadata> {
329        unsafe {
330            RawEntityRef::from_ptr(RawEntityRef::allocate_for_layout(
331                metadata,
332                Layout::new::<T>(),
333                |layout| arena.allocator().allocate(layout).map_err(|_| AllocError),
334                <*mut u8>::cast,
335            ))
336        }
337    }
338}
339
340impl<T: 'static> RawEntityRef<T, ()> {
341    pub fn new(value: T, arena: &blink_alloc::Blink) -> Self {
342        RawEntityRef::new_with_metadata(value, (), arena)
343    }
344
345    pub fn new_uninit(arena: &blink_alloc::Blink) -> RawEntityRef<MaybeUninit<T>, ()> {
346        RawEntityRef::new_uninit_with_metadata((), arena)
347    }
348}
349
350impl<T, Metadata> RawEntityRef<MaybeUninit<T>, Metadata> {
351    /// Converts to `RawEntityRef<T>`.
352    ///
353    /// # Safety
354    ///
355    /// Just like with [MaybeUninit::assume_init], it is up to the caller to guarantee that the
356    /// value really is in an initialized state. Calling this when the content is not yet fully
357    /// initialized causes immediate undefined behavior.
358    #[inline]
359    pub unsafe fn assume_init(self) -> RawEntityRef<T, Metadata> {
360        let ptr = Self::into_inner(self);
361        unsafe { RawEntityRef::from_inner(ptr.cast()) }
362    }
363}
364
365impl<T: ?Sized, Metadata> RawEntityRef<T, Metadata> {
366    /// Convert this handle into a raw pointer to the underlying entity.
367    ///
368    /// This should only be used in situations where the returned pointer will not be used to
369    /// actually access the underlying entity. Use [get] or [get_mut] for that. [RawEntityRef]
370    /// ensures that Rust's aliasing rules are not violated when using it, but if you use the
371    /// returned pointer to do so, no such guarantee is provided, and undefined behavior can
372    /// result.
373    ///
374    /// # Safety
375    ///
376    /// The returned pointer _must_ not be used to create a reference to the underlying entity
377    /// unless you can guarantee that such a reference does not violate Rust's aliasing rules.
378    ///
379    /// Do not use the pointer to create a mutable reference if other references exist, and do
380    /// not use the pointer to create an immutable reference if a mutable reference exists or
381    /// might be created while the immutable reference lives.
382    pub fn into_raw(this: Self) -> *const T {
383        Self::as_ptr(&this)
384    }
385
386    pub fn as_ptr(this: &Self) -> *const T {
387        let ptr: *mut RawEntityMetadata<T, Metadata> = NonNull::as_ptr(this.inner);
388
389        // SAFETY: This cannot go through Deref::deref or RawEntityRef::inner because this
390        // is required to retain raw/mut provenance such that e.g. `get_mut` can write through
391        // the pointer after the RawEntityRef is recovered through `from_raw`
392        let ptr = unsafe { core::ptr::addr_of_mut!((*ptr).entity.cell) };
393        UnsafeCell::raw_get(ptr).cast_const()
394    }
395
396    /// Convert a pointer returned by [RawEntityRef::into_raw] back into a [RawEntityRef].
397    ///
398    /// # Safety
399    ///
400    /// * It is _only_ valid to call this method on a pointer returned by [RawEntityRef::into_raw].
401    /// * The pointer must be a valid pointer for `T`
402    pub unsafe fn from_raw(ptr: *const T) -> Self {
403        let offset = unsafe { RawEntityMetadata::<T, Metadata>::data_offset(ptr) };
404
405        // Reverse the offset to find the original EntityObj
406        let entity_ptr = unsafe { ptr.byte_sub(offset) as *mut RawEntityMetadata<T, Metadata> };
407
408        unsafe { Self::from_ptr(entity_ptr) }
409    }
410
411    /// Get a dynamically-checked immutable reference to the underlying `T`
412    #[track_caller]
413    pub fn borrow<'a, 'b: 'a>(&'a self) -> EntityRef<'b, T> {
414        let ptr: *mut RawEntityMetadata<T, Metadata> = NonNull::as_ptr(self.inner);
415        unsafe { (*core::ptr::addr_of!((*ptr).entity)).borrow() }
416    }
417
418    /// Get a dynamically-checked mutable reference to the underlying `T`
419    #[track_caller]
420    pub fn borrow_mut<'a, 'b: 'a>(&'a mut self) -> EntityMut<'b, T> {
421        let ptr: *mut RawEntityMetadata<T, Metadata> = NonNull::as_ptr(self.inner);
422        unsafe { (*core::ptr::addr_of!((*ptr).entity)).borrow_mut() }
423    }
424
425    /// Try to get a dynamically-checked mutable reference to the underlying `T`
426    ///
427    /// Returns `None` if the entity is already borrowed
428    pub fn try_borrow_mut<'a, 'b: 'a>(&'a mut self) -> Option<EntityMut<'b, T>> {
429        let ptr: *mut RawEntityMetadata<T, Metadata> = NonNull::as_ptr(self.inner);
430        unsafe { (*core::ptr::addr_of!((*ptr).entity)).try_borrow_mut().ok() }
431    }
432
433    pub fn ptr_eq(this: &Self, other: &Self) -> bool {
434        core::ptr::addr_eq(this.inner.as_ptr(), other.inner.as_ptr())
435    }
436
437    unsafe fn allocate_for_layout<F, F2>(
438        metadata: Metadata,
439        value_layout: Layout,
440        allocate: F,
441        mem_to_metadata: F2,
442    ) -> *mut RawEntityMetadata<T, Metadata>
443    where
444        F: FnOnce(Layout) -> Result<NonNull<[u8]>, AllocError>,
445        F2: FnOnce(*mut u8) -> *mut RawEntityMetadata<T, Metadata>,
446    {
447        use alloc::alloc::handle_alloc_error;
448
449        let layout = raw_entity_metadata_layout_for_value_layout::<Metadata>(value_layout);
450        unsafe {
451            RawEntityRef::try_allocate_for_layout(metadata, value_layout, allocate, mem_to_metadata)
452                .unwrap_or_else(|_| handle_alloc_error(layout))
453        }
454    }
455
456    #[inline]
457    unsafe fn try_allocate_for_layout<F, F2>(
458        metadata: Metadata,
459        value_layout: Layout,
460        allocate: F,
461        mem_to_metadata: F2,
462    ) -> Result<*mut RawEntityMetadata<T, Metadata>, AllocError>
463    where
464        F: FnOnce(Layout) -> Result<NonNull<[u8]>, AllocError>,
465        F2: FnOnce(*mut u8) -> *mut RawEntityMetadata<T, Metadata>,
466    {
467        let layout = raw_entity_metadata_layout_for_value_layout::<Metadata>(value_layout);
468        let ptr = allocate(layout)?;
469        let inner = mem_to_metadata(ptr.as_non_null_ptr().as_ptr());
470        unsafe {
471            debug_assert_eq!(Layout::for_value_raw(inner), layout);
472
473            core::ptr::addr_of_mut!((*inner).metadata).write(metadata);
474            core::ptr::addr_of_mut!((*inner).entity.borrow).write(Cell::new(BorrowFlag::UNUSED));
475            #[cfg(debug_assertions)]
476            core::ptr::addr_of_mut!((*inner).entity.borrowed_at).write(Cell::new(None));
477        }
478
479        Ok(inner)
480    }
481}
482
483impl<From: ?Sized, Metadata: 'static> RawEntityRef<From, Metadata> {
484    /// Casts this reference to the concrete type `T`, if the underlying value is a `T`.
485    ///
486    /// If the cast is not valid for this reference, `Err` is returned containing the original value.
487    #[inline]
488    pub fn try_downcast<To>(
489        self,
490    ) -> Result<RawEntityRef<To, Metadata>, RawEntityRef<From, Metadata>>
491    where
492        To: DowncastFromRef<From> + 'static,
493        From: 'static,
494    {
495        RawEntityRef::<To, Metadata>::try_downcast_from(self)
496    }
497
498    /// Casts this reference to the concrete type `T`, if the underlying value is a `T`.
499    ///
500    /// If the cast is not valid for this reference, `Err` is returned containing the original value.
501    #[inline]
502    pub fn try_downcast_ref<To, Obj>(&self) -> Option<RawEntityRef<To, Metadata>>
503    where
504        To: DowncastFromRef<From> + 'static,
505        From: Is<Obj> + AsAny + 'static,
506        Obj: ?Sized,
507    {
508        RawEntityRef::<To, Metadata>::try_downcast_from_ref(self)
509    }
510
511    /// Casts this reference to the concrete type `T`, if the underlying value is a `T`.
512    ///
513    /// Panics if the cast is not valid for this reference.
514    #[inline]
515    #[track_caller]
516    pub fn downcast<To, Obj>(self) -> RawEntityRef<To, Metadata>
517    where
518        To: DowncastFromRef<From> + 'static,
519        From: Is<Obj> + AsAny + 'static,
520        Obj: ?Sized,
521    {
522        RawEntityRef::<To, Metadata>::downcast_from(self)
523    }
524
525    /// Casts this reference to the concrete type `T`, if the underlying value is a `T`.
526    ///
527    /// Panics if the cast is not valid for this reference.
528    #[inline]
529    #[track_caller]
530    pub fn downcast_ref<To, Obj>(&self) -> RawEntityRef<To, Metadata>
531    where
532        To: DowncastFromRef<From> + 'static,
533        From: Is<Obj> + AsAny + 'static,
534        Obj: ?Sized,
535    {
536        RawEntityRef::<To, Metadata>::downcast_from_ref(self)
537    }
538}
539
540impl<To, Metadata: 'static> RawEntityRef<To, Metadata> {
541    pub fn try_downcast_from<From>(
542        from: RawEntityRef<From, Metadata>,
543    ) -> Result<Self, RawEntityRef<From, Metadata>>
544    where
545        From: ?Sized + 'static,
546        To: DowncastFromRef<From> + 'static,
547    {
548        let borrow = from.borrow();
549        <To as DowncastFromRef<From>>::downcast_from_ref(&*borrow)
550            .map(|to| unsafe { RawEntityRef::from_raw(to) })
551            .ok_or(from)
552    }
553
554    pub fn try_downcast_from_ref<From, Obj>(from: &RawEntityRef<From, Metadata>) -> Option<Self>
555    where
556        From: ?Sized + Is<Obj> + AsAny + 'static,
557        To: DowncastFromRef<From> + 'static,
558        Obj: ?Sized,
559    {
560        let borrow = from.borrow();
561        borrow.as_any().downcast_ref().map(|to| unsafe { RawEntityRef::from_raw(to) })
562    }
563
564    #[track_caller]
565    pub fn downcast_from<From, Obj>(from: RawEntityRef<From, Metadata>) -> Self
566    where
567        From: ?Sized + Is<Obj> + AsAny + 'static,
568        To: DowncastFromRef<From> + 'static,
569        Obj: ?Sized,
570    {
571        let borrow = from.borrow();
572        unsafe { RawEntityRef::from_raw(borrow.as_any().downcast_ref().expect("invalid cast")) }
573    }
574
575    #[track_caller]
576    pub fn downcast_from_ref<From, Obj>(from: &RawEntityRef<From, Metadata>) -> Self
577    where
578        From: ?Sized + Is<Obj> + AsAny + 'static,
579        To: DowncastFromRef<From> + 'static,
580        Obj: ?Sized,
581    {
582        let borrow = from.borrow();
583        unsafe { RawEntityRef::from_raw(borrow.as_any().downcast_ref().expect("invalid cast")) }
584    }
585}
586
587impl<From: ?Sized, Metadata: 'static> RawEntityRef<From, Metadata> {
588    /// Casts this reference to the an unsized type `Trait`, if `From` implements `Trait`
589    ///
590    /// If the cast is not valid for this reference, `Err` is returned containing the original value.
591    #[inline]
592    pub fn upcast<To>(self) -> RawEntityRef<To, Metadata>
593    where
594        To: ?Sized,
595        From: core::marker::Unsize<To> + AsAny + 'static,
596    {
597        unsafe { RawEntityRef::<To, Metadata>::from_inner(self.inner) }
598    }
599}
600
601impl<T: crate::Op> RawEntityRef<T, IntrusiveLink> {
602    /// Get a entity ref for the underlying [crate::Operation] data of an [Op].
603    pub fn as_operation_ref(self) -> crate::OperationRef {
604        // SAFETY: This relies on the fact that we generate Op implementations such that the first
605        // field is always the [crate::Operation], and that the containing struct is #[repr(C)].
606        unsafe {
607            let ptr = Self::into_raw(self);
608            crate::OperationRef::from_raw(ptr.cast())
609        }
610    }
611}
612
613impl<T, U, Metadata> core::ops::CoerceUnsized<RawEntityRef<U, Metadata>>
614    for RawEntityRef<T, Metadata>
615where
616    T: ?Sized + core::marker::Unsize<U>,
617    U: ?Sized,
618{
619}
620impl<T: ?Sized, Metadata> Eq for RawEntityRef<T, Metadata> {}
621impl<T: ?Sized, Metadata> PartialEq for RawEntityRef<T, Metadata> {
622    #[inline]
623    fn eq(&self, other: &Self) -> bool {
624        Self::ptr_eq(self, other)
625    }
626}
627impl<T: ?Sized + EntityWithId, Metadata> PartialOrd for RawEntityRef<T, Metadata> {
628    #[inline]
629    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
630        Some(self.cmp(other))
631    }
632}
633impl<T: ?Sized + EntityWithId, Metadata> Ord for RawEntityRef<T, Metadata> {
634    #[inline]
635    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
636        self.borrow().id().cmp(&other.borrow().id())
637    }
638}
639impl<T: ?Sized, Metadata> core::hash::Hash for RawEntityRef<T, Metadata> {
640    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
641        self.inner.as_ptr().addr().hash(state);
642    }
643}
644impl<T: ?Sized, Metadata> fmt::Pointer for RawEntityRef<T, Metadata> {
645    #[inline]
646    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
647        fmt::Pointer::fmt(&Self::as_ptr(self), f)
648    }
649}
650impl<T: ?Sized + fmt::Display, Metadata> fmt::Display for RawEntityRef<T, Metadata> {
651    #[inline]
652    default fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
653        write!(f, "{}", self.borrow())
654    }
655}
656impl<T: ?Sized + fmt::Display + EntityWithId, Metadata> fmt::Display for RawEntityRef<T, Metadata> {
657    #[inline]
658    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
659        write!(f, "{}", self.borrow().id())
660    }
661}
662
663impl<T: ?Sized + fmt::Debug, Metadata> fmt::Debug for RawEntityRef<T, Metadata> {
664    #[inline]
665    default fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
666        fmt::Debug::fmt(&self.borrow(), f)
667    }
668}
669impl<T: ?Sized + fmt::Debug + EntityWithId, Metadata> fmt::Debug for RawEntityRef<T, Metadata> {
670    #[inline]
671    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
672        write!(f, "{}", self.borrow().id())
673    }
674}
675impl<T: ?Sized + crate::formatter::PrettyPrint, Metadata> crate::formatter::PrettyPrint
676    for RawEntityRef<T, Metadata>
677{
678    #[inline]
679    fn render(&self) -> crate::formatter::Document {
680        self.borrow().render()
681    }
682}
683impl<T: ?Sized + StorableEntity, Metadata> StorableEntity for RawEntityRef<T, Metadata> {
684    #[inline]
685    fn index(&self) -> usize {
686        self.borrow().index()
687    }
688
689    #[inline]
690    unsafe fn set_index(&mut self, index: usize) {
691        unsafe {
692            self.borrow_mut().set_index(index);
693        }
694    }
695
696    #[inline]
697    fn unlink(&mut self) {
698        self.borrow_mut().unlink()
699    }
700}
701impl<T: ?Sized + crate::Spanned, Metadata> crate::Spanned for RawEntityRef<T, Metadata> {
702    #[inline]
703    fn span(&self) -> crate::SourceSpan {
704        self.borrow().span()
705    }
706}
707
708/// A guard that ensures a reference to an IR entity cannot be mutably aliased
709pub struct EntityRef<'b, T: ?Sized + 'b> {
710    value: NonNull<T>,
711    borrow: BorrowRef<'b>,
712}
713impl<T: ?Sized> core::ops::Deref for EntityRef<'_, T> {
714    type Target = T;
715
716    fn deref(&self) -> &Self::Target {
717        // SAFETY: the value is accessible as long as we hold our borrow.
718        unsafe { self.value.as_ref() }
719    }
720}
721impl<'b, T: ?Sized> EntityRef<'b, T> {
722    /// Map this reference to a derived reference.
723    #[inline]
724    pub fn map<U: ?Sized, F>(orig: Self, f: F) -> EntityRef<'b, U>
725    where
726        F: FnOnce(&T) -> &U,
727    {
728        EntityRef {
729            value: NonNull::from(f(&*orig)),
730            borrow: orig.borrow,
731        }
732    }
733
734    /// Project this borrow into a owned (but semantically borrowed) value that inherits ownership
735    /// of the underlying borrow.
736    pub fn project<'to, 'from: 'to, To, F>(
737        orig: EntityRef<'from, T>,
738        f: F,
739    ) -> EntityProjection<'from, To>
740    where
741        F: FnOnce(&'to T) -> To,
742        To: 'to,
743    {
744        EntityProjection {
745            value: f(unsafe { orig.value.as_ref() }),
746            borrow: orig.borrow,
747        }
748    }
749
750    /// Try to convert this immutable borrow into a mutable borrow, if it is the only immutable borrow
751    pub fn into_entity_mut(self) -> Result<EntityMut<'b, T>, Self> {
752        let value = self.value;
753        match self.borrow.try_into_mut() {
754            Ok(borrow) => Ok(EntityMut {
755                value,
756                borrow,
757                _marker: core::marker::PhantomData,
758            }),
759            Err(borrow) => Err(Self { value, borrow }),
760        }
761    }
762
763    pub fn into_borrow_ref(self) -> BorrowRef<'b> {
764        self.borrow
765    }
766
767    pub fn from_raw_parts(value: NonNull<T>, borrow: BorrowRef<'b>) -> Self {
768        Self { value, borrow }
769    }
770}
771
772impl<'b, T, U> core::ops::CoerceUnsized<EntityRef<'b, U>> for EntityRef<'b, T>
773where
774    T: ?Sized + core::marker::Unsize<U>,
775    U: ?Sized,
776{
777}
778
779impl<T: ?Sized + fmt::Debug> fmt::Debug for EntityRef<'_, T> {
780    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
781        (**self).fmt(f)
782    }
783}
784impl<T: ?Sized + fmt::Display> fmt::Display for EntityRef<'_, T> {
785    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
786        (**self).fmt(f)
787    }
788}
789impl<T: ?Sized + crate::formatter::PrettyPrint> crate::formatter::PrettyPrint for EntityRef<'_, T> {
790    #[inline]
791    fn render(&self) -> crate::formatter::Document {
792        (**self).render()
793    }
794}
795impl<T: ?Sized + Eq> Eq for EntityRef<'_, T> {}
796impl<T: ?Sized + PartialEq> PartialEq for EntityRef<'_, T> {
797    fn eq(&self, other: &Self) -> bool {
798        **self == **other
799    }
800}
801impl<T: ?Sized + PartialOrd> PartialOrd for EntityRef<'_, T> {
802    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
803        (**self).partial_cmp(&**other)
804    }
805
806    fn ge(&self, other: &Self) -> bool {
807        **self >= **other
808    }
809
810    fn gt(&self, other: &Self) -> bool {
811        **self > **other
812    }
813
814    fn le(&self, other: &Self) -> bool {
815        **self <= **other
816    }
817
818    fn lt(&self, other: &Self) -> bool {
819        **self < **other
820    }
821}
822impl<T: ?Sized + Ord> Ord for EntityRef<'_, T> {
823    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
824        (**self).cmp(&**other)
825    }
826}
827impl<T: ?Sized + Hash> Hash for EntityRef<'_, T> {
828    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
829        (**self).hash(state);
830    }
831}
832
833/// A guard that provides exclusive access to an IR entity
834pub struct EntityMut<'b, T: ?Sized> {
835    /// The raw pointer to the underlying data
836    ///
837    /// This is a pointer rather than a `&'b mut T` to avoid `noalias` violations, because a
838    /// `EntityMut` argument doesn't hold exclusivity for its whole scope, only until it drops.
839    value: NonNull<T>,
840    /// This value provides the drop glue for tracking that the underlying allocation is
841    /// mutably borrowed, but it is otherwise not read.
842    #[allow(unused)]
843    borrow: BorrowRefMut<'b>,
844    /// `NonNull` is covariant over `T`, so we need to reintroduce invariance via phantom data
845    _marker: core::marker::PhantomData<&'b mut T>,
846}
847impl<'b, T: ?Sized> EntityMut<'b, T> {
848    /// Map this mutable reference to a derived mutable reference.
849    #[inline]
850    pub fn map<U: ?Sized, F>(mut orig: Self, f: F) -> EntityMut<'b, U>
851    where
852        F: FnOnce(&mut T) -> &mut U,
853    {
854        let value = NonNull::from(f(&mut *orig));
855        EntityMut {
856            value,
857            borrow: orig.borrow,
858            _marker: core::marker::PhantomData,
859        }
860    }
861
862    /// Project this mutable borrow into a owned (but semantically borrowed) value that inherits
863    /// ownership of the underlying mutable borrow.
864    pub fn project<'to, 'from: 'to, To, F>(
865        mut orig: EntityMut<'from, T>,
866        f: F,
867    ) -> EntityProjectionMut<'from, To>
868    where
869        F: FnOnce(&'to mut T) -> To,
870        To: 'to,
871    {
872        EntityProjectionMut {
873            value: f(unsafe { orig.value.as_mut() }),
874            borrow: orig.borrow,
875        }
876    }
877
878    /// Splits an `EntityMut` into multiple `EntityMut`s for different components of the borrowed
879    /// data.
880    ///
881    /// The underlying entity will remain mutably borrowed until both returned `EntityMut`s go out
882    /// of scope.
883    ///
884    /// The entity is already mutably borrowed, so this cannot fail.
885    ///
886    /// This is an associated function that needs to be used as `EntityMut::map_split(...)`, so as
887    /// to avoid conflicting with any method of the same name accessible via the `Deref` impl.
888    ///
889    /// # Examples
890    ///
891    /// ```rust
892    /// use midenc_hir::*;
893    /// use blink_alloc::Blink;
894    ///
895    /// let alloc = Blink::default();
896    /// let mut entity = UnsafeEntityRef::new([1, 2, 3, 4], &alloc);
897    /// let borrow = entity.borrow_mut();
898    /// let (mut begin, mut end) = EntityMut::map_split(borrow, |slice| slice.split_at_mut(2));
899    /// assert_eq!(*begin, [1, 2]);
900    /// assert_eq!(*end, [3, 4]);
901    /// begin.copy_from_slice(&[4, 3]);
902    /// end.copy_from_slice(&[2, 1]);
903    /// ```
904    #[inline]
905    pub fn map_split<U: ?Sized, V: ?Sized, F>(
906        mut orig: Self,
907        f: F,
908    ) -> (EntityMut<'b, U>, EntityMut<'b, V>)
909    where
910        F: FnOnce(&mut T) -> (&mut U, &mut V),
911    {
912        let borrow = orig.borrow.clone();
913        let (a, b) = f(&mut *orig);
914        (
915            EntityMut {
916                value: NonNull::from(a),
917                borrow,
918                _marker: core::marker::PhantomData,
919            },
920            EntityMut {
921                value: NonNull::from(b),
922                borrow: orig.borrow,
923                _marker: core::marker::PhantomData,
924            },
925        )
926    }
927
928    /// Convert this mutable borrow into an immutable borrow
929    pub fn into_entity_ref(self) -> EntityRef<'b, T> {
930        let value = self.value;
931        let borrow = self.into_borrow_ref_mut();
932
933        EntityRef {
934            value,
935            borrow: borrow.into_borrow_ref(),
936        }
937    }
938
939    #[doc(hidden)]
940    pub(crate) fn into_borrow_ref_mut(self) -> BorrowRefMut<'b> {
941        self.borrow
942    }
943
944    #[allow(unused)]
945    pub(crate) fn from_raw_parts(value: NonNull<T>, borrow: BorrowRefMut<'b>) -> Self {
946        Self {
947            value,
948            borrow,
949            _marker: core::marker::PhantomData,
950        }
951    }
952}
953impl<T: ?Sized> Deref for EntityMut<'_, T> {
954    type Target = T;
955
956    #[inline]
957    fn deref(&self) -> &T {
958        // SAFETY: the value is accessible as long as we hold our borrow.
959        unsafe { self.value.as_ref() }
960    }
961}
962impl<T: ?Sized> DerefMut for EntityMut<'_, T> {
963    #[inline]
964    fn deref_mut(&mut self) -> &mut T {
965        // SAFETY: the value is accessible as long as we hold our borrow.
966        unsafe { self.value.as_mut() }
967    }
968}
969
970impl<'b, T, U> core::ops::CoerceUnsized<EntityMut<'b, U>> for EntityMut<'b, T>
971where
972    T: ?Sized + core::marker::Unsize<U>,
973    U: ?Sized,
974{
975}
976
977impl<T: ?Sized + fmt::Debug> fmt::Debug for EntityMut<'_, T> {
978    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
979        (**self).fmt(f)
980    }
981}
982impl<T: ?Sized + fmt::Display> fmt::Display for EntityMut<'_, T> {
983    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
984        (**self).fmt(f)
985    }
986}
987impl<T: ?Sized + crate::formatter::PrettyPrint> crate::formatter::PrettyPrint for EntityMut<'_, T> {
988    #[inline]
989    fn render(&self) -> crate::formatter::Document {
990        (**self).render()
991    }
992}
993impl<T: ?Sized + Eq> Eq for EntityMut<'_, T> {}
994impl<T: ?Sized + PartialEq> PartialEq for EntityMut<'_, T> {
995    fn eq(&self, other: &Self) -> bool {
996        **self == **other
997    }
998}
999impl<T: ?Sized + PartialOrd> PartialOrd for EntityMut<'_, T> {
1000    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1001        (**self).partial_cmp(&**other)
1002    }
1003
1004    fn ge(&self, other: &Self) -> bool {
1005        **self >= **other
1006    }
1007
1008    fn gt(&self, other: &Self) -> bool {
1009        **self > **other
1010    }
1011
1012    fn le(&self, other: &Self) -> bool {
1013        **self <= **other
1014    }
1015
1016    fn lt(&self, other: &Self) -> bool {
1017        **self < **other
1018    }
1019}
1020impl<T: ?Sized + Ord> Ord for EntityMut<'_, T> {
1021    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1022        (**self).cmp(&**other)
1023    }
1024}
1025impl<T: ?Sized + Hash> Hash for EntityMut<'_, T> {
1026    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
1027        (**self).hash(state);
1028    }
1029}
1030
1031/// Represents a projection of an [EntityRef] into an owned value.
1032///
1033/// This retains the lifetime of the borrow, while allowing the projection itself to be owned. This
1034/// is useful in cases where you would like to return a value derived from an [EntityRef] from a
1035/// function, when the borrowed entity outlives the function itself. Since [EntityRef] can only
1036/// represent references, deriving owned (but semantically borrowed) values from an [EntityRef]
1037/// cannot be returned from an enclosing function, unlike if the value was a reference.
1038///
1039/// NOTE: An [EntityProjection] takes ownership of the [EntityRef] from which it was derived, and
1040/// propagates the lifetime of the borrowed entity. When this type is dropped, so is the original
1041/// borrow.
1042pub struct EntityProjection<'b, T: 'b> {
1043    borrow: BorrowRef<'b>,
1044    value: T,
1045}
1046impl<T> core::ops::Deref for EntityProjection<'_, T> {
1047    type Target = T;
1048
1049    #[inline(always)]
1050    fn deref(&self) -> &Self::Target {
1051        &self.value
1052    }
1053}
1054impl<T> core::ops::DerefMut for EntityProjection<'_, T> {
1055    #[inline(always)]
1056    fn deref_mut(&mut self) -> &mut Self::Target {
1057        &mut self.value
1058    }
1059}
1060impl<'b, T> EntityProjection<'b, T> {
1061    pub fn map<U, F>(orig: Self, f: F) -> EntityProjection<'b, U>
1062    where
1063        F: FnOnce(T) -> U,
1064    {
1065        EntityProjection {
1066            value: f(orig.value),
1067            borrow: orig.borrow,
1068        }
1069    }
1070}
1071impl<T: fmt::Debug> fmt::Debug for EntityProjection<'_, T> {
1072    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1073        fmt::Debug::fmt(&self.value, f)
1074    }
1075}
1076impl<T: fmt::Display> fmt::Display for EntityProjection<'_, T> {
1077    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1078        fmt::Display::fmt(&self.value, f)
1079    }
1080}
1081impl<T: crate::formatter::PrettyPrint> crate::formatter::PrettyPrint for EntityProjection<'_, T> {
1082    #[inline]
1083    fn render(&self) -> crate::formatter::Document {
1084        crate::formatter::PrettyPrint::render(&self.value)
1085    }
1086}
1087impl<T: Eq> Eq for EntityProjection<'_, T> {}
1088impl<T: PartialEq> PartialEq for EntityProjection<'_, T> {
1089    fn eq(&self, other: &Self) -> bool {
1090        self.value == other.value
1091    }
1092}
1093impl<T: PartialOrd> PartialOrd for EntityProjection<'_, T> {
1094    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1095        self.value.partial_cmp(&other.value)
1096    }
1097
1098    fn ge(&self, other: &Self) -> bool {
1099        self.value.ge(&other.value)
1100    }
1101
1102    fn gt(&self, other: &Self) -> bool {
1103        self.value.gt(&other.value)
1104    }
1105
1106    fn le(&self, other: &Self) -> bool {
1107        self.value.le(&other.value)
1108    }
1109
1110    fn lt(&self, other: &Self) -> bool {
1111        self.value.lt(&other.value)
1112    }
1113}
1114impl<T: Ord> Ord for EntityProjection<'_, T> {
1115    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1116        self.value.cmp(&other.value)
1117    }
1118}
1119impl<T: Hash> Hash for EntityProjection<'_, T> {
1120    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
1121        self.value.hash(state)
1122    }
1123}
1124
1125/// Represents a projection of an [EntityMut] into an owned value.
1126///
1127/// This retains the lifetime of the borrow, while allowing the projection itself to be owned. This
1128/// is useful in cases where you would like to return a value derived from an [EntityMut] from a
1129/// function, when the borrowed entity outlives the function itself. Since [EntityMut] can only
1130/// represent references, deriving owned (but semantically borrowed) values from an [EntityMut]
1131/// cannot be returned from an enclosing function, unlike if the value was a reference.
1132///
1133/// NOTE: An [EntityProjectionMut] takes ownership of the [EntityMut] from which it was derived, and
1134/// propagates the lifetime of the borrowed entity. When this type is dropped, so is the original
1135/// borrow.
1136pub struct EntityProjectionMut<'b, T: 'b> {
1137    borrow: BorrowRefMut<'b>,
1138    value: T,
1139}
1140impl<T> core::ops::Deref for EntityProjectionMut<'_, T> {
1141    type Target = T;
1142
1143    #[inline(always)]
1144    fn deref(&self) -> &Self::Target {
1145        &self.value
1146    }
1147}
1148impl<T> core::ops::DerefMut for EntityProjectionMut<'_, T> {
1149    #[inline(always)]
1150    fn deref_mut(&mut self) -> &mut Self::Target {
1151        &mut self.value
1152    }
1153}
1154impl<'b, T> EntityProjectionMut<'b, T> {
1155    pub fn map<U, F>(orig: Self, f: F) -> EntityProjectionMut<'b, U>
1156    where
1157        F: FnOnce(T) -> U,
1158    {
1159        EntityProjectionMut {
1160            value: f(orig.value),
1161            borrow: orig.borrow,
1162        }
1163    }
1164}
1165impl<T: fmt::Debug> fmt::Debug for EntityProjectionMut<'_, T> {
1166    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1167        fmt::Debug::fmt(&self.value, f)
1168    }
1169}
1170impl<T: fmt::Display> fmt::Display for EntityProjectionMut<'_, T> {
1171    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1172        fmt::Display::fmt(&self.value, f)
1173    }
1174}
1175impl<T: crate::formatter::PrettyPrint> crate::formatter::PrettyPrint
1176    for EntityProjectionMut<'_, T>
1177{
1178    #[inline]
1179    fn render(&self) -> crate::formatter::Document {
1180        crate::formatter::PrettyPrint::render(&self.value)
1181    }
1182}
1183impl<T: Eq> Eq for EntityProjectionMut<'_, T> {}
1184impl<T: PartialEq> PartialEq for EntityProjectionMut<'_, T> {
1185    fn eq(&self, other: &Self) -> bool {
1186        self.value == other.value
1187    }
1188}
1189impl<T: PartialOrd> PartialOrd for EntityProjectionMut<'_, T> {
1190    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1191        self.value.partial_cmp(&other.value)
1192    }
1193
1194    fn ge(&self, other: &Self) -> bool {
1195        self.value.ge(&other.value)
1196    }
1197
1198    fn gt(&self, other: &Self) -> bool {
1199        self.value.gt(&other.value)
1200    }
1201
1202    fn le(&self, other: &Self) -> bool {
1203        self.value.le(&other.value)
1204    }
1205
1206    fn lt(&self, other: &Self) -> bool {
1207        self.value.lt(&other.value)
1208    }
1209}
1210impl<T: Ord> Ord for EntityProjectionMut<'_, T> {
1211    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1212        self.value.cmp(&other.value)
1213    }
1214}
1215impl<T: Hash> Hash for EntityProjectionMut<'_, T> {
1216    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
1217        self.value.hash(state)
1218    }
1219}
1220
1221// This type wraps the entity data with extra metadata we want to associate with the entity, but
1222// separately from it, so that pointers to the metadata do not cause aliasing violations if the
1223// entity itself is borrowed.
1224//
1225// The kind of metadata stored here is unconstrained, but in practice should be limited to things
1226// that you _need_ to be able to access from a `RawEntityRef`, without aliasing the entity. For now
1227// the main reason we use this is for the intrusive link used to store entities in an intrusive
1228// linked list. We don't want traversing the intrusive list to require borrowing the entity, only
1229// the link, unless we explicitly want to borrow the entity, thus we use the metadata field here
1230// to hold the link.
1231//
1232// This has to be `pub` for implementing the traits required for the intrusive collections
1233// integration, but its internals are hidden outside this module, and we hide it from the generated
1234// docs as well.
1235#[repr(C)]
1236#[doc(hidden)]
1237pub struct RawEntityMetadata<T: ?Sized, Metadata> {
1238    metadata: Metadata,
1239    entity: RawEntity<T>,
1240}
1241impl<T, Metadata> RawEntityMetadata<T, Metadata> {
1242    pub(crate) fn new(value: T, metadata: Metadata) -> Self {
1243        Self {
1244            metadata,
1245            entity: RawEntity::new(value),
1246        }
1247    }
1248}
1249impl<T: ?Sized, Metadata> RawEntityMetadata<T, Metadata> {
1250    #[track_caller]
1251    pub(crate) fn borrow(&self) -> EntityRef<'_, T> {
1252        let ptr = self as *const Self;
1253        unsafe { (*core::ptr::addr_of!((*ptr).entity)).borrow() }
1254    }
1255
1256    #[track_caller]
1257    pub(crate) fn borrow_mut(&self) -> EntityMut<'_, T> {
1258        let ptr = (self as *const Self).cast_mut();
1259        unsafe { (*core::ptr::addr_of_mut!((*ptr).entity)).borrow_mut() }
1260    }
1261
1262    #[inline]
1263    const fn metadata_offset() -> usize {
1264        core::mem::offset_of!(RawEntityMetadata<(), Metadata>, metadata)
1265    }
1266
1267    /// Get the offset within a `RawEntityMetadata` for the payload behind a pointer.
1268    ///
1269    /// # Safety
1270    ///
1271    /// The pointer must point to (and have valid metadata for) a previously valid instance of T, but
1272    /// the T is allowed to be dropped.
1273    unsafe fn data_offset(ptr: *const T) -> usize {
1274        use core::mem::align_of_val_raw;
1275
1276        // Align the unsized value to the end of the RawEntityMetadata.
1277        // Because RawEntityMetadata/RawEntity is repr(C), it will always be the last field in memory.
1278        //
1279        // SAFETY: since the only unsized types possible are slices, trait objects, and extern types,
1280        // the input safety requirement is currently enough to satisfy the requirements of
1281        // align_of_val_raw; but this is an implementation detail of the language that is unstable
1282        unsafe { RawEntityMetadata::<(), Metadata>::data_offset_align(align_of_val_raw(ptr)) }
1283    }
1284
1285    #[inline]
1286    fn data_offset_align(align: usize) -> usize {
1287        let layout = Layout::new::<RawEntityMetadata<(), Metadata>>();
1288        layout.size() + layout.padding_needed_for(align)
1289    }
1290}
1291
1292fn raw_entity_metadata_layout_for_value_layout<Metadata>(layout: Layout) -> Layout {
1293    Layout::new::<RawEntityMetadata<(), Metadata>>()
1294        .extend(layout)
1295        .unwrap()
1296        .0
1297        .pad_to_align()
1298}
1299
1300/// A [RawEntity] wraps an entity to be allocated in a [Context], and provides dynamic borrow-
1301/// checking functionality for [UnsafeEntityRef], thereby protecting the entity by ensuring that
1302/// all accesses adhere to Rust's aliasing rules.
1303#[repr(C)]
1304pub struct RawEntity<T: ?Sized> {
1305    borrow: Cell<BorrowFlag>,
1306    #[cfg(debug_assertions)]
1307    borrowed_at: Cell<Option<&'static core::panic::Location<'static>>>,
1308    cell: UnsafeCell<T>,
1309}
1310
1311impl<T> RawEntity<T> {
1312    pub fn new(value: T) -> Self {
1313        Self {
1314            borrow: Cell::new(BorrowFlag::UNUSED),
1315            #[cfg(debug_assertions)]
1316            borrowed_at: Cell::new(None),
1317            cell: UnsafeCell::new(value),
1318        }
1319    }
1320
1321    #[allow(unused)]
1322    #[doc(hidden)]
1323    #[inline(always)]
1324    pub(crate) fn entity_addr(&self) -> *mut T {
1325        self.cell.get()
1326    }
1327
1328    #[allow(unused)]
1329    #[doc(hidden)]
1330    #[inline(always)]
1331    pub(crate) const fn entity_offset(&self) -> usize {
1332        core::mem::offset_of!(Self, cell)
1333    }
1334}
1335
1336impl<T, U> core::ops::CoerceUnsized<RawEntity<U>> for RawEntity<T> where
1337    T: core::ops::CoerceUnsized<U>
1338{
1339}
1340
1341impl<T: ?Sized> RawEntity<T> {
1342    /// Construct a borrow of this [RawEntity], returning the raw borrow components.
1343    ///
1344    /// # Safety
1345    ///
1346    /// Callers may only use the returned pointer while holding the corresponding [BorrowRef],
1347    /// otherwise there is no protection against mutable aliasing of the underlying data.
1348    #[track_caller]
1349    #[allow(unused)]
1350    pub unsafe fn borrow_unsafe(&self) -> (NonNull<T>, BorrowRef<'_>) {
1351        match self.try_borrow() {
1352            Ok(b) => (b.value, b.into_borrow_ref()),
1353            Err(err) => panic_aliasing_violation(err),
1354        }
1355    }
1356
1357    /// Construct a mutable borrow of this [RawEntity], returning the raw borrow components.
1358    ///
1359    /// # Safety
1360    ///
1361    /// Callers may only use the returned pointer while holding the corresponding [BorrowRefMut],
1362    /// otherwise there is no protection against mutable aliasing of the underlying data.
1363    #[track_caller]
1364    pub unsafe fn borrow_mut_unsafe(&self) -> (NonNull<T>, BorrowRefMut<'_>) {
1365        match self.try_borrow_mut() {
1366            Ok(b) => (b.value, b.into_borrow_ref_mut()),
1367            Err(err) => panic_aliasing_violation(err),
1368        }
1369    }
1370
1371    #[track_caller]
1372    #[inline]
1373    pub fn borrow(&self) -> EntityRef<'_, T> {
1374        match self.try_borrow() {
1375            Ok(b) => b,
1376            Err(err) => panic_aliasing_violation(err),
1377        }
1378    }
1379
1380    #[inline]
1381    #[track_caller]
1382    pub fn try_borrow(&self) -> Result<EntityRef<'_, T>, AliasingViolationError> {
1383        match BorrowRef::new(&self.borrow) {
1384            Some(b) => {
1385                #[cfg(debug_assertions)]
1386                {
1387                    // `borrowed_at` is always the *first* active borrow
1388                    if b.borrow.get() == BorrowFlag(1) {
1389                        self.borrowed_at.set(Some(core::panic::Location::caller()));
1390                    }
1391                }
1392
1393                // SAFETY: `BorrowRef` ensures that there is only immutable access to the value
1394                // while borrowed.
1395                let value = unsafe { NonNull::new_unchecked(self.cell.get()) };
1396                Ok(EntityRef { value, borrow: b })
1397            }
1398            None => Err(AliasingViolationError {
1399                #[cfg(debug_assertions)]
1400                location: self.borrowed_at.get().unwrap(),
1401                kind: AliasingViolationKind::Immutable,
1402            }),
1403        }
1404    }
1405
1406    #[inline]
1407    #[track_caller]
1408    pub fn borrow_mut(&self) -> EntityMut<'_, T> {
1409        match self.try_borrow_mut() {
1410            Ok(b) => b,
1411            Err(err) => panic_aliasing_violation(err),
1412        }
1413    }
1414
1415    #[inline]
1416    #[track_caller]
1417    pub fn try_borrow_mut(&self) -> Result<EntityMut<'_, T>, AliasingViolationError> {
1418        match BorrowRefMut::new(&self.borrow) {
1419            Some(b) => {
1420                #[cfg(debug_assertions)]
1421                {
1422                    self.borrowed_at.set(Some(core::panic::Location::caller()));
1423                }
1424
1425                // SAFETY: `BorrowRefMut` guarantees unique access.
1426                let value = unsafe { NonNull::new_unchecked(self.cell.get()) };
1427                Ok(EntityMut {
1428                    value,
1429                    borrow: b,
1430                    _marker: core::marker::PhantomData,
1431                })
1432            }
1433            None => Err(AliasingViolationError {
1434                // If a borrow occurred, then we must already have an outstanding borrow,
1435                // so `borrowed_at` will be `Some`
1436                #[cfg(debug_assertions)]
1437                location: self.borrowed_at.get().unwrap(),
1438                kind: AliasingViolationKind::Mutable,
1439            }),
1440        }
1441    }
1442}
1443
1444#[doc(hidden)]
1445pub struct BorrowRef<'b> {
1446    borrow: &'b Cell<BorrowFlag>,
1447}
1448impl<'b> BorrowRef<'b> {
1449    #[inline]
1450    fn new(borrow: &'b Cell<BorrowFlag>) -> Option<Self> {
1451        let b = borrow.get().wrapping_add(1);
1452        if !b.is_reading() {
1453            // Incrementing borrow can result in a non-reading value (<= 0) in these cases:
1454            // 1. It was < 0, i.e. there are writing borrows, so we can't allow a read borrow due to
1455            //    Rust's reference aliasing rules
1456            // 2. It was isize::MAX (the max amount of reading borrows) and it overflowed into
1457            //    isize::MIN (the max amount of writing borrows) so we can't allow an additional
1458            //    read borrow because isize can't represent so many read borrows (this can only
1459            //    happen if you mem::forget more than a small constant amount of `EntityRef`s, which
1460            //    is not good practice)
1461            None
1462        } else {
1463            // Incrementing borrow can result in a reading value (> 0) in these cases:
1464            // 1. It was = 0, i.e. it wasn't borrowed, and we are taking the first read borrow
1465            // 2. It was > 0 and < isize::MAX, i.e. there were read borrows, and isize is large
1466            //    enough to represent having one more read borrow
1467            borrow.set(b);
1468            Some(Self { borrow })
1469        }
1470    }
1471
1472    /// Convert this immutable borrow into a mutable one, if it is the sole immutable borrow.
1473    pub fn try_into_mut(self) -> Result<BorrowRefMut<'b>, Self> {
1474        use core::mem::ManuallyDrop;
1475
1476        // Ensure we don't try to modify the borrow flag when this BorrowRef goes out of scope
1477        let this = ManuallyDrop::new(self);
1478        let b = this.borrow.get();
1479        debug_assert!(b.is_reading());
1480        if (b - 1).is_unused() {
1481            this.borrow.set(BorrowFlag::UNUSED - 1);
1482            Ok(BorrowRefMut {
1483                borrow: this.borrow,
1484            })
1485        } else {
1486            Err(ManuallyDrop::into_inner(this))
1487        }
1488    }
1489}
1490impl Drop for BorrowRef<'_> {
1491    #[inline]
1492    fn drop(&mut self) {
1493        let borrow = self.borrow.get();
1494        debug_assert!(borrow.is_reading());
1495        self.borrow.set(borrow - 1);
1496    }
1497}
1498impl Clone for BorrowRef<'_> {
1499    #[inline]
1500    fn clone(&self) -> Self {
1501        // Since this Ref exists, we know the borrow flag
1502        // is a reading borrow.
1503        let borrow = self.borrow.get();
1504        debug_assert!(borrow.is_reading());
1505        // Prevent the borrow counter from overflowing into
1506        // a writing borrow.
1507        assert!(borrow != BorrowFlag::MAX);
1508        self.borrow.set(borrow + 1);
1509        BorrowRef {
1510            borrow: self.borrow,
1511        }
1512    }
1513}
1514
1515#[doc(hidden)]
1516pub struct BorrowRefMut<'b> {
1517    borrow: &'b Cell<BorrowFlag>,
1518}
1519impl Drop for BorrowRefMut<'_> {
1520    #[inline]
1521    fn drop(&mut self) {
1522        let borrow = self.borrow.get();
1523        debug_assert!(borrow.is_writing());
1524        self.borrow.set(borrow + 1);
1525    }
1526}
1527impl<'b> BorrowRefMut<'b> {
1528    /// Consume this mutable borrow and convert it into a immutable one without releasing it
1529    pub fn into_borrow_ref(self) -> BorrowRef<'b> {
1530        let borrow = self.borrow;
1531        debug_assert!(borrow.get().is_writing());
1532        borrow.set(borrow.get() + 2);
1533        core::mem::forget(self);
1534        BorrowRef { borrow }
1535    }
1536
1537    #[inline]
1538    fn new(borrow: &'b Cell<BorrowFlag>) -> Option<Self> {
1539        // NOTE: Unlike BorrowRefMut::clone, new is called to create the initial
1540        // mutable reference, and so there must currently be no existing
1541        // references. Thus, while clone increments the mutable refcount, here
1542        // we explicitly only allow going from UNUSED to UNUSED - 1.
1543        match borrow.get() {
1544            BorrowFlag::UNUSED => {
1545                borrow.set(BorrowFlag::UNUSED - 1);
1546                Some(Self { borrow })
1547            }
1548            _ => None,
1549        }
1550    }
1551
1552    // Clones a `BorrowRefMut`.
1553    //
1554    // This is only valid if each `BorrowRefMut` is used to track a mutable
1555    // reference to a distinct, nonoverlapping range of the original object.
1556    // This isn't in a Clone impl so that code doesn't call this implicitly.
1557    #[inline]
1558    fn clone(&self) -> Self {
1559        let borrow = self.borrow.get();
1560        debug_assert!(borrow.is_writing());
1561        // Prevent the borrow counter from underflowing.
1562        assert!(borrow != BorrowFlag::MIN);
1563        self.borrow.set(borrow - 1);
1564        Self {
1565            borrow: self.borrow,
1566        }
1567    }
1568}
1569
1570/// Positive values represent the number of outstanding immutable borrows, while negative values
1571/// represent the number of outstanding mutable borrows. Multiple mutable borrows can only be
1572/// active simultaneously if they refer to distinct, non-overlapping components of an entity.
1573#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
1574#[repr(transparent)]
1575struct BorrowFlag(isize);
1576impl BorrowFlag {
1577    const MAX: Self = Self(isize::MAX);
1578    const MIN: Self = Self(isize::MIN);
1579    const UNUSED: Self = Self(0);
1580
1581    #[allow(unused)]
1582    pub fn is_unused(&self) -> bool {
1583        self.0 == Self::UNUSED.0
1584    }
1585
1586    pub fn is_writing(&self) -> bool {
1587        self.0 < Self::UNUSED.0
1588    }
1589
1590    pub fn is_reading(&self) -> bool {
1591        self.0 > Self::UNUSED.0
1592    }
1593
1594    #[inline]
1595    pub const fn wrapping_add(self, rhs: isize) -> Self {
1596        Self(self.0.wrapping_add(rhs))
1597    }
1598}
1599impl core::ops::Add<isize> for BorrowFlag {
1600    type Output = BorrowFlag;
1601
1602    #[inline]
1603    fn add(self, rhs: isize) -> Self::Output {
1604        Self(self.0 + rhs)
1605    }
1606}
1607impl core::ops::Sub<isize> for BorrowFlag {
1608    type Output = BorrowFlag;
1609
1610    #[inline]
1611    fn sub(self, rhs: isize) -> Self::Output {
1612        Self(self.0 - rhs)
1613    }
1614}
1615
1616// This ensures the panicking code is outlined from `borrow` and `borrow_mut` for `EntityObj`.
1617#[cfg_attr(not(panic = "abort"), inline(never))]
1618#[track_caller]
1619#[cold]
1620fn panic_aliasing_violation(err: AliasingViolationError) -> ! {
1621    panic!("{err:?}")
1622}