[−][src]Trait zerogc::Trace
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
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.
Required methods
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
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
- Interior mutation is undefined behavior, even if you use
- Calling
GcVisitor::visit
with the specified collectorGarbageCollector::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
- One example is
- This rule may change in future versions, depending on how we deal with multi-threading.
- This should be reserved for cases where you are seriously screwed up,
and can't fulfill your contract to trace your interior properly.
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
- The mutable
- Invoking this function directly, without delegating to
GcVisitor
Implementations on Foreign Types
impl Trace for i8
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for i16
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for i32
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for i64
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for isize
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for u8
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for u16
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for u32
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for u64
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for usize
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for f32
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for f64
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for ()
[src]
const NEEDS_TRACE: bool
[src]
fn visit<Visit: GcVisitor>(
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
impl<A> Trace for (A,) where
A: Trace,
[src]
A: Trace,
const NEEDS_TRACE: bool
[src]
fn visit<Visit: GcVisitor>(
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
impl<A, B> Trace for (A, B) where
A: Trace,
B: Trace,
[src]
A: Trace,
B: Trace,
const NEEDS_TRACE: bool
[src]
fn visit<Visit: GcVisitor>(
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
impl<A, B, C> Trace for (A, B, C) where
A: Trace,
B: Trace,
C: Trace,
[src]
A: Trace,
B: Trace,
C: Trace,
const NEEDS_TRACE: bool
[src]
fn visit<Visit: GcVisitor>(
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
impl<A, B, C, D> Trace for (A, B, C, D) where
A: Trace,
B: Trace,
C: Trace,
D: Trace,
[src]
A: Trace,
B: Trace,
C: Trace,
D: Trace,
const NEEDS_TRACE: bool
[src]
fn visit<Visit: GcVisitor>(
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
impl<A, B, C, D, E> Trace for (A, B, C, D, E) where
A: Trace,
B: Trace,
C: Trace,
D: Trace,
E: Trace,
[src]
A: Trace,
B: Trace,
C: Trace,
D: Trace,
E: Trace,
const NEEDS_TRACE: bool
[src]
fn visit<Visit: GcVisitor>(
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
impl<A, B, C, D, E, F> Trace for (A, B, C, D, E, F) where
A: Trace,
B: Trace,
C: Trace,
D: Trace,
E: Trace,
F: Trace,
[src]
A: Trace,
B: Trace,
C: Trace,
D: Trace,
E: Trace,
F: Trace,
const NEEDS_TRACE: bool
[src]
fn visit<Visit: GcVisitor>(
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
impl<A, B, C, D, E, F, G> Trace for (A, B, C, D, E, F, G) where
A: Trace,
B: Trace,
C: Trace,
D: Trace,
E: Trace,
F: Trace,
G: Trace,
[src]
A: Trace,
B: Trace,
C: Trace,
D: Trace,
E: Trace,
F: Trace,
G: Trace,
const NEEDS_TRACE: bool
[src]
fn visit<Visit: GcVisitor>(
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
impl<A, B, C, D, E, F, G, H> Trace for (A, B, C, D, E, F, G, H) where
A: Trace,
B: Trace,
C: Trace,
D: Trace,
E: Trace,
F: Trace,
G: Trace,
H: Trace,
[src]
A: Trace,
B: Trace,
C: Trace,
D: Trace,
E: Trace,
F: Trace,
G: Trace,
H: Trace,
const NEEDS_TRACE: bool
[src]
fn visit<Visit: GcVisitor>(
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
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]
A: Trace,
B: Trace,
C: Trace,
D: Trace,
E: Trace,
F: Trace,
G: Trace,
H: Trace,
I: Trace,
const NEEDS_TRACE: bool
[src]
fn visit<Visit: GcVisitor>(
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
impl<T: Trace> Trace for [T; 0]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 1]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 2]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 3]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 4]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 5]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 6]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 7]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 8]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 9]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 10]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 11]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 12]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 13]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 14]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 15]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 16]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 17]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 18]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 19]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 20]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 24]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 32]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 48]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 64]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 100]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 128]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 256]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 512]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 1024]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 2048]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 4096]
[src]
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<'a, T: TraceImmutable> Trace for &'a T
[src]
Implements tracing for references.
The underlying data must support TraceImmutable
since we
only have an immutable reference.
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<'a, T: Trace> Trace for &'a mut T
[src]
Implements tracing for mutable references.
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T]
[src]
Implements tracing for slices, by tracing all the objects they refer to.
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T> Trace for Vec<T> where
T: Trace,
[src]
T: Trace,
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T> Trace for Box<T> where
T: Trace,
[src]
T: Trace,
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T> Trace for Rc<T> where
T: TraceImmutable,
[src]
T: TraceImmutable,
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T> Trace for Arc<T> where
T: TraceImmutable,
[src]
T: TraceImmutable,
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T> Trace for Wrapping<T> where
T: Trace,
[src]
T: Trace,
const NEEDS_TRACE: bool
[src]
fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<K: TraceImmutable, V: Trace> Trace for HashMap<K, V>
[src]
const NEEDS_TRACE: bool
[src]
fn visit<Visit: GcVisitor>(
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
impl<V: TraceImmutable> Trace for HashSet<V>
[src]
const NEEDS_TRACE: bool
[src]
fn visit<Visit: GcVisitor>(
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>