zerogc/
lib.rs

1// NOTE: Both these features have accepted RFCs
2#![feature(
3    const_panic, // RFC 2345 - Const asserts
4)]
5#![deny(missing_docs)]
6#![cfg_attr(not(feature = "std"), no_std)]
7//! Zero overhead tracing garbage collection for rust,
8//! by abusing the borrow checker.
9//!
10//! ## Features
11//! 1. Easy to use, since `Gc<T>` is `Copy` and coerces to a reference.
12//! 2. Absolutely zero overhead when modifying pointers, since `Gc<T>` is `Copy`.
13//! 3. Implementation agnostic API
14//! 4. Unsafe code has complete freedom to manipulate garbage collected pointers, and it doesn't need to understand the distinction
15//! 5. Uses rust's lifetime system to ensure all roots are known at explicit safepoints, without any runtime overhead.
16//! 6. Collection can only happen with an explicit `safepoint` call and has no overhead between these calls,
17//! 7. API supports moving objects (allowing copying/generational GCs)
18
19#![cfg(any(feature = "alloc", feature = "std"))]
20extern crate alloc;
21
22/*
23 * I want this library to use 'mostly' stable features,
24 * unless there's good justification to use an unstable feature.
25 */
26use core::mem;
27use core::ops::{Deref, DerefMut};
28use core::ptr::NonNull;
29use core::marker::PhantomData;
30use core::hash::{Hash, Hasher};
31use core::fmt::{self, Debug, Formatter};
32
33#[macro_use]
34mod manually_traced;
35pub mod cell;
36pub mod prelude;
37
38/// Invoke the closure with a temporary [GcContext],
39/// then perform a safepoint afterwards.
40///
41/// Normally returns a tuple `($updated_root, $closure_result)`.
42///
43/// If a value is provided it is considered as a root of garbage collection
44/// both for the safepoint and the duration of the entire context.
45///
46/// # Safety
47/// This macro is completely safe, although it expands to unsafe code internally.
48// TODO: Document all forms of this macro
49#[macro_export(local_inner_macros)]
50macro_rules! safepoint_recurse {
51    ($context:ident, |$sub_context:ident| $closure:expr) => {{
52        let ((), result) = safepoint_recurse!($context, (), |$sub_context, new_root| {
53            let () = new_root;
54            $closure
55        });
56        result
57    }};
58    ($context:ident, $root:expr, |$sub_context:ident, $new_root:ident| $closure:expr) => {{
59        let mut root = $root;
60        let result = unsafe { __recurse_context!($context, &mut root, |$sub_context, $new_root| {
61            $closure
62        }) };
63        /*
64         * NOTE: We're assuming result is unmanaged here
65         * The borrow checker will verify this is true (by marking this as a mutation).
66         * If you need a manged result, use the @managed_result variant
67         */
68        let updated_root = safepoint!($context, $root);
69        (updated_root, result)
70    }};
71    ($context:ident, $root:expr, @managed_result, |$sub_context:ident, $new_root:ident| $closure:expr) => {{
72        use $crate::{GcContext};
73        let mut root = $root;
74        let erased_result = unsafe { __recurse_context!(
75            $context, &mut root,
76            |$sub_context, $new_root| {
77                let result = $closure;
78                $sub_context.rebrand_static(result)
79            }
80        ) };
81        /*
82         * Rebrand back to the current collector lifetime
83         * It could have possibly been allocated from the sub-context inside the closure,
84         * but as long as it was valid at the end of the closure it's valid now.
85         * We trust that GcContext::recurse_context
86         * did not perform a collection after calling the closure.
87         */
88        let result = unsafe { $context.rebrand_self(erased_result) };
89        safepoint!($context, (root, result))
90    }};
91}
92
93/// Create a new sub-context for the duration of the closure
94///
95/// The specified `root` object will be appended to the shadowstack
96/// and is guarenteed to live for the entire lifetime of the closure (and the created sub-context).
97///
98/// Unlike `safepoint_recurse!` this doesn't imply a safepoint anywhere.
99///
100/// # Safety
101/// This doesn't actually mutate the original collector.
102/// It is possible user code could trigger a collection in the closure
103/// without the borrow checker noticing invalid pointers elsewhere.
104/// (See docs for [GcContext::recurse_context])
105///
106/// It is not publicly exposed for this reason
107#[macro_export]
108#[doc(hidden)]
109macro_rules! __recurse_context {
110    ($context:ident, $root:expr, |$sub_context:ident, $new_root:ident| $closure:expr) => {{
111        use $crate::{GcContext};
112        // TODO: Panic safety
113        $context.recurse_context(&mut $root, |mut $sub_context, erased_root| {
114            /*
115             * NOTE: Guarenteed to live for the lifetime of the entire closure.
116             * However, it could be relocated if 'sub_collector' is collected
117             */
118            let $new_root = $sub_context.rebrand_self(erased_root);
119            $closure
120        })
121    }};
122}
123
124/// Indicate it's safe to begin a garbage collection,
125/// while keeping the specified root alive.
126///
127/// All other garbage collected pointers that aren't reachable from the root are invalidated.
128/// They have a lifetime that references the [GcRef]
129/// and the borrow checker considers the safepoint a 'mutation'.
130///
131/// The root is exempted from the "mutation" and rebound to the new lifetime.
132///
133/// ## Example
134/// ```
135/// let root = safepoint!(collector, root);
136/// ```
137///
138/// ## Safety
139/// This macro is completely safe, although it expands to unsafe code internally.
140#[macro_export]
141macro_rules! safepoint {
142    ($context:ident, $value:expr) => {unsafe {
143        use $crate::{GcContext};
144        // TODO: What happens if we panic during a collection
145        /*
146         * Some collectors support multiple running instances
147         * with different ids, handing out different GC pointers.
148         * TODO: Should we be checking somehow that the ids match?
149         */
150        let mut erased = $context.rebrand_static($value);
151        $context.basic_safepoint(&mut &mut erased);
152        $context.rebrand_self(erased)
153    }};
154}
155
156/// Indicate its safe to begin a garbage collection (like [safepoint!])
157/// and then "freeze" the specified context.
158///
159/// Until it's unfrozen, the context can't be used for allocation.
160/// Its roots are marked invalid, since the collector could be relocating them.
161/// However, the roots of any parent contexts are still considered valid.
162///
163/// This allows other threads to perform collections *without blocking this thread*.
164#[macro_export]
165macro_rules! freeze_context {
166    ($context:ident) => {unsafe {
167        use $crate::{GcContext, FrozenContext};
168        let mut context = $context;
169        context.freeze();
170        FrozenContext::new(context)
171    }};
172}
173
174/// Unfreeze the context, allowing it to be used again
175///
176/// Returns a [GcContext] struct.
177#[macro_export]
178macro_rules! unfreeze_context {
179    ($frozen:ident) => {unsafe {
180        use $crate::{FrozenContext, GcContext};
181        let mut context = FrozenContext::into_context($frozen);
182        context.unfreeze();
183        context
184    }};
185}
186
187/// A garbage collector implementation.
188///
189/// These implementations should be completely safe and zero-overhead.
190pub unsafe trait GcSystem {
191    /// The type of collector IDs given by this system
192    type Id: CollectorId;
193    /// The type of contexts used in this sytem
194    type Context: GcContext<Id=Self::Id>;
195}
196
197
198/// A system which supports creating handles to [Gc] references.
199///
200/// This type-system hackery is needed because
201/// we need to place bounds on `T as GcBrand`
202// TODO: Remove when we get more powerful types
203pub unsafe trait GcHandleSystem<'gc, T: GcSafe + ?Sized + 'gc>: GcSystem
204    where T: GcBrand<'static, Self::Id>,
205          <T as GcBrand<'static, Self::Id>>::Branded: GcSafe {
206    /// The type of handles to this object.
207    type Handle: GcHandle<<T as GcBrand<'static, Self::Id>>::Branded, System=Self>;
208
209    /// Create a handle to the specified GC pointer,
210    /// which can be used without a context
211    ///
212    /// NOTE: Users should only use from [Gc::create_handle].
213    ///
214    /// The system is implicit in the [Gc]
215    #[doc(hidden)]
216    fn create_handle(gc: Gc<'gc, T, Self::Id>) -> Self::Handle;
217}
218
219/// The context of garbage collection,
220/// which can be frozen at a safepoint.
221///
222/// This is essentially used to maintain a shadow-stack to a set of roots,
223/// which are guarenteed not to be collected until a safepoint.
224///
225/// This context doesn't necessarily support allocation (see [GcSimpleAlloc] for that).
226pub unsafe trait GcContext: Sized {
227    /// The system used with this context
228    type System: GcSystem<Context=Self, Id=Self::Id>;
229    /// The type of ids used in the system
230    type Id: CollectorId;
231
232    /// Inform the garbage collection system we are at a safepoint
233    /// and are ready for a potential garbage collection.
234    ///
235    /// ## Safety
236    /// This method is unsafe and should never be invoked by user code.
237    ///
238    /// See the [safepoint!] macro for a safe wrapper.
239    unsafe fn basic_safepoint<T: Trace>(&mut self, value: &mut &mut T);
240
241    /// Inform the garbage collection system we are at a safepoint
242    /// and are ready for a potential garbage collection.
243    ///
244    /// Unlike a `basic_safepoint`, the collector continues to
245    /// stay at the safepoint instead of returning immediately.
246    /// The context can't be used for anything (including allocations),
247    /// until it is unfrozen.
248    ///
249    /// This allows other threds to perform collections while this
250    /// thread does other work (without using the GC).
251    ///
252    /// The current contexts roots are considered invalid
253    /// for the duration of the collection,
254    /// since the collector could potentially relocate them.
255    ///
256    /// Any parent contexts are fine and their roots will be
257    /// preserved by collections.
258    ///
259    /// ## Safety
260    /// Assumes this context is valid and not already frozen.
261    ///
262    /// Don't invoke this directly
263    unsafe fn freeze(&mut self);
264
265    /// Unfreeze this context, allowing it to be used again.
266    ///
267    /// ## Safety
268    /// Must be a valid context!
269    /// Must be currently frozen!
270    ///
271    /// Don't invoke this directly
272    unsafe fn unfreeze(&mut self);
273
274    #[inline(always)]
275    #[doc(hidden)]
276    unsafe fn rebrand_static<T>(&self, value: T) -> T::Branded
277        where T: GcBrand<'static, Self::Id> {
278        let branded = mem::transmute_copy(&value);
279        mem::forget(value);
280        branded
281    }
282    #[inline(always)]
283    #[doc(hidden)]
284    unsafe fn rebrand_self<'a, T>(&'a self, value: T) -> T::Branded
285        where T: GcBrand<'a, Self::Id> {
286        let branded = mem::transmute_copy(&value);
287        mem::forget(value);
288        branded
289    }
290
291    /// Invoke the closure with a temporary [GcContext].
292    ///
293    /// The specified value is
294    /// guarenteed to live throughout the created context for the closure.
295    /// However, because it could possibly be relocated by a collection,
296    /// it's bound to the lifetime of the sub-collector.
297    ///
298    /// ## Safety
299    /// This macro doesn't imply garbage collection,
300    /// so it doesn't mutate the collector directly.
301    /// However the specified closure could trigger a collection in the sub-context.
302    /// This would in undefined behavior if the collection
303    /// invalidates a pointer tied to this context.
304    ///
305    /// For this reason, this function should never be invoked by user code.
306    ///
307    /// See the [safepoint_recurse!] macro for a safe wrapper
308    unsafe fn recurse_context<T, F, R>(&self, value: &mut &mut T, func: F) -> R
309        where T: Trace, F: for <'gc> FnOnce(&'gc mut Self, &'gc mut T) -> R;
310}
311/// A simple interface to allocating from a [GcContext]. 
312///
313/// Some garbage collectors implement more complex interfaces,
314/// so implementing this is optional
315pub unsafe trait GcSimpleAlloc<'gc, T: GcSafe + 'gc>: GcContext + 'gc {
316    /// Allocate the specified object in this garbage collector,
317    /// binding it to the lifetime of this collector.
318    ///
319    /// The object will never be collected until the next safepoint,
320    /// which is considered a mutation by the borrow checker and will be statically checked.
321    /// Therefore, we can statically guarantee the pointers will survive until the next safepoint.
322    ///
323    /// See `safepoint!` docs on how to properly invoke a safepoint
324    /// and transfer values across it.
325    ///
326    /// This gives a immutable reference to the resulting object.
327    /// Once allocated, the object can only be correctly modified with a `GcCell`
328    fn alloc(&'gc self, value: T) -> Gc<'gc, T, Self::Id>;
329}
330/// The internal representation of a frozen context
331///
332/// ## Safety
333/// Don't use this directly!!!
334#[doc(hidden)]
335#[must_use]
336pub struct FrozenContext<C: GcContext> {
337    /// The frozen context
338    context: C,
339}
340impl<C: GcContext> FrozenContext<C> {
341    #[doc(hidden)]
342    #[inline]
343    pub unsafe fn new(context: C) -> Self {
344        FrozenContext { context }
345    }
346    #[doc(hidden)]
347    #[inline]
348    pub unsafe fn into_context(self) -> C {
349        self.context
350    }
351}
352
353/// Uniquely identifies the collector in case there are
354/// multiple collectors.
355///
356/// ## Safety
357/// To simply the typing, this contains no references to the
358/// lifetime of the associated [GcSystem].
359///
360/// It's implicitly held and is unsafe to access.
361/// As long as the collector is valid,
362/// this id should be too.
363///
364/// It should be safe to assume that a collector exists
365/// if any of its pointers still do!
366pub unsafe trait CollectorId: Copy + Eq + Debug + NullTrace + 'static {
367    /// The type of the garbage collector system
368    type System: GcSystem<Id=Self>;
369    /// Perform a write barrier before writing to a garbage collected field
370    ///
371    /// ## Safety
372    /// Smilar to the [GcDirectBarrier] trait, it can be assumed that
373    /// the field offset is correct and the types match.
374    unsafe fn gc_write_barrier<'gc, T: GcSafe + ?Sized + 'gc, V: GcSafe + ?Sized + 'gc>(
375        owner: &Gc<'gc, T, Self>,
376        value: &Gc<'gc, V, Self>,
377        field_offset: usize
378    );
379
380    /// Assume the ID is valid and use it to access the [GcSystem]
381    ///
382    /// NOTE: The system is bound to the lifetime of *THIS* id.
383    /// A CollectorId may have an internal pointer to the system
384    /// and the pointer may not have a stable address. In other words,
385    /// it may be difficult to reliably take a pointer to a pointer.
386    ///
387    /// ## Safety
388    /// Undefined behavior if the associated collector no longer exists.
389    unsafe fn assume_valid_system(&self) -> &Self::System;
390}
391
392/// A garbage collected pointer to a value.
393///
394/// This is the equivalent of a garbage collected smart-pointer.
395/// It's so smart, you can even coerce it to a reference bound to the lifetime of the `GarbageCollectorRef`.
396/// However, all those references are invalidated by the borrow checker as soon as
397/// your reference to the collector reaches a safepoint.
398/// The objects can only survive garbage collection if they live in this smart-pointer.
399///
400/// The smart pointer is simply a guarantee to the garbage collector
401/// that this points to a garbage collected object with the correct header,
402/// and not some arbitrary bits that you've decided to heap allocate.
403#[repr(C)]
404pub struct Gc<'gc, T: GcSafe + ?Sized + 'gc, Id: CollectorId> {
405    value: NonNull<T>,
406    /// Used to uniquely identify the collector,
407    /// to ensure we aren't modifying another collector's pointers
408    collector_id: Id,
409    marker: PhantomData<&'gc T>,
410}
411impl<'gc, T: GcSafe + ?Sized + 'gc, Id: CollectorId> Gc<'gc, T, Id> {
412    /// Create a GC pointer from a raw ID/pointer pair
413    ///
414    /// ## Safety
415    /// Undefined behavior if the underlying pointer is not valid
416    /// and associated with the collector corresponding to the id.
417    #[inline(always)]
418    pub unsafe fn from_raw(id: Id, value: NonNull<T>) -> Self {
419        Gc { collector_id: id, value, marker: PhantomData }
420    }
421
422    /// The value of the underlying pointer
423    #[inline(always)]
424    pub fn value(&self) -> &'gc T {
425        unsafe { *(&self.value as *const NonNull<T> as *const &'gc T) }
426    }
427    /// Cast this reference to a raw pointer
428    ///
429    /// ## Safety
430    /// It's undefined behavior to mutate the
431    /// value.
432    /// The pointer is only valid as long as
433    /// the reference is.
434    #[inline]
435    pub unsafe fn as_raw_ptr(&self) -> *mut T {
436        self.value.as_ptr() as *const T as *mut T
437    }
438
439
440    /// Create a handle to this object, which can be used without a context
441    #[inline]
442    pub fn create_handle(&self) -> <Id::System as GcHandleSystem<'gc, T>>::Handle
443        where Id::System: GcHandleSystem<'gc, T>,
444              T: GcBrand<'static, Id>,
445              <T as GcBrand<'static, Id>>::Branded: GcSafe {
446        <Id::System as GcHandleSystem<'gc, T>>::create_handle(*self)
447    }
448
449    /// Get a reference to the system
450    ///
451    /// ## Safety
452    /// This is based on the assumption that a [GcSystem] must outlive
453    /// all of the pointers it owns.
454    /// Although it could be restricted to the lifetime of the [CollectorId]
455    /// (in theory that may have an internal pointer) it will still live for '&self'.
456    #[inline]
457    pub fn system(&self) -> &'_ Id::System {
458        // This assumption is safe - see the docs
459        unsafe { self.collector_id.assume_valid_system() }
460    }
461
462    /// Get a copy of the collector's id
463    ///
464    /// The underlying collector it points to is not necessarily always valid
465    #[inline]
466    pub fn collector_id(&self) -> Id {
467        self.collector_id
468    }
469}
470
471/// Double-indirection is completely safe
472unsafe impl<'gc, T: GcSafe + 'gc, Id: CollectorId> GcSafe for Gc<'gc, T, Id> {
473    const NEEDS_DROP: bool = true; // We are Copy
474}
475/// Rebrand
476unsafe impl<'gc, 'new_gc, T, Id> GcBrand<'new_gc, Id> for Gc<'gc, T, Id>
477    where T: GcSafe + GcBrand<'new_gc, Id>,
478          T::Branded: GcSafe, Id: CollectorId {
479    type Branded = Gc<'new_gc, <T as GcBrand<'new_gc, Id>>::Branded, Id>;
480}
481unsafe impl<'gc, T: GcSafe + 'gc, Id: CollectorId> Trace for Gc<'gc, T, Id> {
482    // We always need tracing....
483    const NEEDS_TRACE: bool = true;
484
485    #[inline]
486    fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err> {
487        unsafe {
488            // We're doing this correctly!
489            V::visit_gc(visitor, self)
490        }
491    }
492}
493impl<'gc, T: GcSafe + 'gc, Id: CollectorId> Deref for Gc<'gc, T, Id> {
494    type Target = &'gc T;
495
496    #[inline(always)]
497    fn deref(&self) -> &Self::Target {
498        unsafe { &*(&self.value as *const NonNull<T> as *const &'gc T) }
499    }
500}
501unsafe impl<'gc, O, V, Id> GcDirectBarrier<'gc, Gc<'gc, O, Id>> for Gc<'gc, V,Id>
502    where O: GcSafe + 'gc, V: GcSafe + 'gc, Id: CollectorId {
503    #[inline(always)]
504    unsafe fn write_barrier(&self, owner: &Gc<'gc, O, Id>, field_offset: usize) {
505        Id::gc_write_barrier(owner, self, field_offset)
506    }
507}
508// We can be copied freely :)
509impl<'gc, T: GcSafe + ?Sized + 'gc, Id: CollectorId> Copy for Gc<'gc, T, Id> {}
510impl<'gc, T: GcSafe + ?Sized + 'gc, Id: CollectorId> Clone for Gc<'gc, T, Id> {
511    #[inline(always)]
512    fn clone(&self) -> Self {
513        *self
514    }
515}
516// Delegating impls
517impl<'gc, T: GcSafe + Hash + 'gc, Id: CollectorId> Hash for Gc<'gc, T, Id> {
518    #[inline]
519    fn hash<H: Hasher>(&self, state: &mut H) {
520        self.value().hash(state)
521    }
522}
523impl<'gc, T: GcSafe + PartialEq + 'gc, Id: CollectorId> PartialEq for Gc<'gc, T, Id> {
524    #[inline]
525    fn eq(&self, other: &Self) -> bool {
526        // NOTE: We compare by value, not identity
527        self.value() == other.value()
528    }
529}
530impl<'gc, T: GcSafe + Eq + 'gc, Id: CollectorId> Eq for Gc<'gc, T, Id> {}
531impl<'gc, T: GcSafe + PartialEq + 'gc, Id: CollectorId> PartialEq<T> for Gc<'gc, T, Id> {
532    #[inline]
533    fn eq(&self, other: &T) -> bool {
534        self.value() == other
535    }
536}
537impl<'gc, T: GcSafe + Debug + 'gc, Id: CollectorId> Debug for Gc<'gc, T, Id> {
538    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
539        if !f.alternate() {
540            // Pretend we're a newtype by default
541            f.debug_tuple("Gc").field(self.value()).finish()
542        } else {
543            // Alternate spec reveals `collector_id`
544            f.debug_struct("Gc")
545                .field("collector_id", &self.collector_id)
546                .field("value", self.value())
547                .finish()
548        }
549    }
550}
551
552/// In order to send *references* between threads,
553/// the underlying type must be sync.
554///
555/// This is the same reason that `Arc<T>: Send` requires `T: Sync`
556unsafe impl<'gc, T, Id> Send for Gc<'gc, T, Id>
557    where T: GcSafe + ?Sized + Sync, Id: CollectorId + Sync {}
558
559/// If the underlying type is `Sync`, it's safe
560/// to share garbage collected references between threads.
561///
562/// The safety of the collector itself depends on whether [CollectorId] is Sync.
563/// If it is, the whole garbage collection implenentation should be as well.
564unsafe impl<'gc, T, Id> Sync for Gc<'gc, T, Id>
565    where T: GcSafe + ?Sized + Sync, Id: CollectorId + Sync {}
566
567/// A owned handle which points to a garbage collected object.
568///
569/// This is considered a root by the garbage collector that is independent
570/// of any specific [GcContext]. Safepoints
571/// don't need to be informed of this object for collection to start.
572/// The root is manually managed by user-code, much like a [Box] or
573/// a reference counted pointer.
574///
575/// This can be cloned and stored independently from a context,
576/// bridging the gap between native memory and managed memory.
577/// These are useful to pass to C APIs or any other code
578/// that doesn't cooperate with zerogc.
579///
580/// ## Tracing
581/// The object behind this handle is already considered a root of the collection.
582/// It should always be considered reachable by the garbage collector.
583///
584/// Validity is tracked by this smart-pointer and not by tracing.
585/// Therefore it is safe to implement [NullTrace] for handles.
586/*
587 * TODO: Should we drop the Clone requirement?
588 */
589pub unsafe trait GcHandle<T: GcSafe + ?Sized>: Clone + NullTrace {
590    /// The type of the system used with this handle
591    type System: GcSystem<Id=Self::Id>;
592    /// The type of [CollectorId] used with this sytem
593    type Id: CollectorId;
594
595    /// Access this handle inside the closure,
596    /// possibly associating it with the specified
597    ///
598    /// This is accesses the object within "critical section"
599    /// that will **block collections**
600    /// for as long as the closure is in use.
601    ///
602    /// These calls cannot be invoked recursively or they
603    /// may cause a deadlock.
604    ///
605    /// This is similar in purpose to JNI's [GetPrimitiveArrayCritical](https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#GetPrimitiveArrayCritical_ReleasePrimitiveArrayCritical).
606    /// However it never performs a copy, it is just guarenteed to block any collections.
607    /*
608     * TODO: Should we require this of all collectors?
609     * How much does it limit flexibility?
610     */
611    fn use_critical<R>(&self, func: impl FnOnce(&T) -> R) -> R;
612}
613/// Trait for binding [GcHandle]s to contexts
614/// using [GcBindHandle::bind_to]
615///
616/// This is separate from the [GcHandle] trait
617/// because Rust doesn't have Generic Associated Types
618///
619/// TODO: Remove when we get more powerful types
620pub unsafe trait GcBindHandle<'new_gc, T: GcSafe + ?Sized>: GcHandle<T>
621    where T: GcBrand<'new_gc, Self::Id>,
622          <T as GcBrand<'new_gc, Self::Id>>::Branded: GcSafe {
623    /// Associate this handle with the specified context,
624    /// allowing its underlying object to be accessed
625    /// as long as the context is valid.
626    ///
627    /// The underlying object can be accessed just like any
628    /// other object that would be allocated from the context.
629    /// It'll be properly collected and can even be used as a root
630    /// at the next safepoint.
631    fn bind_to(&self, context: &'new_gc <Self::System as GcSystem>::Context) -> Gc<
632        'new_gc,
633        <T as GcBrand<'new_gc, Self::Id>>::Branded,
634        Self::Id
635    >;
636}
637
638/// Safely trigger a write barrier before
639/// writing to a garbage collected value.
640///
641/// The value must be in managed memory,
642/// a *direct* part of a garbage collected object.
643/// Write barriers (and writes) must include a reference
644/// to its owning object.
645///
646/// ## Safety
647/// It is undefined behavior to forget to trigger a write barrier.
648///
649/// Field offsets are unchecked. They must refer to the correct
650/// offset (in bytes).
651///
652/// ### Indirection
653/// This trait only support "direct" writes,
654/// where the destination field is inline with the source object.
655///
656/// For example it's correct to implement `GcDirectWrite<Value=A> for (A, B)`,
657/// since since `A` is inline with the owning tuple.
658///
659/// It is **incorrect** to implement `GcDirectWrite<Value=T> for Vec<T>`,
660/// since it `T` is indirectly referred to by the vector.
661/// There's no "field offset" we can use to get from `*mut Vec` -> `*mut T`.
662///
663/// The only exception to this rule is [Gc] itself.
664/// GcRef can freely implement [GcDirectWrite] for any (and all values),
665/// even though it's just a pointer.
666/// It's the final destination of all write barriers and is expected
667/// to internally handle the indirection.
668pub unsafe trait GcDirectBarrier<'gc, OwningRef>: Trace {
669    /// Trigger a write barrier,
670    /// before writing to one of the owning object's managed fields
671    ///
672    /// It is undefined behavior to mutate a garbage collected field
673    /// without inserting a write barrier before it.
674    ///
675    /// Generational, concurrent and incremental GCs need this to maintain
676    /// the tricolor invariant.
677    ///
678    /// ## Safety
679    /// The specified field offset must point to a valid field
680    /// in the source object.
681    ///
682    /// The type of this value must match the appropriate field
683    unsafe fn write_barrier(&self, owner: &OwningRef, field_offset: usize);
684}
685
686/// Indicates that a type can be safely allocated by a garbage collector.
687///
688/// ## Safety
689/// Custom destructors must never reference garbage collected pointers.
690/// The garbage collector may have already freed the other objects
691/// before calling this type's drop function.
692///
693/// Unlike java finalizers, this allows us to deallocate objects normally
694/// and avoids a second pass over the objects
695/// to check for resurrected objects.
696pub unsafe trait GcSafe: Trace {
697    /// If this type needs a destructor run
698    ///
699    /// This is usually equivalent to `std::mem::needs_drop`.
700    /// However procedurally derived code can sometimes provide
701    /// a no-op drop implementation (for safety),
702    /// which would lead to a false positive with `std::mem::needs_drop()`
703    const NEEDS_DROP: bool;
704
705    /// Assert this type is GC safe
706    ///
707    /// Only used by procedural derive
708    #[doc(hidden)]
709    fn assert_gc_safe() {}
710}
711/// Assert that a type implements Copy
712///
713/// Used by the derive code
714#[doc(hidden)]
715pub fn assert_copy<T: Copy>() {}
716
717/// A wrapper type that assumes its contents don't need to be traced
718#[repr(transparent)]
719#[derive(Copy, Clone, Debug)]
720pub struct AssumeNotTraced<T>(T);
721impl<T> AssumeNotTraced<T> {
722    /// Assume the specified value doesn't need to be traced
723    ///
724    /// ## Safety
725    /// Undefined behavior if the value contains anything that need to be traced
726    /// by a garbage collector.
727    #[inline]
728    pub unsafe fn new(value: T) -> Self {
729        AssumeNotTraced(value)
730    }
731    /// Unwrap the inner value of this wrapper
732    #[inline]
733    pub fn into_inner(self) -> T {
734        self.0
735    }
736}
737impl<T> Deref for AssumeNotTraced<T> {
738    type Target = T;
739
740    #[inline]
741    fn deref(&self) -> &Self::Target {
742        &self.0
743    }
744}
745impl<T> DerefMut for AssumeNotTraced<T> {
746    #[inline]
747    fn deref_mut(&mut self) -> &mut Self::Target {
748        &mut self.0
749    }
750}
751
752unsafe impl<T> Trace for AssumeNotTraced<T> {
753    const NEEDS_TRACE: bool = false;
754    #[inline(always)] // This method does nothing and is always a win to inline
755    fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err> {
756        Ok(())
757    }
758}
759unsafe impl<T> TraceImmutable for AssumeNotTraced<T> {
760    #[inline(always)]
761    fn visit_immutable<V: GcVisitor>(&self, _visitor: &mut V) -> Result<(), V::Err> {
762        Ok(())
763    }
764}
765unsafe impl<T> NullTrace for AssumeNotTraced<T> {}
766/// No tracing implies GcSafe
767unsafe impl<T> GcSafe for AssumeNotTraced<T> {
768    const NEEDS_DROP: bool = core::mem::needs_drop::<T>();
769}
770unsafe_gc_brand!(AssumeNotTraced, T);
771
772/// Changes all references to garbage
773/// collected objects to match `'new_gc`.
774///
775/// This indicates that its safe to transmute to the new `Branded` type
776/// and all that will change is the lifetimes.
777pub unsafe trait GcBrand<'new_gc, Id: CollectorId>: Trace {
778    /// This type with all garbage collected lifetimes
779    /// changed to `'new_gc`
780    ///
781    /// This must have the same in-memory repr as `Self`,
782    /// so that it's safe to transmute.
783    type Branded: Trace + 'new_gc;
784}
785
786/// Indicates that a type can be traced by a garbage collector.
787///
788/// This doesn't necessarily mean that the type is safe to allocate in a garbage collector ([GcSafe]).
789///
790/// ## Safety
791/// See the documentation of the `trace` method for more info.
792/// Essentially, this object must faithfully trace anything that
793/// could contain garbage collected pointers or other `Trace` items.
794pub unsafe trait Trace {
795    /// Whether this type needs to be traced by the garbage collector.
796    ///
797    /// Some primitive types don't need to be traced at all,
798    /// and can be simply ignored by the garbage collector.
799    ///
800    /// Collections should usually delegate this decision to their element type,
801    /// claiming the need for tracing only if their elements do.
802    /// For example, to decide `Vec<u32>::NEEDS_TRACE` you'd check whether `u32::NEEDS_TRACE` (false),
803    /// and so then `Vec<u32>` doesn't need to be traced.
804    /// By the same logic, `Vec<Gc<u32>>` does need to be traced,
805    /// since it contains a garbage collected pointer.
806    ///
807    /// If there are multiple types involved, you should check if any of them need tracing.
808    /// One perfect example of this is structure/tuple types which check
809    /// `field1::NEEDS_TRACE || field2::NEEDS_TRACE || field3::needs_trace`.
810    /// The fields which don't need tracing will always ignored by `GarbageCollector::trace`,
811    /// while the fields that do will be properly traced.
812    ///
813    /// False negatives will always result in completely undefined behavior.
814    /// False positives could result in un-necessary tracing, but are perfectly safe otherwise.
815    /// Therefore, when in doubt you always assume this is true.
816    ///
817    /// If this is true `NullTrace` should (but doesn't have to) be implemented.
818    const NEEDS_TRACE: bool;
819    /// Visit each field in this type
820    ///
821    /// Users should never invoke this method, and always call the `V::visit` instead.
822    /// Only the collector itself is premitted to call this method,
823    /// and **it is undefined behavior for the user to invoke this**.
824    ///
825    /// Structures should trace each of their fields,
826    /// and collections should trace each of their elements.
827    ///
828    /// ### Safety
829    /// Some types (like `Gc`) need special actions taken when they're traced,
830    /// but those are somewhat rare and are usually already provided by the garbage collector.
831    ///
832    /// Unless I explicitly document actions as legal I may decide to change i.
833    /// I am only bound by the constraints of [semantic versioning](http://semver.org/) in the trace function
834    /// if I explicitly document it as safe behavior in this method's documentation.
835    /// If you try something that isn't explicitly documented here as permitted behavior,
836    /// the collector may choose to override your memory with `0xDEADBEEF`.
837    /// ## Always Permitted
838    /// - Reading your own memory (includes iteration)
839    ///   - Interior mutation is undefined behavior, even if you use `GcCell`
840    /// - Calling `GcVisitor::visit` with the specified collector
841    ///   - `GarbageCollector::trace` already verifies that it owns the data, so you don't need to do that
842    /// - Panicking
843    ///   - This should be reserved for cases where you are seriously screwed up,
844    ///       and can't fulfill your contract to trace your interior properly.
845    ///     - One example is `Gc<T>` which panics if the garbage collectors are mismatched
846    ///   - This rule may change in future versions, depending on how we deal with multi-threading.
847    /// ## Never Permitted Behavior
848    /// - Forgetting a element of a collection, or field of a structure
849    ///   - If you forget an element undefined behavior will result
850    ///   - This is why we always prefer automatically derived implementations where possible.
851    ///     - You will never trigger undefined behavior with an automatic implementation,
852    ///       and it'll always be completely sufficient for safe code (aside from destructors).
853    ///     - With an automatically derived implementation you will never miss a field
854    /// - It is undefined behavior to mutate any of your own data.
855    ///   - The mutable `&mut self` is just so copying collectors can relocate GC pointers
856    /// - Invoking this function directly, without delegating to `GcVisitor`
857    fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>;
858}
859/// A type that can be safely traced/relocated
860/// without having to use a mutable reference
861///
862/// Types with interior mutability (like `RefCell` or `Cell<Gc<T>>`)
863/// can safely implement this, since they allow safely relocating the pointer
864/// without a mutable reference.
865/// Likewise primitives (with new garbage collected data) can also
866/// implement this (since they have nothing to trace).
867pub unsafe trait TraceImmutable: Trace {
868    /// Visit an immutable reference to this type
869    ///
870    /// The visitor may want to relocate garbage collected pointers,
871    /// which this type must support.
872    fn visit_immutable<V: GcVisitor>(&self, visitor: &mut V) -> Result<(), V::Err>;
873}
874
875/// Marker types for types that don't need to be traced
876///
877/// If this trait is implemented `Trace::NEEDS_TRACE` must be false
878pub unsafe trait NullTrace: Trace + TraceImmutable {}
879
880/// Visits garbage collected objects
881///
882/// This should only be used by a [GcSystem]
883pub unsafe trait GcVisitor: Sized {
884    /// The type of errors returned by this visitor
885    type Err: Debug;
886
887    /// Visit a reference to the specified value
888    #[inline(always)]
889    fn visit<T: Trace + ?Sized>(&mut self, value: &mut T) -> Result<(), Self::Err> {
890        value.visit(self)
891    }
892    /// Visit a reference to the specified value
893    #[inline(always)]
894    fn visit_immutable<T: TraceImmutable + ?Sized>(&mut self, value: &T) -> Result<(), Self::Err> {
895        value.visit_immutable(self)
896    }
897
898    /// Visit a garbage collected pointer
899    ///
900    /// ## Safety
901    /// Undefined behavior if the GC pointer isn't properly visited.
902    unsafe fn visit_gc<'gc, T: GcSafe + 'gc, Id: CollectorId>(
903        &mut self, gc: &mut Gc<'gc, T, Id>
904    ) -> Result<(), Self::Err>;
905}