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