turbo_tasks/
dyn_task_inputs.rs1use std::{
2 any::{Any, type_name},
3 fmt::Debug,
4 hash::Hash,
5};
6
7use turbo_dyn_eq_hash::{
8 DynEq, DynHash, impl_eq_for_dyn, impl_hash_for_dyn, impl_partial_eq_for_dyn,
9};
10
11use crate::trace::TraceRawVcs;
12
13pub trait DynTaskInputs: Debug + DynEq + DynHash + TraceRawVcs + Send + Sync + 'static {
14 #[cfg(debug_assertions)]
15 fn dyn_type_name(&self) -> &'static str;
16}
17
18impl<T> DynTaskInputs for T
19where
20 T: Debug + Eq + Hash + Send + Sync + TraceRawVcs + 'static,
21{
22 #[cfg(debug_assertions)]
23 fn dyn_type_name(&self) -> &'static str {
24 std::any::type_name::<T>()
25 }
26}
27
28impl_partial_eq_for_dyn!(dyn DynTaskInputs);
29impl_eq_for_dyn!(dyn DynTaskInputs);
30impl_hash_for_dyn!(dyn DynTaskInputs);
31
32pub fn any_as_encode<T: Any>(this: &dyn Any) -> &T {
33 if let Some(enc) = this.downcast_ref::<T>() {
34 return enc;
35 }
36 unreachable!(
37 "any_as_encode::<{}> called with invalid type",
38 type_name::<T>()
39 );
40}
41
42pub trait StackDynTaskInputs {
49 fn as_ref(&self) -> &dyn DynTaskInputs;
51 fn take_box(&mut self) -> Box<dyn DynTaskInputs>;
53 fn as_any_mut(&mut self) -> &mut dyn Any;
55}
56
57#[repr(transparent)]
62pub struct StackDynTaskInputsSlot<T> {
63 slot: Option<T>,
64}
65
66impl<T> StackDynTaskInputsSlot<T> {
67 #[inline]
68 pub fn new(value: T) -> Self {
69 Self { slot: Some(value) }
70 }
71
72 #[inline]
73 pub fn take(&mut self) -> T {
74 self.slot
75 .take()
76 .expect("StackDynTaskInputsSlot::take called after value was already taken")
77 }
78}
79
80impl<T: DynTaskInputs> StackDynTaskInputs for StackDynTaskInputsSlot<T> {
81 #[inline]
82 fn as_ref(&self) -> &dyn DynTaskInputs {
83 self.slot
84 .as_ref()
85 .expect("StackDynTaskInputsSlot::as_ref called after take_box")
86 }
87
88 #[inline]
89 fn take_box(&mut self) -> Box<dyn DynTaskInputs> {
90 Box::new(
91 self.slot
92 .take()
93 .expect("StackDynTaskInputsSlot::take_box called twice"),
94 )
95 }
96
97 #[inline]
98 fn as_any_mut(&mut self) -> &mut dyn Any {
99 self
100 }
101}
102
103pub struct OwnedStackDynTaskInputs {
105 slot: Option<Box<dyn DynTaskInputs>>,
106}
107
108impl OwnedStackDynTaskInputs {
109 #[inline]
110 pub fn new(value: Box<dyn DynTaskInputs>) -> Self {
111 Self { slot: Some(value) }
112 }
113}
114
115impl StackDynTaskInputs for OwnedStackDynTaskInputs {
116 #[inline]
117 fn as_ref(&self) -> &dyn DynTaskInputs {
118 &**self
119 .slot
120 .as_ref()
121 .expect("OwnedStackDynTaskInputs::as_ref called after take_box")
122 }
123
124 #[inline]
125 fn take_box(&mut self) -> Box<dyn DynTaskInputs> {
126 self.slot
127 .take()
128 .expect("OwnedStackDynTaskInputs::take_box called twice")
129 }
130
131 #[inline]
132 fn as_any_mut(&mut self) -> &mut dyn Any {
133 self
134 }
135}