turbo_tasks/vc/
resolved.rs1use std::{
2 any::Any,
3 fmt::Debug,
4 future::IntoFuture,
5 hash::{Hash, Hasher},
6 marker::PhantomData,
7 mem::transmute,
8 ops::Deref,
9};
10
11use anyhow::Result;
12use serde::{Deserialize, Serialize};
13
14use crate::{
15 RawVc, Upcast, VcRead, VcTransparentRead, VcValueTrait, VcValueType,
16 debug::{ValueDebug, ValueDebugFormat, ValueDebugFormatString},
17 trace::{TraceRawVcs, TraceRawVcsContext},
18 vc::Vc,
19};
20
21#[derive(Serialize, Deserialize)]
68#[serde(transparent, bound = "")]
69#[repr(transparent)]
70pub struct ResolvedVc<T>
71where
72 T: ?Sized,
73{
74 pub(crate) node: Vc<T>,
75}
76
77impl<T> ResolvedVc<T>
78where
79 T: ?Sized,
80{
81 #[deprecated(note = "No point in resolving a vc that is already resolved")]
85 pub async fn to_resolved(self) -> Result<Self> {
86 Ok(self)
87 }
88 #[deprecated(note = "No point in resolving a vc that is already resolved")]
89 pub async fn resolve(self) -> Result<Vc<T>> {
90 Ok(self.node)
91 }
92}
93
94impl<T> Copy for ResolvedVc<T> where T: ?Sized {}
95
96impl<T> Clone for ResolvedVc<T>
97where
98 T: ?Sized,
99{
100 fn clone(&self) -> Self {
101 *self
102 }
103}
104
105impl<T> Deref for ResolvedVc<T>
106where
107 T: ?Sized,
108{
109 type Target = Vc<T>;
110
111 fn deref(&self) -> &Self::Target {
112 &self.node
113 }
114}
115
116impl<T> PartialEq<ResolvedVc<T>> for ResolvedVc<T>
117where
118 T: ?Sized,
119{
120 fn eq(&self, other: &Self) -> bool {
121 self.node == other.node
122 }
123}
124
125impl<T> Eq for ResolvedVc<T> where T: ?Sized {}
126
127impl<T> Hash for ResolvedVc<T>
128where
129 T: ?Sized,
130{
131 fn hash<H: Hasher>(&self, state: &mut H) {
132 self.node.hash(state);
133 }
134}
135
136impl<T, Inner, Repr> Default for ResolvedVc<T>
137where
138 T: VcValueType<Read = VcTransparentRead<T, Inner, Repr>>,
139 Inner: Any + Send + Sync + Default,
140 Repr: VcValueType,
141{
142 fn default() -> Self {
143 Self::cell(Default::default())
144 }
145}
146
147macro_rules! into_future {
148 ($ty:ty) => {
149 impl<T> IntoFuture for $ty
150 where
151 T: VcValueType,
152 {
153 type Output = <Vc<T> as IntoFuture>::Output;
154 type IntoFuture = <Vc<T> as IntoFuture>::IntoFuture;
155 fn into_future(self) -> Self::IntoFuture {
156 (*self).into_future()
157 }
158 }
159 };
160}
161
162into_future!(ResolvedVc<T>);
163into_future!(&ResolvedVc<T>);
164into_future!(&mut ResolvedVc<T>);
165
166impl<T> ResolvedVc<T>
167where
168 T: VcValueType,
169{
170 #[doc(hidden)]
172 pub fn cell_private(inner: <T::Read as VcRead<T>>::Target) -> Self {
173 Self {
174 node: Vc::<T>::cell_private(inner),
175 }
176 }
177}
178
179impl<T, Inner, Repr> ResolvedVc<T>
180where
181 T: VcValueType<Read = VcTransparentRead<T, Inner, Repr>>,
182 Inner: Any + Send + Sync,
183 Repr: VcValueType,
184{
185 pub fn cell(inner: Inner) -> Self {
186 Self {
187 node: Vc::<T>::cell(inner),
188 }
189 }
190}
191
192impl<T> ResolvedVc<T>
193where
194 T: ?Sized,
195{
196 #[inline(always)]
200 pub fn upcast<K>(this: Self) -> ResolvedVc<K>
201 where
202 T: Upcast<K>,
203 K: VcValueTrait + ?Sized,
204 {
205 ResolvedVc {
206 node: Vc::upcast(this.node),
207 }
208 }
209
210 pub fn deref_vec(vec: Vec<ResolvedVc<T>>) -> Vec<Vc<T>> {
212 debug_assert!(size_of::<ResolvedVc<T>>() == size_of::<Vc<T>>());
213 unsafe { transmute::<Vec<ResolvedVc<T>>, Vec<Vc<T>>>(vec) }
215 }
216
217 pub fn deref_slice(slice: &[ResolvedVc<T>]) -> &[Vc<T>] {
219 debug_assert!(size_of::<ResolvedVc<T>>() == size_of::<Vc<T>>());
220 unsafe { transmute::<&[ResolvedVc<T>], &[Vc<T>]>(slice) }
222 }
223}
224
225impl<T> ResolvedVc<T>
226where
227 T: VcValueTrait + ?Sized,
228{
229 pub fn try_sidecast<K>(this: Self) -> Option<ResolvedVc<K>>
236 where
237 K: VcValueTrait + ?Sized,
238 {
239 let raw_vc = this.node.node;
242 raw_vc
243 .resolved_has_trait(<K as VcValueTrait>::get_trait_type_id())
244 .then_some(ResolvedVc {
245 node: Vc {
246 node: raw_vc,
247 _t: PhantomData,
248 },
249 })
250 }
251
252 pub fn try_downcast<K>(this: Self) -> Option<ResolvedVc<K>>
259 where
260 K: Upcast<T> + VcValueTrait + ?Sized,
261 {
262 Self::try_sidecast(this)
264 }
265
266 pub fn try_downcast_type<K>(this: Self) -> Option<ResolvedVc<K>>
272 where
273 K: Upcast<T> + VcValueType,
274 {
275 let raw_vc = this.node.node;
276 raw_vc
277 .resolved_is_type(<K as VcValueType>::get_value_type_id())
278 .then_some(ResolvedVc {
279 node: Vc {
280 node: raw_vc,
281 _t: PhantomData,
282 },
283 })
284 }
285}
286
287impl<T> Debug for ResolvedVc<T>
294where
295 T: ?Sized,
296{
297 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
298 f.debug_struct("ResolvedVc")
299 .field("node", &self.node.node)
300 .finish()
301 }
302}
303
304impl<T> TraceRawVcs for ResolvedVc<T>
305where
306 T: ?Sized,
307{
308 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
309 TraceRawVcs::trace_raw_vcs(&self.node, trace_context);
310 }
311}
312
313impl<T> ValueDebugFormat for ResolvedVc<T>
314where
315 T: Upcast<Box<dyn ValueDebug>> + Send + Sync + ?Sized,
316{
317 fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString {
318 self.node.value_debug_format(depth)
319 }
320}
321
322impl<T> TryFrom<RawVc> for ResolvedVc<T>
323where
324 T: ?Sized,
325{
326 type Error = anyhow::Error;
327
328 fn try_from(raw: RawVc) -> Result<Self> {
329 if !matches!(raw, RawVc::TaskCell(..)) {
330 anyhow::bail!("Given RawVc {raw:?} is not a TaskCell");
331 }
332 Ok(Self {
333 node: Vc::from(raw),
334 })
335 }
336}