Trait zerogc::Trace[][src]

pub unsafe trait Trace {
    const NEEDS_TRACE: bool;

    fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>;
}

Indicates that a type can be traced by a garbage collector.

This doesn’t necessarily mean that the type is safe to allocate in a garbage collector (GcSafe).

Safety

See the documentation of the trace method for more info. Essentially, this object must faithfully trace anything that could contain garbage collected pointers or other Trace items.

Associated Constants

const NEEDS_TRACE: bool[src]

Whether this type needs to be traced by the garbage collector.

Some primitive types don’t need to be traced at all, and can be simply ignored by the garbage collector.

Collections should usually delegate this decision to their element type, claiming the need for tracing only if their elements do. For example, to decide Vec<u32>::NEEDS_TRACE you’d check whether u32::NEEDS_TRACE (false), and so then Vec<u32> doesn’t need to be traced. By the same logic, Vec<Gc<u32>> does need to be traced, since it contains a garbage collected pointer.

If there are multiple types involved, you should check if any of them need tracing. One perfect example of this is structure/tuple types which check field1::NEEDS_TRACE || field2::NEEDS_TRACE || field3::needs_trace. The fields which don’t need tracing will always ignored by GarbageCollector::trace, while the fields that do will be properly traced.

False negatives will always result in completely undefined behavior. False positives could result in un-necessary tracing, but are perfectly safe otherwise. Therefore, when in doubt you always assume this is true.

If this is true NullTrace should (but doesn’t have to) be implemented.

Loading content...

Required methods

fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>[src]

Visit each field in this type

Users should never invoke this method, and always call the V::visit instead. Only the collector itself is premitted to call this method, and it is undefined behavior for the user to invoke this.

Structures should trace each of their fields, and collections should trace each of their elements.

Safety

Some types (like Gc) need special actions taken when they’re traced, but those are somewhat rare and are usually already provided by the garbage collector.

Unless I explicitly document actions as legal I may decide to change i. I am only bound by the constraints of semantic versioning in the trace function if I explicitly document it as safe behavior in this method’s documentation. If you try something that isn’t explicitly documented here as permitted behavior, the collector may choose to override your memory with 0xDEADBEEF.

Always Permitted

  • Reading your own memory (includes iteration)
    • Interior mutation is undefined behavior, even if you use GcCell
  • Calling GcVisitor::visit with the specified collector
    • GarbageCollector::trace already verifies that it owns the data, so you don’t need to do that
  • Panicking
    • This should be reserved for cases where you are seriously screwed up, and can’t fulfill your contract to trace your interior properly.
      • One example is Gc<T> which panics if the garbage collectors are mismatched
    • This rule may change in future versions, depending on how we deal with multi-threading.

Never Permitted Behavior

  • Forgetting a element of a collection, or field of a structure
    • If you forget an element undefined behavior will result
    • This is why we always prefer automatically derived implementations where possible.
      • You will never trigger undefined behavior with an automatic implementation, and it’ll always be completely sufficient for safe code (aside from destructors).
      • With an automatically derived implementation you will never miss a field
  • It is undefined behavior to mutate any of your own data.
    • The mutable &mut self is just so copying collectors can relocate GC pointers
  • Invoking this function directly, without delegating to GcVisitor
Loading content...

Implementations on Foreign Types

impl Trace for i8[src]

impl Trace for i16[src]

impl Trace for i32[src]

impl Trace for i64[src]

impl Trace for isize[src]

impl Trace for u8[src]

impl Trace for u16[src]

impl Trace for u32[src]

impl Trace for u64[src]

impl Trace for usize[src]

impl Trace for f32[src]

impl Trace for f64[src]

impl Trace for bool[src]

impl Trace for char[src]

impl Trace for &'static str[src]

impl<T> Trace for PhantomData<T>[src]

impl Trace for ()[src]

impl<I> Trace for (I,) where
    I: Trace
[src]

impl<H, I> Trace for (H, I) where
    H: Trace,
    I: Trace
[src]

impl<G, H, I> Trace for (G, H, I) where
    G: Trace,
    H: Trace,
    I: Trace
[src]

impl<F, G, H, I> Trace for (F, G, H, I) where
    F: Trace,
    G: Trace,
    H: Trace,
    I: Trace
[src]

impl<E, F, G, H, I> Trace for (E, F, G, H, I) where
    E: Trace,
    F: Trace,
    G: Trace,
    H: Trace,
    I: Trace
[src]

impl<D, E, F, G, H, I> Trace for (D, E, F, G, H, I) where
    D: Trace,
    E: Trace,
    F: Trace,
    G: Trace,
    H: Trace,
    I: Trace
[src]

impl<C, D, E, F, G, H, I> Trace for (C, D, E, F, G, H, I) where
    C: Trace,
    D: Trace,
    E: Trace,
    F: Trace,
    G: Trace,
    H: Trace,
    I: Trace
[src]

impl<B, C, D, E, F, G, H, I> Trace for (B, C, D, E, F, G, H, I) where
    B: Trace,
    C: Trace,
    D: Trace,
    E: Trace,
    F: Trace,
    G: Trace,
    H: Trace,
    I: Trace
[src]

impl<A, B, C, D, E, F, G, H, I> Trace for (A, B, C, D, E, F, G, H, I) where
    A: Trace,
    B: Trace,
    C: Trace,
    D: Trace,
    E: Trace,
    F: Trace,
    G: Trace,
    H: Trace,
    I: Trace
[src]

impl<T> Trace for [T; 0] where
    T: Trace
[src]

impl<T> Trace for [T; 1] where
    T: Trace
[src]

impl<T> Trace for [T; 2] where
    T: Trace
[src]

impl<T> Trace for [T; 3] where
    T: Trace
[src]

impl<T> Trace for [T; 4] where
    T: Trace
[src]

impl<T> Trace for [T; 5] where
    T: Trace
[src]

impl<T> Trace for [T; 6] where
    T: Trace
[src]

impl<T> Trace for [T; 7] where
    T: Trace
[src]

impl<T> Trace for [T; 8] where
    T: Trace
[src]

impl<T> Trace for [T; 9] where
    T: Trace
[src]

impl<T> Trace for [T; 10] where
    T: Trace
[src]

impl<T> Trace for [T; 11] where
    T: Trace
[src]

impl<T> Trace for [T; 12] where
    T: Trace
[src]

impl<T> Trace for [T; 13] where
    T: Trace
[src]

impl<T> Trace for [T; 14] where
    T: Trace
[src]

impl<T> Trace for [T; 15] where
    T: Trace
[src]

impl<T> Trace for [T; 16] where
    T: Trace
[src]

impl<T> Trace for [T; 17] where
    T: Trace
[src]

impl<T> Trace for [T; 18] where
    T: Trace
[src]

impl<T> Trace for [T; 19] where
    T: Trace
[src]

impl<T> Trace for [T; 20] where
    T: Trace
[src]

impl<T> Trace for [T; 24] where
    T: Trace
[src]

impl<T> Trace for [T; 32] where
    T: Trace
[src]

impl<T> Trace for [T; 48] where
    T: Trace
[src]

impl<T> Trace for [T; 64] where
    T: Trace
[src]

impl<T> Trace for [T; 100] where
    T: Trace
[src]

impl<T> Trace for [T; 128] where
    T: Trace
[src]

impl<T> Trace for [T; 256] where
    T: Trace
[src]

impl<T> Trace for [T; 512] where
    T: Trace
[src]

impl<T> Trace for [T; 1024] where
    T: Trace
[src]

impl<T> Trace for [T; 2048] where
    T: Trace
[src]

impl<T> Trace for [T; 4096] where
    T: Trace
[src]

impl<'a, T: 'a> Trace for &'a T where
    T: TraceImmutable
[src]

impl<'a, T: 'a> Trace for &'a mut T where
    T: Trace
[src]

impl<T> Trace for [T] where
    T: Trace
[src]

impl<T> Trace for Option<T> where
    T: Trace
[src]

impl<T> Trace for Wrapping<T> where
    T: Trace
[src]

impl<T> Trace for Vec<T> where
    T: Trace
[src]

impl<T> Trace for Box<T> where
    T: Trace
[src]

impl<T: TraceImmutable> Trace for Rc<T> where
    T: Trace
[src]

impl<T: TraceImmutable> Trace for Arc<T> where
    T: Trace
[src]

impl Trace for String[src]

impl<K: TraceImmutable, V> Trace for HashMap<K, V> where
    K: Trace,
    V: Trace
[src]

impl<T: TraceImmutable> Trace for HashSet<T> where
    T: Trace
[src]

Loading content...

Implementors

impl Trace for DummyCollectorId[src]

impl<'gc, T: GcSafe + 'gc, Id: CollectorId> Trace for Gc<'gc, T, Id>[src]

impl<T> Trace for AssumeNotTraced<T>[src]

impl<T: Trace + Copy> Trace for GcCell<T>[src]

GcCell can only support mutating types that are NullTrace, because garbage collected types need write barriers.

However, this is already enforced by the bounds of GcCell::set, so we don’t need to verify here. In other words is possible to safely trace a GcCell with a garbage collected type, as long as it is never mutated.

Loading content...