1use std::{
2 any::Any,
3 fmt::Debug,
4 future::IntoFuture,
5 hash::{Hash, Hasher},
6 marker::PhantomData,
7 ops::Deref,
8 slice,
9};
10
11use anyhow::Result;
12use bincode::{Decode, Encode};
13use serde::{Deserialize, Serialize};
14
15#[cfg(debug_assertions)]
16use crate::debug::{ValueDebug, ValueDebugFormat, ValueDebugFormatString};
17use crate::{
18 RawVc, Upcast, UpcastStrict, VcRead, VcTransparentRead, VcValueTrait, VcValueType,
19 trace::{TraceRawVcs, TraceRawVcsContext},
20 vc::Vc,
21};
22
23#[derive(Serialize, Deserialize, Encode, Decode)]
76#[serde(transparent, bound = "")]
77#[bincode(bounds = "T: ?Sized")]
78#[repr(transparent)]
79pub struct ResolvedVc<T>
80where
81 T: ?Sized,
82{
83 pub(crate) node: Vc<T>,
84}
85
86impl<T> ResolvedVc<T>
87where
88 T: ?Sized,
89{
90 #[deprecated(note = "No point in resolving a vc that is already resolved")]
94 pub async fn to_resolved(self) -> Result<Self> {
95 Ok(self)
96 }
97 #[deprecated(note = "No point in resolving a vc that is already resolved")]
98 pub async fn resolve(self) -> Result<Vc<T>> {
99 Ok(self.node)
100 }
101}
102
103impl<T> Copy for ResolvedVc<T> where T: ?Sized {}
104
105impl<T> Clone for ResolvedVc<T>
106where
107 T: ?Sized,
108{
109 fn clone(&self) -> Self {
110 *self
111 }
112}
113
114impl<T> Deref for ResolvedVc<T>
115where
116 T: ?Sized,
117{
118 type Target = Vc<T>;
119
120 fn deref(&self) -> &Self::Target {
121 &self.node
122 }
123}
124
125impl<T> PartialEq<ResolvedVc<T>> for ResolvedVc<T>
126where
127 T: ?Sized,
128{
129 fn eq(&self, other: &Self) -> bool {
130 self.node == other.node
131 }
132}
133
134impl<T> Eq for ResolvedVc<T> where T: ?Sized {}
135
136impl<T> Hash for ResolvedVc<T>
137where
138 T: ?Sized,
139{
140 fn hash<H: Hasher>(&self, state: &mut H) {
141 self.node.hash(state);
142 }
143}
144
145impl<T, Inner> Default for ResolvedVc<T>
146where
147 T: VcValueType<Read = VcTransparentRead<T, Inner>>,
148 Inner: Any + Send + Sync + Default,
149{
150 fn default() -> Self {
151 Self::cell(Default::default())
152 }
153}
154
155macro_rules! into_future {
156 ($ty:ty) => {
157 impl<T> IntoFuture for $ty
158 where
159 T: VcValueType,
160 {
161 type Output = <Vc<T> as IntoFuture>::Output;
162 type IntoFuture = <Vc<T> as IntoFuture>::IntoFuture;
163 fn into_future(self) -> Self::IntoFuture {
164 (*self).into_future()
165 }
166 }
167 };
168}
169
170into_future!(ResolvedVc<T>);
171into_future!(&ResolvedVc<T>);
172into_future!(&mut ResolvedVc<T>);
173
174impl<T> ResolvedVc<T>
175where
176 T: VcValueType,
177{
178 #[doc(hidden)]
180 pub fn cell_private(inner: <T::Read as VcRead<T>>::Target) -> Self {
181 Self {
182 node: Vc::<T>::cell_private(inner),
183 }
184 }
185}
186
187impl<T, Inner> ResolvedVc<T>
188where
189 T: VcValueType<Read = VcTransparentRead<T, Inner>>,
190 Inner: Any + Send + Sync,
191{
192 pub fn cell(inner: Inner) -> Self {
193 Self {
194 node: Vc::<T>::cell(inner),
195 }
196 }
197}
198
199impl<T> ResolvedVc<T>
200where
201 T: ?Sized,
202{
203 #[inline(always)]
207 pub fn upcast<K>(this: Self) -> ResolvedVc<K>
208 where
209 T: UpcastStrict<K>,
210 K: VcValueTrait + ?Sized,
211 {
212 Self::upcast_non_strict(this)
213 }
214
215 #[inline(always)]
221 pub fn upcast_non_strict<K>(this: Self) -> ResolvedVc<K>
222 where
223 T: Upcast<K>,
224 K: VcValueTrait + ?Sized,
225 {
226 ResolvedVc {
227 node: Vc::upcast_non_strict(this.node),
228 }
229 }
230
231 #[inline(always)]
235 pub fn upcast_vec<K>(vec: Vec<Self>) -> Vec<ResolvedVc<K>>
236 where
237 T: UpcastStrict<K>,
238 K: VcValueTrait + ?Sized,
239 {
240 debug_assert!(size_of::<ResolvedVc<T>>() == size_of::<ResolvedVc<K>>());
241 debug_assert!(size_of::<Vec<ResolvedVc<T>>>() == size_of::<Vec<ResolvedVc<K>>>());
242 let (ptr, len, capacity) = vec.into_raw_parts();
243 unsafe { Vec::from_raw_parts(ptr as *mut ResolvedVc<K>, len, capacity) }
245 }
246
247 pub fn deref_vec(vec: Vec<ResolvedVc<T>>) -> Vec<Vc<T>> {
249 debug_assert!(size_of::<ResolvedVc<T>>() == size_of::<Vc<T>>());
250 let (ptr, len, capacity) = vec.into_raw_parts();
251 unsafe { Vec::from_raw_parts(ptr as *mut Vc<T>, len, capacity) }
253 }
254
255 pub fn deref_slice(s: &[ResolvedVc<T>]) -> &[Vc<T>] {
257 debug_assert!(size_of::<ResolvedVc<T>>() == size_of::<Vc<T>>());
258 unsafe { slice::from_raw_parts(s.as_ptr() as *const Vc<T>, s.len()) }
260 }
261}
262
263impl<T> ResolvedVc<T>
264where
265 T: VcValueTrait + ?Sized,
266{
267 pub fn try_sidecast<K>(this: Self) -> Option<ResolvedVc<K>>
272 where
273 K: VcValueTrait + ?Sized,
274 {
275 debug_assert!(
279 <K as VcValueTrait>::get_trait_type_id() != <T as VcValueTrait>::get_trait_type_id(),
280 "Attempted to cast a type {} to itself, which is pointless. Use the value directly \
281 instead.",
282 crate::registry::get_trait(<T as VcValueTrait>::get_trait_type_id())
283 .ty
284 .global_name
285 );
286 let raw_vc = this.node.node;
289 raw_vc
290 .resolved_has_trait(<K as VcValueTrait>::get_trait_type_id())
291 .then_some(ResolvedVc {
292 node: Vc {
293 node: raw_vc,
294 _t: PhantomData,
295 },
296 })
297 }
298
299 pub fn try_downcast<K>(this: Self) -> Option<ResolvedVc<K>>
304 where
305 K: UpcastStrict<T> + VcValueTrait + ?Sized,
306 {
307 Self::try_sidecast(this)
309 }
310
311 pub fn try_downcast_type<K>(this: Self) -> Option<ResolvedVc<K>>
315 where
316 K: UpcastStrict<T> + VcValueType,
317 {
318 let raw_vc = this.node.node;
319 raw_vc
320 .resolved_is_type(<K as VcValueType>::get_value_type_id())
321 .then_some(ResolvedVc {
322 node: Vc {
323 node: raw_vc,
324 _t: PhantomData,
325 },
326 })
327 }
328}
329
330impl<T> Debug for ResolvedVc<T>
337where
338 T: ?Sized,
339{
340 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
341 f.debug_tuple("ResolvedVc").field(&self.node.node).finish()
342 }
343}
344
345impl<T> TraceRawVcs for ResolvedVc<T>
346where
347 T: ?Sized,
348{
349 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
350 TraceRawVcs::trace_raw_vcs(&self.node, trace_context);
351 }
352}
353
354#[cfg(debug_assertions)]
355impl<T> ValueDebugFormat for ResolvedVc<T>
356where
357 T: UpcastStrict<Box<dyn ValueDebug>> + Send + Sync + ?Sized,
358{
359 fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString<'_> {
360 self.node.value_debug_format(depth)
361 }
362}
363
364impl<T> TryFrom<RawVc> for ResolvedVc<T>
365where
366 T: ?Sized,
367{
368 type Error = anyhow::Error;
369
370 fn try_from(raw: RawVc) -> Result<Self> {
371 if !matches!(raw, RawVc::TaskCell(..)) {
372 anyhow::bail!("Given RawVc {raw:?} is not a TaskCell");
373 }
374 Ok(Self {
375 node: Vc::from(raw),
376 })
377 }
378}