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