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