1use alloc::boxed::Box;
2use alloc::collections::{BTreeMap, BTreeSet};
3use alloc::collections::{LinkedList, VecDeque};
4use alloc::rc::Rc;
5use alloc::string::String;
6use alloc::vec::Vec;
7use core::cell::{Cell, RefCell};
8use core::marker::PhantomData;
9#[cfg(feature = "std")]
10use std::collections::{HashMap, HashSet};
11
12use crate::collect::Collect;
13use crate::context::Collection;
14
15#[macro_export]
18macro_rules! unsafe_empty_collect {
19 ($type:ty) => {
20 unsafe impl Collect for $type {
21 #[inline]
22 fn needs_trace() -> bool {
23 false
24 }
25 }
26 };
27}
28
29#[macro_export]
32macro_rules! static_collect {
33 ($type:ty) => {
34 unsafe impl Collect for $type
35 where
36 $type: 'static,
37 {
38 #[inline]
39 fn needs_trace() -> bool {
40 false
41 }
42 }
43 };
44}
45
46static_collect!(bool);
47static_collect!(char);
48static_collect!(u8);
49static_collect!(u16);
50static_collect!(u32);
51static_collect!(u64);
52static_collect!(usize);
53static_collect!(i8);
54static_collect!(i16);
55static_collect!(i32);
56static_collect!(i64);
57static_collect!(isize);
58static_collect!(f32);
59static_collect!(f64);
60static_collect!(String);
61static_collect!(str);
62static_collect!(alloc::ffi::CString);
63static_collect!(core::ffi::CStr);
64static_collect!(core::any::TypeId);
65#[cfg(feature = "std")]
66static_collect!(std::path::Path);
67#[cfg(feature = "std")]
68static_collect!(std::path::PathBuf);
69#[cfg(feature = "std")]
70static_collect!(std::ffi::OsStr);
71#[cfg(feature = "std")]
72static_collect!(std::ffi::OsString);
73
74unsafe impl<T: ?Sized + 'static> Collect for &'static T {
101 #[inline]
102 fn needs_trace() -> bool {
103 false
104 }
105}
106
107unsafe impl<T: ?Sized + Collect> Collect for Box<T> {
108 #[inline]
109 fn trace(&self, cc: &Collection) {
110 (**self).trace(cc)
111 }
112}
113
114unsafe impl<T: Collect> Collect for [T] {
115 #[inline]
116 fn needs_trace() -> bool {
117 T::needs_trace()
118 }
119
120 #[inline]
121 fn trace(&self, cc: &Collection) {
122 for t in self.iter() {
123 t.trace(cc)
124 }
125 }
126}
127
128unsafe impl<T: Collect> Collect for Option<T> {
129 #[inline]
130 fn needs_trace() -> bool {
131 T::needs_trace()
132 }
133
134 #[inline]
135 fn trace(&self, cc: &Collection) {
136 if let Some(t) = self.as_ref() {
137 t.trace(cc)
138 }
139 }
140}
141
142unsafe impl<T: Collect, E: Collect> Collect for Result<T, E> {
143 #[inline]
144 fn needs_trace() -> bool {
145 T::needs_trace() || E::needs_trace()
146 }
147
148 #[inline]
149 fn trace(&self, cc: &Collection) {
150 match self {
151 Ok(r) => r.trace(cc),
152 Err(e) => e.trace(cc),
153 }
154 }
155}
156
157unsafe impl<T: Collect> Collect for Vec<T> {
158 #[inline]
159 fn needs_trace() -> bool {
160 T::needs_trace()
161 }
162
163 #[inline]
164 fn trace(&self, cc: &Collection) {
165 for t in self {
166 t.trace(cc)
167 }
168 }
169}
170
171unsafe impl<T: Collect> Collect for VecDeque<T> {
172 #[inline]
173 fn needs_trace() -> bool {
174 T::needs_trace()
175 }
176
177 #[inline]
178 fn trace(&self, cc: &Collection) {
179 for t in self {
180 t.trace(cc)
181 }
182 }
183}
184
185unsafe impl<T: Collect> Collect for LinkedList<T> {
186 #[inline]
187 fn needs_trace() -> bool {
188 T::needs_trace()
189 }
190
191 #[inline]
192 fn trace(&self, cc: &Collection) {
193 for t in self {
194 t.trace(cc)
195 }
196 }
197}
198
199#[cfg(feature = "std")]
200unsafe impl<K, V, S> Collect for HashMap<K, V, S>
201where
202 K: Collect,
203 V: Collect,
204 S: 'static,
205{
206 #[inline]
207 fn needs_trace() -> bool {
208 K::needs_trace() || V::needs_trace()
209 }
210
211 #[inline]
212 fn trace(&self, cc: &Collection) {
213 for (k, v) in self {
214 k.trace(cc);
215 v.trace(cc);
216 }
217 }
218}
219
220#[cfg(feature = "std")]
221unsafe impl<T, S> Collect for HashSet<T, S>
222where
223 T: Collect,
224 S: 'static,
225{
226 #[inline]
227 fn needs_trace() -> bool {
228 T::needs_trace()
229 }
230
231 #[inline]
232 fn trace(&self, cc: &Collection) {
233 for v in self {
234 v.trace(cc);
235 }
236 }
237}
238
239unsafe impl<K, V> Collect for BTreeMap<K, V>
240where
241 K: Collect,
242 V: Collect,
243{
244 #[inline]
245 fn needs_trace() -> bool {
246 K::needs_trace() || V::needs_trace()
247 }
248
249 #[inline]
250 fn trace(&self, cc: &Collection) {
251 for (k, v) in self {
252 k.trace(cc);
253 v.trace(cc);
254 }
255 }
256}
257
258unsafe impl<T> Collect for BTreeSet<T>
259where
260 T: Collect,
261{
262 #[inline]
263 fn needs_trace() -> bool {
264 T::needs_trace()
265 }
266
267 #[inline]
268 fn trace(&self, cc: &Collection) {
269 for v in self {
270 v.trace(cc);
271 }
272 }
273}
274
275unsafe impl<T> Collect for Rc<T>
276where
277 T: ?Sized + Collect,
278{
279 #[inline]
280 fn trace(&self, cc: &Collection) {
281 (**self).trace(cc);
282 }
283}
284
285#[cfg(target_has_atomic = "ptr")]
286unsafe impl<T> Collect for alloc::sync::Arc<T>
287where
288 T: ?Sized + Collect,
289{
290 #[inline]
291 fn trace(&self, cc: &Collection) {
292 (**self).trace(cc);
293 }
294}
295
296unsafe impl<T> Collect for Cell<T>
297where
298 T: 'static,
299{
300 #[inline]
301 fn needs_trace() -> bool {
302 false
303 }
304}
305
306unsafe impl<T> Collect for RefCell<T>
307where
308 T: 'static,
309{
310 #[inline]
311 fn needs_trace() -> bool {
312 false
313 }
314}
315
316unsafe impl<T> Collect for PhantomData<T> {
318 #[inline]
319 fn needs_trace() -> bool {
320 false
321 }
322}
323
324unsafe impl<T: Collect, const N: usize> Collect for [T; N] {
325 #[inline]
326 fn needs_trace() -> bool {
327 T::needs_trace()
328 }
329
330 #[inline]
331 fn trace(&self, cc: &Collection) {
332 for t in self {
333 t.trace(cc)
334 }
335 }
336}
337
338macro_rules! impl_tuple {
339 () => (
340 unsafe impl Collect for () {
341 #[inline]
342 fn needs_trace() -> bool {
343 false
344 }
345 }
346 );
347
348 ($($name:ident)+) => (
349 unsafe impl<$($name,)*> Collect for ($($name,)*)
350 where $($name: Collect,)*
351 {
352 #[inline]
353 fn needs_trace() -> bool {
354 $($name::needs_trace() ||)* false
355 }
356
357 #[allow(non_snake_case)]
358 #[inline]
359 fn trace(&self, cc: &Collection) {
360 let ($($name,)*) = self;
361 $($name.trace(cc);)*
362 }
363 }
364 );
365}
366
367impl_tuple! {}
368impl_tuple! {A}
369impl_tuple! {A B}
370impl_tuple! {A B C}
371impl_tuple! {A B C D}
372impl_tuple! {A B C D E}
373impl_tuple! {A B C D E F}
374impl_tuple! {A B C D E F G}
375impl_tuple! {A B C D E F G H}
376impl_tuple! {A B C D E F G H I}
377impl_tuple! {A B C D E F G H I J}
378impl_tuple! {A B C D E F G H I J K}
379impl_tuple! {A B C D E F G H I J K L}
380impl_tuple! {A B C D E F G H I J K L M}
381impl_tuple! {A B C D E F G H I J K L M N}
382impl_tuple! {A B C D E F G H I J K L M N O}
383impl_tuple! {A B C D E F G H I J K L M N O P}