[−][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
pub 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.
Required methods
pub 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
- 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]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for i16
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for i32
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for i64
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for isize
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for u8
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for u16
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for u32
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for u64
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for usize
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for f32
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for f64
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for bool
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for char
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for &'static str
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for ()
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<Visit: GcVisitor>(
&mut self,
#[allow(unused)]
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
#[allow(unused)] visitor: &mut Visit
) -> Result<(), Visit::Err>
impl<A> Trace for (A,) where
A: Trace,
[src]
A: Trace,
pub const NEEDS_TRACE: bool
[src]
pub fn visit<Visit: GcVisitor>(
&mut self,
#[allow(unused)]
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
#[allow(unused)] visitor: &mut Visit
) -> Result<(), Visit::Err>
impl<A, B> Trace for (A, B) where
A: Trace,
B: Trace,
[src]
A: Trace,
B: Trace,
pub const NEEDS_TRACE: bool
[src]
pub fn visit<Visit: GcVisitor>(
&mut self,
#[allow(unused)]
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
#[allow(unused)] 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,
pub const NEEDS_TRACE: bool
[src]
pub fn visit<Visit: GcVisitor>(
&mut self,
#[allow(unused)]
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
#[allow(unused)] 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,
pub const NEEDS_TRACE: bool
[src]
pub fn visit<Visit: GcVisitor>(
&mut self,
#[allow(unused)]
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
#[allow(unused)] 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,
pub const NEEDS_TRACE: bool
[src]
pub fn visit<Visit: GcVisitor>(
&mut self,
#[allow(unused)]
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
#[allow(unused)] 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,
pub const NEEDS_TRACE: bool
[src]
pub fn visit<Visit: GcVisitor>(
&mut self,
#[allow(unused)]
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
#[allow(unused)] 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,
pub const NEEDS_TRACE: bool
[src]
pub fn visit<Visit: GcVisitor>(
&mut self,
#[allow(unused)]
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
#[allow(unused)] 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,
pub const NEEDS_TRACE: bool
[src]
pub fn visit<Visit: GcVisitor>(
&mut self,
#[allow(unused)]
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
#[allow(unused)] 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,
pub const NEEDS_TRACE: bool
[src]
pub fn visit<Visit: GcVisitor>(
&mut self,
#[allow(unused)]
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
#[allow(unused)] visitor: &mut Visit
) -> Result<(), Visit::Err>
impl<T: Trace> Trace for [T; 0]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 1]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 2]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 3]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 4]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 5]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 6]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 7]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 8]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 9]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 10]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 11]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 12]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 13]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 14]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 15]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 16]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 17]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 18]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 19]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 20]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 24]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 32]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 48]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 64]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 100]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 128]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 256]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 512]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 1024]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 2048]
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for [T; 4096]
[src]
pub const NEEDS_TRACE: bool
[src]
pub 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.
pub const NEEDS_TRACE: bool
[src]
pub 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.
pub const NEEDS_TRACE: bool
[src]
pub 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.
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T: Trace> Trace for Option<T>
[src]
pub const NEEDS_TRACE: bool
[src]
pub 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,
pub const NEEDS_TRACE: bool
[src]
pub 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,
pub const NEEDS_TRACE: bool
[src]
pub 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,
pub const NEEDS_TRACE: bool
[src]
pub 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,
pub const NEEDS_TRACE: bool
[src]
pub 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,
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl Trace for String
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[src]
impl<K: TraceImmutable, V: Trace> Trace for HashMap<K, V>
[src]
pub const NEEDS_TRACE: bool
[src]
pub 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]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<Visit: GcVisitor>(
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
[src]
&mut self,
visitor: &mut Visit
) -> Result<(), Visit::Err>
Implementors
impl Trace for DummyCollectorId
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(
&mut self,
_visitor: &mut V
) -> Result<(), <V as GcVisitor>::Err>
[src]
&mut self,
_visitor: &mut V
) -> Result<(), <V as GcVisitor>::Err>
impl<'gc, T: GcSafe + 'gc, Id: CollectorId> Trace for Gc<'gc, T, Id>
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, visitor: &mut V) -> Result<(), V::Err>
[src]
impl<T> Trace for AssumeNotTraced<T>
[src]
pub const NEEDS_TRACE: bool
[src]
pub fn visit<V: GcVisitor>(&mut self, _visitor: &mut V) -> Result<(), V::Err>
[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.