turbo_tasks/vc/
mod.rs

1pub(crate) mod cast;
2mod cell_mode;
3pub(crate) mod default;
4mod local;
5pub(crate) mod operation;
6mod read;
7pub(crate) mod resolved;
8mod traits;
9
10use std::{
11    any::Any,
12    fmt::Debug,
13    future::{Future, IntoFuture},
14    hash::{Hash, Hasher},
15    marker::PhantomData,
16    ops::Deref,
17};
18
19use anyhow::Result;
20use bincode::{Decode, Encode};
21use serde::{Deserialize, Serialize};
22use shrink_to_fit::ShrinkToFit;
23
24pub use self::{
25    cast::{VcCast, VcValueTraitCast, VcValueTypeCast},
26    cell_mode::{VcCellCompareMode, VcCellMode, VcCellNewMode},
27    default::ValueDefault,
28    local::NonLocalValue,
29    operation::{OperationValue, OperationVc},
30    read::{ReadOwnedVcFuture, ReadVcFuture, VcDefaultRead, VcRead, VcTransparentRead},
31    resolved::ResolvedVc,
32    traits::{Dynamic, Upcast, UpcastStrict, VcValueTrait, VcValueType},
33};
34use crate::{
35    CellId, RawVc, ResolveTypeError,
36    debug::{ValueDebug, ValueDebugFormat, ValueDebugFormatString},
37    registry,
38    trace::{TraceRawVcs, TraceRawVcsContext},
39};
40
41type VcReadTarget<T> = <<T as VcValueType>::Read as VcRead<T>>::Target;
42
43/// A "Value Cell" (`Vc` for short) is a reference to a memoized computation result stored on the
44/// heap or in filesystem cache, depending on the Turbo Engine backend implementation.
45///
46/// In order to get a reference to the pointed value, you need to `.await` the [`Vc<T>`] to get a
47/// [`ReadRef<T>`][`ReadRef`]:
48///
49/// ```
50/// let some_vc: Vc<T>;
51/// let some_ref: ReadRef<T> = some_vc.await?;
52/// some_ref.some_method_on_t();
53/// ```
54///
55/// `Vc`s are similar to a [`Future`] or a Promise with a few key differences:
56///
57/// - The value pointed to by a `Vc` can be invalidated by changing dependencies or cache evicted,
58///   meaning that `await`ing a `Vc` multiple times can give different results. A [`ReadRef`] is
59///   snapshot of the underlying cell at a point in time.
60///
61/// - Reading (`await`ing) `Vc`s causes the current task to be tracked a dependent of the `Vc`'s
62///   task or task cell. When the read task or task cell changes, the current task may be
63///   re-executed.
64///
65/// - `Vc` types are always [`Copy`]. Most [`Future`]s are not. This works because `Vc`s are
66///   represented as a few ids or indices into data structures managed by the `turbo-tasks`
67///   framework. `Vc` types are not reference counted, but do support [tracing] for a hypothetical
68///   (unimplemented) garbage collector.
69///
70/// - Unlike futures (but like promises), the work that a `Vc` represents [begins execution even if
71///   the `Vc` is not `await`ed](#execution-model).
72///
73/// For a more in-depth explanation of the concepts behind value cells, [refer to the Turbopack
74/// book][book-cells].
75///
76///
77/// ## Subtypes
78///
79/// There are a couple of explicit "subtypes" of `Vc`. These can both be cheaply converted back into
80/// a `Vc`.
81///
82/// - **[`ResolvedVc`]:** *(aka [`RawVc::TaskCell`])* A reference to a cell constructed within a
83///   task, as part of a [`Vc::cell`] or `value_type.cell()` constructor. As the cell has been
84///   constructed at least once, the concrete type of the cell is known (allowing
85///   [downcasting][ResolvedVc::try_downcast]). This is stored as a combination of a task id, a type
86///   id, and a cell id.
87///
88/// - **[`OperationVc`]:** *(aka [`RawVc::TaskOutput`])* The synchronous return value of a
89///   [`turbo_tasks::function`]. Internally, this is stored using a task id. Exact type information
90///   of trait types (i.e. `Vc<Box<dyn Trait>>`) is not known because the function may not have
91///   finished execution yet. [`OperationVc`]s must first be [`connect`][OperationVc::connect]ed
92///   before being read.
93///
94/// [`ResolvedVc`] is almost always preferred over the more awkward [`OperationVc`] API, but
95/// [`OperationVc`] can be useful when dealing with [collectibles], when you need to [read the
96/// result of a function with strong consistency][OperationVc::read_strongly_consistent], or with
97/// [`State`].
98///
99/// These many representations are stored internally using a type-erased [`RawVc`]. Type erasure
100/// reduces the [monomorphization] (and therefore binary size and compilation time) required to
101/// support `Vc` and its subtypes.
102///
103/// |                 | Representation                     | Equality        | Downcasting                | Strong Consistency     | Collectibles      | [Non-Local]  |
104/// |-----------------|------------------------------------|-----------------|----------------------------|------------------------|-------------------|--------------|
105/// | [`Vc`]          | [One of many][RawVc]               | ❌ [Broken][eq] | ⚠️  After resolution        | ❌ Eventual            | ❌ No             | ❌ [No][loc] |
106/// | [`ResolvedVc`]  | [Task Id + Type Id + Cell Id][rtc] | ✅ Yes\*        | ✅ [Yes, cheaply][resolve] | ❌ Eventual            | ❌ No             | ✅ Yes       |
107/// | [`OperationVc`] | [Task Id][rto]                     | ✅ Yes\*        | ⚠️  After resolution        | ✅ [Supported][strong] | ✅ [Yes][collect] | ✅ Yes       |
108///
109/// *\* see the type's documentation for details*
110///
111/// [Non-Local]: NonLocalValue
112/// [rtc]: RawVc::TaskCell
113/// [rto]: RawVc::TaskOutput
114/// [loc]: #optimization-local-outputs
115/// [eq]: #equality--hashing
116/// [resolve]: ResolvedVc::try_downcast
117/// [strong]: OperationVc::read_strongly_consistent
118/// [collect]: crate::CollectiblesSource
119///
120///
121/// ## Execution Model
122///
123/// While task functions are expected to be side-effect free, their execution behavior is still
124/// important for performance reasons, or to code using [collectibles] to represent issues or
125/// side-effects.
126///
127/// Function calls are neither "eager", nor "lazy". Even if not awaited, they are guaranteed to
128/// execute (potentially emitting collectibles) before the root task finishes or before the
129/// completion of any strongly consistent read containing their call. However, the exact point when
130/// that execution begins is an implementation detail. Functions may execute more than once due to
131/// dirty task invalidation.
132///
133///
134/// ## Equality & Hashing
135///
136/// Because `Vc`s can be equivalent but have different representation, it's not recommended to
137/// compare `Vc`s by equality. Instead, you should convert a `Vc` to an explicit subtype first
138/// (likely [`ResolvedVc`]). Future versions of `Vc` may not implement [`Eq`], [`PartialEq`], or
139/// [`Hash`].
140///
141///
142/// ## Optimization: Local Outputs
143///
144/// In addition to the potentially-explicit "resolved" and "operation" representations of a `Vc`,
145/// there's another internal representation of a `Vc`, known as a "Local `Vc`", or
146/// [`RawVc::LocalOutput`].
147///
148/// This is a special case of the synchronous return value of a [`turbo_tasks::function`] when some
149/// of its arguments have not yet been resolved. These are stored in task-local state that is freed
150/// after their parent non-local task exits.
151///
152/// We prevent potentially-local `Vc`s from escaping the lifetime of a function using the
153/// [`NonLocalValue`] marker trait alongside some fallback runtime checks. We do this to avoid some
154/// ergonomic challenges that would come from using lifetime annotations with `Vc`.
155///
156///
157/// [tracing]: crate::trace::TraceRawVcs
158/// [`ReadRef`]: crate::ReadRef
159/// [`turbo_tasks::function`]: crate::function
160/// [monomorphization]: https://doc.rust-lang.org/book/ch10-01-syntax.html#performance-of-code-using-generics
161/// [`State`]: crate::State
162/// [book-cells]: https://turbopack-rust-docs.vercel.sh/turbo-engine/cells.html
163/// [collectibles]: crate::CollectiblesSource
164#[must_use]
165#[derive(Serialize, Deserialize, Encode, Decode)]
166#[serde(transparent, bound = "")]
167#[bincode(bounds = "T: ?Sized")]
168#[repr(transparent)]
169pub struct Vc<T>
170where
171    T: ?Sized,
172{
173    pub(crate) node: RawVc,
174    #[doc(hidden)]
175    pub(crate) _t: PhantomData<T>,
176}
177
178/// This only exists to satisfy the Rust type system. However, this struct can
179/// never actually be instantiated, as dereferencing a `Vc<T>` will result in a
180/// linker error. See the implementation of `Deref` for `Vc<T>`.
181pub struct VcDeref<T>
182where
183    T: ?Sized,
184{
185    _t: PhantomData<T>,
186}
187
188macro_rules! do_not_use_or_you_will_be_fired {
189    ($($name:ident)*) => {
190        impl<T> VcDeref<T>
191        where
192            T: ?Sized,
193        {
194            $(
195                #[doc(hidden)]
196                #[allow(unused)]
197                #[allow(clippy::wrong_self_convention)]
198                #[deprecated = "This is not the method you are looking for."]
199                pub fn $name(self) {}
200            )*
201        }
202    };
203}
204
205// Hide raw pointer methods on `Vc<T>`. This is an artifact of having
206// implement `Deref<Target = *const T>` on `Vc<T>` for `arbitrary_self_types` to
207// do its thing. This can be removed once the `Receiver` trait no longer depends
208// on `Deref`.
209do_not_use_or_you_will_be_fired!(
210    add
211    addr
212    align_offset
213    as_mut
214    as_mut_ptr
215    as_ptr
216    as_ref
217    as_uninit_mut
218    as_uninit_ref
219    as_uninit_slice
220    as_uninit_slice_mut
221    byte_add
222    byte_offset
223    byte_offset_from
224    byte_sub
225    cast
226    cast_const
227    cast_mut
228    copy_from
229    copy_from_nonoverlapping
230    copy_to
231    copy_to_nonoverlapping
232    drop_in_place
233    expose_addr
234    from_bits
235    get_unchecked
236    get_unchecked_mut
237    guaranteed_eq
238    guaranteed_ne
239    is_aligned
240    is_aligned_to
241    is_empty
242    is_null
243    len
244    map_addr
245    mask
246    offset
247    offset_from
248    read
249    read_unaligned
250    read_volatile
251    replace
252    split_at_mut
253    split_at_mut_unchecked
254    sub
255    sub_ptr
256    swap
257    to_bits
258    to_raw_parts
259    with_addr
260    with_metadata_of
261    wrapping_add
262    wrapping_byte_add
263    wrapping_byte_offset
264    wrapping_byte_sub
265    wrapping_offset
266    wrapping_sub
267    write
268    write_bytes
269    write_unaligned
270    write_volatile
271);
272
273// Call this macro for all the applicable methods above:
274
275#[doc(hidden)]
276impl<T> Deref for VcDeref<T>
277where
278    T: ?Sized,
279{
280    // `*const T` or `*mut T` would be enough here, but from an abundance of
281    // caution, we use `*const *mut *const T` to make sure there will never be an
282    // applicable method.
283    type Target = *const *mut *const T;
284
285    fn deref(&self) -> &Self::Target {
286        unsafe extern "C" {
287            #[link_name = "\n\nERROR: you tried to dereference a `Vc<T>`\n"]
288            fn trigger() -> !;
289        }
290
291        unsafe { trigger() };
292    }
293}
294
295// This is the magic that makes `Vc<T>` accept `self: Vc<Self>` methods through
296// `arbitrary_self_types`, while not allowing any other receiver type:
297// * `Vc<T>` dereferences to `*const *mut *const T`, which means that it is valid under the
298//   `arbitrary_self_types` rules.
299// * `*const *mut *const T` is not a valid receiver for any attribute access on `T`, which means
300//   that the only applicable items will be the methods declared on `self: Vc<Self>`.
301//
302// If we had used `type Target = T` instead, `vc_t.some_attr_defined_on_t` would
303// have been accepted by the compiler.
304#[doc(hidden)]
305impl<T> Deref for Vc<T>
306where
307    T: ?Sized,
308{
309    type Target = VcDeref<T>;
310
311    fn deref(&self) -> &Self::Target {
312        unsafe extern "C" {
313            #[link_name = "\n\nERROR: you tried to dereference a `Vc<T>`\n"]
314            fn trigger() -> !;
315        }
316
317        unsafe { trigger() };
318    }
319}
320
321impl<T> Copy for Vc<T> where T: ?Sized {}
322
323impl<T> Clone for Vc<T>
324where
325    T: ?Sized,
326{
327    fn clone(&self) -> Self {
328        *self
329    }
330}
331
332impl<T> Hash for Vc<T>
333where
334    T: ?Sized,
335{
336    fn hash<H: Hasher>(&self, state: &mut H) {
337        self.node.hash(state);
338    }
339}
340
341impl<T> PartialEq<Vc<T>> for Vc<T>
342where
343    T: ?Sized,
344{
345    fn eq(&self, other: &Self) -> bool {
346        self.node == other.node
347    }
348}
349
350impl<T> Eq for Vc<T> where T: ?Sized {}
351
352/// Generates an opaque debug representation of the [`Vc`] itself, but not the data inside of it.
353///
354/// This is implemented to allow types containing [`Vc`] to implement the synchronous [`Debug`]
355/// trait, but in most cases users should use the [`ValueDebug`] implementation to get a string
356/// representation of the contents of the cell.
357impl<T> Debug for Vc<T>
358where
359    T: ?Sized,
360{
361    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
362        f.debug_tuple("Vc").field(&self.node).finish()
363    }
364}
365
366impl<T> Vc<T>
367where
368    T: VcValueType,
369{
370    // called by the `.cell()` method generated by the `#[turbo_tasks::value]` macro
371    #[doc(hidden)]
372    pub fn cell_private(mut inner: <T::Read as VcRead<T>>::Target) -> Self {
373        // cell contents are immutable, so go ahead and shrink the cell's contents
374        ShrinkToFit::shrink_to_fit(<T::Read as VcRead<T>>::target_to_value_mut_ref(&mut inner));
375        <T::CellMode as VcCellMode<T>>::cell(inner)
376    }
377}
378
379impl<T, Inner, Repr> Vc<T>
380where
381    T: VcValueType<Read = VcTransparentRead<T, Inner, Repr>>,
382    Inner: Any + Send + Sync,
383    Repr: VcValueType,
384{
385    pub fn cell(inner: Inner) -> Self {
386        Self::cell_private(inner)
387    }
388}
389
390impl<T> Vc<T>
391where
392    T: ?Sized,
393{
394    /// Returns a debug identifier for this `Vc`.
395    pub async fn debug_identifier(vc: Self) -> Result<String> {
396        let resolved = vc.resolve().await?;
397        let raw_vc: RawVc = resolved.node;
398        if let RawVc::TaskCell(task_id, CellId { type_id, index }) = raw_vc {
399            let value_ty = registry::get_value_type(type_id);
400            Ok(format!("{}#{}: {}", value_ty.name, index, task_id))
401        } else {
402            unreachable!()
403        }
404    }
405
406    /// Returns the `RawVc` corresponding to this `Vc`.
407    pub fn into_raw(vc: Self) -> RawVc {
408        vc.node
409    }
410
411    /// Upcasts the given `Vc<T>` to a `Vc<Box<dyn K>>`.
412    ///
413    /// This is also available as an `Into`/`From` conversion.
414    #[inline(always)]
415    pub fn upcast<K>(vc: Self) -> Vc<K>
416    where
417        T: UpcastStrict<K>,
418        K: VcValueTrait + ?Sized,
419    {
420        Self::upcast_non_strict(vc)
421    }
422
423    /// Upcasts the given `Vc<T>` to a `Vc<Box<dyn K>>`
424    ///
425    /// This has a loose type constraint which would allow upcasting to the same type, prefer using
426    /// [`Vc::upcast`] when possible.  This is useful for extension traits and other more generic
427    /// usecases.
428    ///
429    /// # Example
430    /// ```rust
431    /// // In generic code where T might be the same as K
432    /// fn process_foo(vc: ResolvedVc<impl Upcast<Box<dyn MyTrait>>>) -> Vc<Foo> {
433    ///    let my_trait: ResolvedVc<Box<dyn MyTrait>> = Vc::upcast_non_strict(vc);
434    ///    my_trait.do_something()
435    /// }
436    /// ```
437    /// Using generics you could allow users to pass any compatible type, but if you specified
438    /// `UpcastStrict<...>` instead of `Upcast<...>` you would disallow calling this function if you
439    /// already had a `ResolvedVc<Box<dyn MyTrait>>.  So this function has a looser type constraint
440    /// to make these functions easier to write and use.
441    #[inline(always)]
442    pub fn upcast_non_strict<K>(vc: Self) -> Vc<K>
443    where
444        T: Upcast<K>,
445        K: VcValueTrait + ?Sized,
446    {
447        Vc {
448            node: vc.node,
449            _t: PhantomData,
450        }
451    }
452    /// Runs the operation, but ignores the returned Vc. Use that when only interested in running
453    /// the task for side effects.
454    pub async fn as_side_effect(self) -> Result<()> {
455        self.node.resolve().await?;
456        Ok(())
457    }
458
459    /// Do not use this: Use [`Vc::to_resolved`] instead. If you must have a resolved [`Vc`] type
460    /// and not a [`ResolvedVc`] type, simply deref the result of [`Vc::to_resolved`].
461    pub async fn resolve(self) -> Result<Vc<T>> {
462        Ok(Self {
463            node: self.node.resolve().await?,
464            _t: PhantomData,
465        })
466    }
467
468    /// Resolve the reference until it points to a cell directly, and wrap the
469    /// result in a [`ResolvedVc`], which statically guarantees that the
470    /// [`Vc`] was resolved.
471    pub async fn to_resolved(self) -> Result<ResolvedVc<T>> {
472        Ok(ResolvedVc {
473            node: self.resolve().await?,
474        })
475    }
476
477    /// Returns `true` if the reference is resolved, meaning the underlying [`RawVc`] uses the
478    /// [`RawVc::TaskCell`] representation.
479    ///
480    /// If you need resolved [`Vc`] value, it's typically better to use the [`ResolvedVc`] type to
481    /// enforce your requirements statically instead of dynamically at runtime.
482    ///
483    /// See also [`ResolvedVc::to_resolved`] and [`RawVc::is_resolved`].
484    pub fn is_resolved(self) -> bool {
485        self.node.is_resolved()
486    }
487
488    /// Returns `true` if the `Vc` was by a local function call (e.g. one who's arguments were not
489    /// fully resolved) and has not yet been resolved.
490    ///
491    /// Aside from differences in caching, a function's behavior should not be changed by using
492    /// local or non-local cells, so this function is mostly useful inside tests and internally in
493    /// turbo-tasks.
494    pub fn is_local(self) -> bool {
495        self.node.is_local()
496    }
497
498    /// Do not use this: Use [`OperationVc::resolve_strongly_consistent`] instead.
499    #[cfg(feature = "non_operation_vc_strongly_consistent")]
500    pub async fn resolve_strongly_consistent(self) -> Result<Self> {
501        Ok(Self {
502            node: self.node.resolve_strongly_consistent().await?,
503            _t: PhantomData,
504        })
505    }
506}
507
508impl<T> Vc<T>
509where
510    T: VcValueTrait + ?Sized,
511{
512    /// Attempts to sidecast the given `Vc<Box<dyn T>>` to a `Vc<Box<dyn K>>`.
513    /// This operation also resolves the `Vc`.
514    ///
515    /// Returns `None` if the underlying value type does not implement `K`.
516    ///
517    /// **Note:** if the trait T is required to implement K, use
518    /// `Vc::upcast(vc).resolve()` instead. This provides stronger guarantees,
519    /// removing the need for a `Result` return type.
520    pub async fn try_resolve_sidecast<K>(vc: Self) -> Result<Option<Vc<K>>, ResolveTypeError>
521    where
522        K: VcValueTrait + ?Sized,
523    {
524        debug_assert!(
525            <K as VcValueTrait>::get_trait_type_id() != <T as VcValueTrait>::get_trait_type_id(),
526            "Attempted to cast a type {} to itself, which is pointless. Use the value directly \
527             instead.",
528            crate::registry::get_trait(<T as VcValueTrait>::get_trait_type_id()).global_name
529        );
530        let raw_vc: RawVc = vc.node;
531        let raw_vc = raw_vc
532            .resolve_trait(<K as VcValueTrait>::get_trait_type_id())
533            .await?;
534        Ok(raw_vc.map(|raw_vc| Vc {
535            node: raw_vc,
536            _t: PhantomData,
537        }))
538    }
539
540    /// Attempts to downcast the given `Vc<Box<dyn T>>` to a `Vc<K>`, where `K`
541    /// is of the form `Box<dyn L>`, and `L` is a value trait.
542    /// This operation also resolves the `Vc`.
543    ///
544    /// Returns `None` if the underlying value type is not a `K`.
545    pub async fn try_resolve_downcast<K>(vc: Self) -> Result<Option<Vc<K>>, ResolveTypeError>
546    where
547        K: UpcastStrict<T> + VcValueTrait + ?Sized,
548    {
549        Self::try_resolve_sidecast(vc).await
550    }
551
552    /// Attempts to downcast the given `Vc<Box<dyn T>>` to a `Vc<K>`, where `K`
553    /// is a value type.
554    /// This operation also resolves the `Vc`.
555    ///
556    /// Returns `None` if the underlying value type is not a `K`.
557    pub async fn try_resolve_downcast_type<K>(vc: Self) -> Result<Option<Vc<K>>, ResolveTypeError>
558    where
559        K: UpcastStrict<T> + VcValueType,
560    {
561        let raw_vc: RawVc = vc.node;
562        let raw_vc = raw_vc
563            .resolve_value(<K as VcValueType>::get_value_type_id())
564            .await?;
565        Ok(raw_vc.map(|raw_vc| Vc {
566            node: raw_vc,
567            _t: PhantomData,
568        }))
569    }
570}
571
572impl<T> From<RawVc> for Vc<T>
573where
574    T: ?Sized,
575{
576    fn from(node: RawVc) -> Self {
577        Self {
578            node,
579            _t: PhantomData,
580        }
581    }
582}
583
584impl<T> TraceRawVcs for Vc<T>
585where
586    T: ?Sized,
587{
588    fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
589        TraceRawVcs::trace_raw_vcs(&self.node, trace_context);
590    }
591}
592
593impl<T> ValueDebugFormat for Vc<T>
594where
595    T: UpcastStrict<Box<dyn ValueDebug>> + Send + Sync + ?Sized,
596{
597    fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString<'_> {
598        ValueDebugFormatString::Async(Box::pin(async move {
599            Ok({
600                let vc_value_debug = Vc::upcast::<Box<dyn ValueDebug>>(*self);
601                vc_value_debug.dbg_depth(depth).await?.to_string()
602            })
603        }))
604    }
605}
606
607macro_rules! into_future {
608    ($ty:ty) => {
609        impl<T> IntoFuture for $ty
610        where
611            T: VcValueType,
612        {
613            type Output = <ReadVcFuture<T> as Future>::Output;
614            type IntoFuture = ReadVcFuture<T>;
615            fn into_future(self) -> Self::IntoFuture {
616                self.node.into_read(T::has_serialization()).into()
617            }
618        }
619    };
620}
621
622into_future!(Vc<T>);
623into_future!(&Vc<T>);
624into_future!(&mut Vc<T>);
625
626impl<T> Vc<T>
627where
628    T: VcValueType,
629{
630    /// Do not use this: Use [`OperationVc::read_strongly_consistent`] instead.
631    #[cfg(feature = "non_operation_vc_strongly_consistent")]
632    #[must_use]
633    pub fn strongly_consistent(self) -> ReadVcFuture<T> {
634        self.node
635            .into_read(T::has_serialization())
636            .strongly_consistent()
637            .into()
638    }
639
640    /// Returns a untracked read of the value. This will not invalidate the current function when
641    /// the read value changed.
642    #[must_use]
643    pub fn untracked(self) -> ReadVcFuture<T> {
644        self.node
645            .into_read(T::has_serialization())
646            .untracked()
647            .into()
648    }
649
650    /// Read the value with the hint that this is the final read of the value. This might drop the
651    /// cell content. Future reads might need to recompute the value.
652    #[must_use]
653    pub fn final_read_hint(self) -> ReadVcFuture<T> {
654        self.node
655            .into_read(T::has_serialization())
656            .final_read_hint()
657            .into()
658    }
659}
660
661impl<T> Vc<T>
662where
663    T: VcValueType,
664    VcReadTarget<T>: Clone,
665{
666    /// Read the value and returns a owned version of it. It might clone the value.
667    pub fn owned(self) -> ReadOwnedVcFuture<T> {
668        let future: ReadVcFuture<T> = self.node.into_read(T::has_serialization()).into();
669        future.owned()
670    }
671}
672
673impl<T> Unpin for Vc<T> where T: ?Sized {}
674
675impl<T> Default for Vc<T>
676where
677    T: ValueDefault,
678{
679    fn default() -> Self {
680        T::value_default()
681    }
682}
683
684pub trait OptionVcExt<T>
685where
686    T: VcValueType,
687{
688    fn to_resolved(self) -> impl Future<Output = Result<Option<ResolvedVc<T>>>> + Send;
689}
690
691impl<T> OptionVcExt<T> for Option<Vc<T>>
692where
693    T: VcValueType,
694{
695    async fn to_resolved(self) -> Result<Option<ResolvedVc<T>>> {
696        if let Some(vc) = self {
697            Ok(Some(vc.to_resolved().await?))
698        } else {
699            Ok(None)
700        }
701    }
702}