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