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 bincode::{Decode, Encode};
13use serde::{Deserialize, Serialize};
14
15use crate::{
16 RawVc, Upcast, UpcastStrict, VcRead, VcTransparentRead, VcValueTrait, VcValueType,
17 debug::{ValueDebug, ValueDebugFormat, ValueDebugFormatString},
18 trace::{TraceRawVcs, TraceRawVcsContext},
19 vc::Vc,
20};
21
22#[derive(Serialize, Deserialize, Encode, Decode)]
69#[serde(transparent, bound = "")]
70#[bincode(bounds = "T: ?Sized")]
71#[repr(transparent)]
72pub struct ResolvedVc<T>
73where
74 T: ?Sized,
75{
76 pub(crate) node: Vc<T>,
77}
78
79impl<T> ResolvedVc<T>
80where
81 T: ?Sized,
82{
83 #[deprecated(note = "No point in resolving a vc that is already resolved")]
87 pub async fn to_resolved(self) -> Result<Self> {
88 Ok(self)
89 }
90 #[deprecated(note = "No point in resolving a vc that is already resolved")]
91 pub async fn resolve(self) -> Result<Vc<T>> {
92 Ok(self.node)
93 }
94}
95
96impl<T> Copy for ResolvedVc<T> where T: ?Sized {}
97
98impl<T> Clone for ResolvedVc<T>
99where
100 T: ?Sized,
101{
102 fn clone(&self) -> Self {
103 *self
104 }
105}
106
107impl<T> Deref for ResolvedVc<T>
108where
109 T: ?Sized,
110{
111 type Target = Vc<T>;
112
113 fn deref(&self) -> &Self::Target {
114 &self.node
115 }
116}
117
118impl<T> PartialEq<ResolvedVc<T>> for ResolvedVc<T>
119where
120 T: ?Sized,
121{
122 fn eq(&self, other: &Self) -> bool {
123 self.node == other.node
124 }
125}
126
127impl<T> Eq for ResolvedVc<T> where T: ?Sized {}
128
129impl<T> Hash for ResolvedVc<T>
130where
131 T: ?Sized,
132{
133 fn hash<H: Hasher>(&self, state: &mut H) {
134 self.node.hash(state);
135 }
136}
137
138impl<T, Inner> Default for ResolvedVc<T>
139where
140 T: VcValueType<Read = VcTransparentRead<T, Inner>>,
141 Inner: Any + Send + Sync + Default,
142{
143 fn default() -> Self {
144 Self::cell(Default::default())
145 }
146}
147
148macro_rules! into_future {
149 ($ty:ty) => {
150 impl<T> IntoFuture for $ty
151 where
152 T: VcValueType,
153 {
154 type Output = <Vc<T> as IntoFuture>::Output;
155 type IntoFuture = <Vc<T> as IntoFuture>::IntoFuture;
156 fn into_future(self) -> Self::IntoFuture {
157 (*self).into_future()
158 }
159 }
160 };
161}
162
163into_future!(ResolvedVc<T>);
164into_future!(&ResolvedVc<T>);
165into_future!(&mut ResolvedVc<T>);
166
167impl<T> ResolvedVc<T>
168where
169 T: VcValueType,
170{
171 #[doc(hidden)]
173 pub fn cell_private(inner: <T::Read as VcRead<T>>::Target) -> Self {
174 Self {
175 node: Vc::<T>::cell_private(inner),
176 }
177 }
178}
179
180impl<T, Inner> ResolvedVc<T>
181where
182 T: VcValueType<Read = VcTransparentRead<T, Inner>>,
183 Inner: Any + Send + Sync,
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: UpcastStrict<K>,
203 K: VcValueTrait + ?Sized,
204 {
205 Self::upcast_non_strict(this)
206 }
207
208 #[inline(always)]
214 pub fn upcast_non_strict<K>(this: Self) -> ResolvedVc<K>
215 where
216 T: Upcast<K>,
217 K: VcValueTrait + ?Sized,
218 {
219 ResolvedVc {
220 node: Vc::upcast_non_strict(this.node),
221 }
222 }
223
224 #[inline(always)]
228 pub fn upcast_vec<K>(vec: Vec<Self>) -> Vec<ResolvedVc<K>>
229 where
230 T: UpcastStrict<K>,
231 K: VcValueTrait + ?Sized,
232 {
233 debug_assert!(size_of::<ResolvedVc<T>>() == size_of::<ResolvedVc<K>>());
234 debug_assert!(size_of::<Vec<ResolvedVc<T>>>() == size_of::<Vec<ResolvedVc<K>>>());
235 let (ptr, len, capacity) = vec.into_raw_parts();
236 unsafe { Vec::from_raw_parts(ptr as *mut ResolvedVc<K>, len, capacity) }
238 }
239
240 pub fn deref_vec(vec: Vec<ResolvedVc<T>>) -> Vec<Vc<T>> {
242 debug_assert!(size_of::<ResolvedVc<T>>() == size_of::<Vc<T>>());
243 unsafe { transmute::<Vec<ResolvedVc<T>>, Vec<Vc<T>>>(vec) }
245 }
246
247 pub fn deref_slice(slice: &[ResolvedVc<T>]) -> &[Vc<T>] {
249 debug_assert!(size_of::<ResolvedVc<T>>() == size_of::<Vc<T>>());
250 unsafe { transmute::<&[ResolvedVc<T>], &[Vc<T>]>(slice) }
252 }
253}
254
255impl<T> ResolvedVc<T>
256where
257 T: VcValueTrait + ?Sized,
258{
259 pub fn try_sidecast<K>(this: Self) -> Option<ResolvedVc<K>>
266 where
267 K: VcValueTrait + ?Sized,
268 {
269 debug_assert!(
273 <K as VcValueTrait>::get_trait_type_id() != <T as VcValueTrait>::get_trait_type_id(),
274 "Attempted to cast a type {} to itself, which is pointless. Use the value directly \
275 instead.",
276 crate::registry::get_trait(<T as VcValueTrait>::get_trait_type_id()).global_name
277 );
278 let raw_vc = this.node.node;
281 raw_vc
282 .resolved_has_trait(<K as VcValueTrait>::get_trait_type_id())
283 .then_some(ResolvedVc {
284 node: Vc {
285 node: raw_vc,
286 _t: PhantomData,
287 },
288 })
289 }
290
291 pub fn try_downcast<K>(this: Self) -> Option<ResolvedVc<K>>
298 where
299 K: UpcastStrict<T> + VcValueTrait + ?Sized,
300 {
301 Self::try_sidecast(this)
303 }
304
305 pub fn try_downcast_type<K>(this: Self) -> Option<ResolvedVc<K>>
311 where
312 K: UpcastStrict<T> + VcValueType,
313 {
314 let raw_vc = this.node.node;
315 raw_vc
316 .resolved_is_type(<K as VcValueType>::get_value_type_id())
317 .then_some(ResolvedVc {
318 node: Vc {
319 node: raw_vc,
320 _t: PhantomData,
321 },
322 })
323 }
324}
325
326impl<T> Debug for ResolvedVc<T>
333where
334 T: ?Sized,
335{
336 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
337 f.debug_tuple("ResolvedVc").field(&self.node.node).finish()
338 }
339}
340
341impl<T> TraceRawVcs for ResolvedVc<T>
342where
343 T: ?Sized,
344{
345 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
346 TraceRawVcs::trace_raw_vcs(&self.node, trace_context);
347 }
348}
349
350impl<T> ValueDebugFormat for ResolvedVc<T>
351where
352 T: UpcastStrict<Box<dyn ValueDebug>> + Send + Sync + ?Sized,
353{
354 fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString<'_> {
355 self.node.value_debug_format(depth)
356 }
357}
358
359impl<T> TryFrom<RawVc> for ResolvedVc<T>
360where
361 T: ?Sized,
362{
363 type Error = anyhow::Error;
364
365 fn try_from(raw: RawVc) -> Result<Self> {
366 if !matches!(raw, RawVc::TaskCell(..)) {
367 anyhow::bail!("Given RawVc {raw:?} is not a TaskCell");
368 }
369 Ok(Self {
370 node: Vc::from(raw),
371 })
372 }
373}