|
5 | 5 | //! `RefCell` and `Cell` are intentionally ignored and do not have implementations.
|
6 | 6 | //! Some collectors may need write barriers to protect their internals.
|
7 | 7 | use core::num::Wrapping;
|
| 8 | +use core::marker::PhantomData; |
8 | 9 |
|
9 | 10 | use crate::prelude::*;
|
10 | 11 | use crate::GcDirectBarrier;
|
@@ -121,6 +122,24 @@ unsafe_trace_primitive!(char);
|
121 | 122 | // TODO: Get proper support for unsized types (issue #15)
|
122 | 123 | unsafe_trace_primitive!(&'static str);
|
123 | 124 |
|
| 125 | +unsafe_gc_impl! { |
| 126 | + target => PhantomData<T>, |
| 127 | + params => [T], |
| 128 | + bounds => { |
| 129 | + Trace => always, |
| 130 | + TraceImmutable => always, |
| 131 | + GcSafe => always, |
| 132 | + GcRebrand => { where T: 'new_gc }, |
| 133 | + GcErase => { where T: 'min } |
| 134 | + }, |
| 135 | + branded_type => Self, |
| 136 | + erased_type => Self, |
| 137 | + null_trace => always, |
| 138 | + NEEDS_TRACE => false, |
| 139 | + NEEDS_DROP => core::mem::needs_drop::<Self>(), |
| 140 | + visit => |self, visitor| { /* nop */ Ok(()) } |
| 141 | +} |
| 142 | + |
124 | 143 | trace_tuple! { A, B, C, D, E, F, G, H, I }
|
125 | 144 |
|
126 | 145 | macro_rules! trace_array {
|
@@ -289,10 +308,15 @@ mod test {
|
289 | 308 | use crate::dummy_impl::{DummyCollectorId, Gc};
|
290 | 309 | use zerogc_derive::Trace;
|
291 | 310 | use crate::prelude::*;
|
| 311 | + use std::marker::PhantomData; |
| 312 | + |
292 | 313 | #[test]
|
293 |
| - fn test_null_trace() { |
| 314 | + fn test_null_trace<'gc>() { |
294 | 315 | assert!(!<Option<i32> as Trace>::NEEDS_TRACE);
|
295 |
| - assert!(!<Option<(i32, char)> as Trace>::NEEDS_TRACE) |
| 316 | + assert!(!<Option<(i32, char)> as Trace>::NEEDS_TRACE); |
| 317 | + // PhantomData is NullTrace regardless of inside |
| 318 | + assert!(!<PhantomData<Gc<'gc, i32>> as Trace>::NEEDS_TRACE); |
| 319 | + |
296 | 320 | }
|
297 | 321 | #[derive(Trace)]
|
298 | 322 | #[zerogc(collector_id(DummyCollectorId))]
|
|
0 commit comments