1use crate::sync::GcVisitor;
2
3pub trait Trace: Send + Sync {
5 fn visit_children(&self, visitor: &mut GcVisitor);
8}
9
10#[macro_export]
16macro_rules! sync_empty_trace {
17 ($t:path) => {
18 impl $crate::sync::Trace for $t {
19 #[inline]
20 fn visit_children(&self, _: &mut $crate::sync::GcVisitor) {}
21 }
22 };
23 ($first:path, $($rest:path),+) => {
24 sync_empty_trace!($first);
25 sync_empty_trace!($($rest),+);
26 };
27}
28
29sync_empty_trace!(f32, f64);
30sync_empty_trace!(i8, i16, i32, i64, isize, i128);
31sync_empty_trace!(u8, u16, u32, u64, usize, u128);
32sync_empty_trace!(bool, char);
33sync_empty_trace!(std::string::String);
34
35impl Trace for () {
36 fn visit_children(&self, _: &mut GcVisitor) {}
37}
38
39impl<T: Trace> Trace for std::option::Option<T> {
40 fn visit_children(&self, visitor: &mut GcVisitor) {
41 if let Some(inner) = self {
42 inner.visit_children(visitor);
43 }
44 }
45}
46
47impl<T: Trace> Trace for std::vec::Vec<T> {
48 fn visit_children(&self, visitor: &mut GcVisitor) {
49 for elem in self.iter() {
50 elem.visit_children(visitor);
51 }
52 }
53}
54
55impl<T: Trace> Trace for std::boxed::Box<T> {
56 fn visit_children(&self, visitor: &mut GcVisitor) {
57 T::visit_children(self, visitor);
58 }
59}
60
61impl<T: Trace, const S: usize> Trace for [T; S] {
62 fn visit_children(&self, visitor: &mut GcVisitor) {
63 for elem in self.iter() {
64 elem.visit_children(visitor);
65 }
66 }
67}
68
69impl<T: Trace> Trace for [T] {
70 fn visit_children(&self, visitor: &mut GcVisitor) {
71 for elem in self.iter() {
72 elem.visit_children(visitor);
73 }
74 }
75}
76
77impl<V: Trace> Trace for std::collections::BinaryHeap<V> {
78 fn visit_children(&self, visitor: &mut GcVisitor) {
79 for v in self.iter() {
80 v.visit_children(visitor);
81 }
82 }
83}
84
85impl<K: Trace, V: Trace> Trace for std::collections::BTreeMap<K, V> {
86 fn visit_children(&self, visitor: &mut GcVisitor) {
87 for (k, v) in self.iter() {
88 k.visit_children(visitor);
89 v.visit_children(visitor);
90 }
91 }
92}
93
94impl<V: Trace> Trace for std::collections::BTreeSet<V> {
95 fn visit_children(&self, visitor: &mut GcVisitor) {
96 for v in self.iter() {
97 v.visit_children(visitor);
98 }
99 }
100}
101
102impl<K: Trace, V: Trace, S: std::hash::BuildHasher + Send + Sync> Trace
103 for std::collections::HashMap<K, V, S>
104{
105 fn visit_children(&self, visitor: &mut GcVisitor) {
106 for (k, v) in self.iter() {
107 k.visit_children(visitor);
108 v.visit_children(visitor);
109 }
110 }
111}
112
113impl<V: Trace, S: std::hash::BuildHasher + Send + Sync> Trace for std::collections::HashSet<V, S> {
114 fn visit_children(&self, visitor: &mut GcVisitor) {
115 for v in self.iter() {
116 v.visit_children(visitor);
117 }
118 }
119}
120
121impl<V: Trace> Trace for std::collections::LinkedList<V> {
122 fn visit_children(&self, visitor: &mut GcVisitor) {
123 for v in self.iter() {
124 v.visit_children(visitor);
125 }
126 }
127}
128
129impl<V: Trace> Trace for std::collections::VecDeque<V> {
130 fn visit_children(&self, visitor: &mut GcVisitor) {
131 for v in self.iter() {
132 v.visit_children(visitor);
133 }
134 }
135}
136
137impl<T: Trace> Trace for std::sync::Mutex<T> {
138 fn visit_children(&self, visitor: &mut GcVisitor) {
139 if let Ok(guard) = self.try_lock() {
140 guard.visit_children(visitor);
141 }
142 }
143}
144
145impl<T: Trace> Trace for std::sync::RwLock<T> {
146 fn visit_children(&self, visitor: &mut GcVisitor) {
147 if let Ok(guard) = self.try_read() {
148 guard.visit_children(visitor);
149 }
150 }
151}