1use std::{
2 borrow::Cow,
3 cell::RefCell,
4 collections::{BTreeMap, BTreeSet, HashMap, HashSet},
5 marker::PhantomData,
6 path::{Path, PathBuf},
7 sync::{Arc, Mutex, atomic::*},
8 time::Duration,
9};
10
11use auto_hash_map::{AutoMap, AutoSet};
12use either::Either;
13use indexmap::{IndexMap, IndexSet};
14use smallvec::SmallVec;
15use turbo_rcstr::RcStr;
16
17use crate::RawVc;
18
19pub struct TraceRawVcsContext {
20 list: Vec<RawVc>,
21}
22
23impl TraceRawVcsContext {
24 pub(crate) fn new() -> Self {
25 Self { list: Vec::new() }
26 }
27
28 pub(crate) fn into_vec(self) -> Vec<RawVc> {
29 self.list
30 }
31}
32
33pub trait TraceRawVcs {
44 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext);
45 fn get_raw_vcs(&self) -> Vec<RawVc> {
46 let mut trace_context = TraceRawVcsContext::new();
47 self.trace_raw_vcs(&mut trace_context);
48 trace_context.into_vec()
49 }
50}
51
52macro_rules! ignore {
53 ($ty:ty) => {
54 impl TraceRawVcs for $ty {
55 fn trace_raw_vcs(&self, _context: &mut TraceRawVcsContext) {}
56 }
57 };
58
59 ($ty:ty, $($tys:ty),+) => {
60 ignore!($ty);
61 ignore!($($tys),+);
62 }
63}
64
65ignore!(
66 i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, f32, f64, char, bool, isize, usize
67);
68ignore!(
69 AtomicI8,
70 AtomicU8,
71 AtomicI16,
72 AtomicU16,
73 AtomicI32,
74 AtomicU32,
75 AtomicI64,
76 AtomicU64,
77 AtomicBool,
78 AtomicUsize
79);
80ignore!((), str, String, Duration, anyhow::Error, RcStr);
81ignore!(Path, PathBuf);
82ignore!(serde_json::Value, serde_json::Map<String, serde_json::Value>);
83
84impl<T: ?Sized> TraceRawVcs for PhantomData<T> {
85 fn trace_raw_vcs(&self, _trace_context: &mut TraceRawVcsContext) {}
86}
87
88macro_rules! impl_trace_tuple {
90 ($T:ident) => {
91 impl_trace_tuple!(@impl $T);
92 };
93 ($T:ident $( $U:ident )+) => {
94 impl_trace_tuple!($( $U )+);
95 impl_trace_tuple!(@impl $T $( $U )+);
96 };
97 (@impl $( $T:ident )+) => {
98 impl<$($T: TraceRawVcs),+> TraceRawVcs for ($($T,)+) {
99 #[allow(non_snake_case)]
100 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
101 let ($($T,)+) = self;
102 $(
103 TraceRawVcs::trace_raw_vcs($T, trace_context);
104 )+
105 }
106 }
107 };
108}
109
110impl_trace_tuple!(E D C B A Z Y X W V U T);
111
112macro_rules! impl_trace_fn_ptr {
115 ($T:ident) => {
116 impl_trace_fn_ptr!(@impl $T);
117 };
118 ($T:ident $( $U:ident )+) => {
119 impl_trace_fn_ptr!($( $U )+);
120 impl_trace_fn_ptr!(@impl $T $( $U )+);
121 };
122 (@impl $( $T:ident )+) => {
123 impl<$($T,)+ Return> TraceRawVcs for fn($($T),+) -> Return {
124 fn trace_raw_vcs(&self, _trace_context: &mut TraceRawVcsContext) {}
125 }
126 };
127}
128
129impl_trace_fn_ptr!(E D C B A Z Y X W V U T);
130
131impl<T: TraceRawVcs> TraceRawVcs for Option<T> {
132 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
133 if let Some(item) = self {
134 TraceRawVcs::trace_raw_vcs(item, trace_context);
135 }
136 }
137}
138
139impl<T: TraceRawVcs> TraceRawVcs for Vec<T> {
140 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
141 for item in self.iter() {
142 TraceRawVcs::trace_raw_vcs(item, trace_context);
143 }
144 }
145}
146
147impl<T: TraceRawVcs> TraceRawVcs for Box<[T]> {
148 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
149 for item in self.iter() {
150 TraceRawVcs::trace_raw_vcs(item, trace_context);
151 }
152 }
153}
154
155impl<T: TraceRawVcs, const N: usize> TraceRawVcs for SmallVec<[T; N]> {
156 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
157 for item in self.iter() {
158 TraceRawVcs::trace_raw_vcs(item, trace_context);
159 }
160 }
161}
162
163impl<T: TraceRawVcs, const N: usize> TraceRawVcs for [T; N] {
164 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
165 for item in self.iter() {
166 TraceRawVcs::trace_raw_vcs(item, trace_context);
167 }
168 }
169}
170
171impl<T: TraceRawVcs, S> TraceRawVcs for HashSet<T, S> {
172 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
173 for item in self.iter() {
174 TraceRawVcs::trace_raw_vcs(item, trace_context);
175 }
176 }
177}
178
179impl<T: TraceRawVcs, S, const I: usize> TraceRawVcs for AutoSet<T, S, I> {
180 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
181 for item in self.iter() {
182 TraceRawVcs::trace_raw_vcs(item, trace_context);
183 }
184 }
185}
186
187impl<T: TraceRawVcs> TraceRawVcs for BTreeSet<T> {
188 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
189 for item in self.iter() {
190 TraceRawVcs::trace_raw_vcs(item, trace_context);
191 }
192 }
193}
194
195impl<T: TraceRawVcs, S> TraceRawVcs for IndexSet<T, S> {
196 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
197 for item in self.iter() {
198 TraceRawVcs::trace_raw_vcs(item, trace_context);
199 }
200 }
201}
202
203impl<K: TraceRawVcs, V: TraceRawVcs, S> TraceRawVcs for HashMap<K, V, S> {
204 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
205 for (key, value) in self.iter() {
206 TraceRawVcs::trace_raw_vcs(key, trace_context);
207 TraceRawVcs::trace_raw_vcs(value, trace_context);
208 }
209 }
210}
211
212impl<K: TraceRawVcs, V: TraceRawVcs, S, const I: usize> TraceRawVcs for AutoMap<K, V, S, I> {
213 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
214 for (key, value) in self.iter() {
215 TraceRawVcs::trace_raw_vcs(key, trace_context);
216 TraceRawVcs::trace_raw_vcs(value, trace_context);
217 }
218 }
219}
220
221impl<K: TraceRawVcs, V: TraceRawVcs> TraceRawVcs for BTreeMap<K, V> {
222 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
223 for (key, value) in self.iter() {
224 TraceRawVcs::trace_raw_vcs(key, trace_context);
225 TraceRawVcs::trace_raw_vcs(value, trace_context);
226 }
227 }
228}
229
230impl<K: TraceRawVcs, V: TraceRawVcs, S> TraceRawVcs for IndexMap<K, V, S> {
231 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
232 for (key, value) in self.iter() {
233 TraceRawVcs::trace_raw_vcs(key, trace_context);
234 TraceRawVcs::trace_raw_vcs(value, trace_context);
235 }
236 }
237}
238
239impl<T: TraceRawVcs + ?Sized> TraceRawVcs for Box<T> {
240 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
241 TraceRawVcs::trace_raw_vcs(&**self, trace_context);
242 }
243}
244
245impl<T: TraceRawVcs + ?Sized> TraceRawVcs for Arc<T> {
246 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
247 TraceRawVcs::trace_raw_vcs(&**self, trace_context);
248 }
249}
250
251impl<B: TraceRawVcs + ToOwned + ?Sized> TraceRawVcs for Cow<'_, B> {
252 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
253 TraceRawVcs::trace_raw_vcs(&**self, trace_context);
254 }
255}
256
257impl TraceRawVcs for RawVc {
258 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
259 trace_context.list.push(*self);
260 }
261}
262
263impl<T: TraceRawVcs, E: TraceRawVcs> TraceRawVcs for Result<T, E> {
264 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
265 match self {
266 Ok(o) => o.trace_raw_vcs(trace_context),
267 Err(e) => e.trace_raw_vcs(trace_context),
268 }
269 }
270}
271
272impl<T: TraceRawVcs + ?Sized> TraceRawVcs for Mutex<T> {
273 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
274 self.lock().unwrap().trace_raw_vcs(trace_context);
275 }
276}
277
278impl<T: TraceRawVcs + ?Sized> TraceRawVcs for RefCell<T> {
279 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
280 self.borrow().trace_raw_vcs(trace_context);
281 }
282}
283
284impl<T: TraceRawVcs + ?Sized> TraceRawVcs for &T {
285 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
286 (**self).trace_raw_vcs(trace_context);
287 }
288}
289impl<T: TraceRawVcs + ?Sized> TraceRawVcs for &mut T {
290 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
291 (**self).trace_raw_vcs(trace_context);
292 }
293}
294
295impl<L: TraceRawVcs, R: TraceRawVcs> TraceRawVcs for Either<L, R> {
296 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
297 match self {
298 Either::Left(l) => l.trace_raw_vcs(trace_context),
299 Either::Right(r) => r.trace_raw_vcs(trace_context),
300 }
301 }
302}
303
304pub use turbo_tasks_macros::TraceRawVcs;