1use std::any::TypeId;
2use std::cell::{Cell, RefCell};
3use std::collections::{LinkedList, VecDeque};
4use std::ffi::{OsStr, OsString};
5use std::fs::File;
6use std::marker::{PhantomData, PhantomPinned};
7use std::ops::Deref;
8use std::path::{Path, PathBuf};
9use std::rc::Rc;
10use std::time::{Duration, Instant};
11
12use crate::{trace_none, GcTarget, GcTraceToken};
13
14impl<'c, T: GcTarget<'c> + ?Sized> GcTarget<'c> for &T {
15 fn trace(&self, token: &mut GcTraceToken<'c>) {
16 T::trace(*self, token);
17 }
18}
19
20impl<'c, T: GcTarget<'c> + ?Sized> GcTarget<'c> for &mut T {
21 fn trace(&self, token: &mut GcTraceToken<'c>) {
22 T::trace(*self, token);
23 }
24}
25
26impl<'c, T: GcTarget<'c>> GcTarget<'c> for [T] {
27 fn trace(&self, token: &mut GcTraceToken<'c>) {
28 for i in self {
29 i.trace(token);
30 }
31 }
32}
33
34impl<'c, T: GcTarget<'c>> GcTarget<'c> for Vec<T> {
35 fn trace(&self, token: &mut GcTraceToken<'c>) {
36 for i in self {
37 i.trace(token);
38 }
39 }
40}
41
42impl<'c, T: GcTarget<'c>> GcTarget<'c> for LinkedList<T> {
43 fn trace(&self, token: &mut GcTraceToken<'c>) {
44 for i in self {
45 i.trace(token);
46 }
47 }
48}
49
50impl<'c, T: GcTarget<'c>> GcTarget<'c> for VecDeque<T> {
51 fn trace(&self, token: &mut GcTraceToken<'c>) {
52 for i in self {
53 i.trace(token);
54 }
55 }
56}
57
58impl<'c, T: GcTarget<'c>> GcTarget<'c> for Option<T> {
59 fn trace(&self, token: &mut GcTraceToken<'c>) {
60 if let Some(x) = self {
61 x.trace(token);
62 }
63 }
64}
65
66impl<'c, T: GcTarget<'c>, E: GcTarget<'c>> GcTarget<'c> for Result<T, E> {
67 fn trace(&self, token: &mut GcTraceToken<'c>) {
68 match self {
69 Ok(x) => x.trace(token),
70 Err(x) => x.trace(token),
71 }
72 }
73}
74
75impl<'c, T: GcTarget<'c> + ?Sized> GcTarget<'c> for Box<T> {
76 fn trace(&self, token: &mut GcTraceToken<'c>) {
77 T::trace(self, token);
78 }
79}
80
81impl<'c, T: GcTarget<'c> + ?Sized> GcTarget<'c> for Rc<T> {
82 fn trace(&self, token: &mut GcTraceToken<'c>) {
83 T::trace(self, token);
84 }
85}
86
87impl<'c, T: GcTarget<'c> + Copy> GcTarget<'c> for Cell<T> {
88 fn trace(&self, token: &mut GcTraceToken<'c>) {
89 self.get().trace(token);
90 }
91}
92
93impl<'c, T: GcTarget<'c> + ?Sized> GcTarget<'c> for RefCell<T> {
94 fn trace(&self, token: &mut GcTraceToken<'c>) {
95 T::trace(self.borrow().deref(), token);
96 }
97}
98
99impl<'c, T> GcTarget<'c> for PhantomData<T> {
100 fn trace(&self, token: &mut GcTraceToken<'c>) {
101 let _ = token;
102 }
103}
104
105trace_none!(PhantomPinned);
106
107trace_none!(bool);
108trace_none!(i8);
109trace_none!(u8);
110trace_none!(i16);
111trace_none!(u16);
112trace_none!(i32);
113trace_none!(u32);
114trace_none!(i64);
115trace_none!(u64);
116trace_none!(i128);
117trace_none!(u128);
118trace_none!(isize);
119trace_none!(usize);
120trace_none!(f32);
121trace_none!(f64);
122trace_none!(str);
123trace_none!(String);
124trace_none!(OsStr);
125trace_none!(OsString);
126trace_none!(Path);
127trace_none!(PathBuf);
128trace_none!(TypeId);
129trace_none!(File);
130trace_none!(Instant);
131trace_none!(Duration);
132
133macro_rules! trace_tuple {
134 ($($name:ident)*) => {
135 impl<'c, $($name: $crate::GcTarget<'c>),*> $crate::GcTarget<'c> for ($($name,)*) {
136 #[allow(unused_variables)]
137 fn trace(&self, token: &mut $crate::GcTraceToken<'c>) {
138 #[allow(non_snake_case)]
139 let ($($name,)*) = self;
140 $($name.trace(token);)*
141 }
142 }
143 };
144}
145
146macro_rules! trace_tuple_all {
147 () => {
148 trace_tuple!();
149 };
150 ($name:ident $($names:ident)*) => {
151 trace_tuple_all!($($names)*);
152 trace_tuple!($name $($names)*);
153 };
154}
155
156trace_tuple_all!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15);