Skip to main content

turbo_tasks/vc/
traits.rs

1use crate::{
2    NonLocalValue, ShrinkToFit, TraitTypeId, ValueTypeId, VcRead, macro_helpers::VTableRegistry,
3    vc::cell_mode::VcCellMode,
4};
5
6/// A trait implemented on all values types that can be put into a value cell ([`Vc`][crate::Vc]).
7///
8/// Custom traits for `VcValueType`s should be subtraits of [`VcValueTrait`].
9///
10/// You should not implement this trait directly, but instead use the
11/// [`#[turbo_tasks::value]`][crate::value] macro instead.
12///
13/// ## Safety
14///
15/// The implementor of this trait must ensure that the read and cell mode implementations are
16/// correct for the value type. Otherwise, it is possible to generate invalid reads, for instance by
17/// using [`VcTransparentRead`][crate::VcTransparentRead] for a value type that is not
18/// `#[repr(transparent)]`.
19pub unsafe trait VcValueType: ShrinkToFit + Sized + Send + Sync + 'static {
20    /// How to read the value.
21    type Read: VcRead<Self>;
22
23    /// How to update cells of this value type.
24    type CellMode: VcCellMode<Self>;
25
26    /// Returns the type id of the value type.
27    fn get_value_type_id() -> ValueTypeId;
28
29    fn has_serialization() -> bool;
30}
31
32/// A trait implemented on all values trait object references that can be used with a value cell
33/// ([`Vc<Box<dyn Trait>>`][crate::Vc]).
34///
35/// You should not create subtraits of this trait manually, but instead use the
36/// [`#[turbo_tasks::value_trait]`][crate::value_trait] macro. Implementations of `VcValueTrait`s
37/// should use the [`#[turbo_tasks::value_impl]`][crate::value_impl] macro.
38///
39/// [`Vc`]: crate::Vc
40///
41///
42/// ## Upcasting
43///
44/// A concrete [`Vc`] of a [`VcValueType`] can be converted to a [`Vc`] of a `VcValueTrait` with an
45/// upcast:
46///
47/// ```ignore
48/// let something_vc: Vc<ConcreteType> = ...;
49/// let trait_vc: Vc<Box<dyn MyTrait>> = Vc::upcast(something_vc);
50///
51/// // there is an equivalent API for ResolvedVc
52/// let something_resolved_vc: ResolvedVc<ConcreteType> = ...;
53/// let trait_resolved_vc: ResolvedVc<Box<dyn MyTrait>> = ResolvedVc::upcast(something_resolved_vc);
54/// ```
55///
56/// Upcast safety is enforced at compile-time with the [`Upcast`] and [`UpcastStrict`] traits.
57/// Upcasts always succeed.
58///
59///
60/// ## Downcasting
61///
62/// A [`ResolvedVc`] containing a `VcValueTrait` subtrait can be downcast to a concrete type with
63/// [`ResolvedVc::try_downcast_type`]:
64///
65/// ```ignore
66/// let trait_vc: Vc<Box<dyn MyTrait>> = ...;
67/// if let Some(something_vc) = ResolvedVc::try_downcast_type::<Something>(trait_vc) {
68///     // ...
69/// }
70/// ```
71///
72/// A supertrait can be cast to a subtrait with [`ResolvedVc::try_downcast`]:
73///
74/// ```ignore
75/// let trait_vc: Vc<Box<dyn SubTrait>> = ...;
76/// if let Some(something_vc) = ResolvedVc::try_downcast::<Box<dyn SuperTrait>>(trait_vc) {
77///     // ...
78/// }
79/// ```
80///
81/// If you have an unresolved [`Vc`] that you'd like to downcast, you should [resolve it first].
82///
83/// A compile-time check using the [`Upcast`] and [`UpcastStrict`] traits ensures that a downcast is
84/// possible (the target type or trait implements the source trait), but it may still return
85/// `None` at runtime if the concrete value does not implement the trait.
86///
87/// [`ResolvedVc`]: crate::ResolvedVc
88/// [`ResolvedVc::try_downcast_type`]: crate::ResolvedVc::try_downcast_type
89/// [`ResolvedVc::try_downcast`]: crate::ResolvedVc::try_downcast
90/// [resolve it first]: crate::Vc::to_resolved
91///
92///
93/// ## Sidecasting
94///
95/// In some cases, you may want to convert between two traits that do not have a supertrait/subtrait
96/// relationship:
97///
98/// ```ignore
99/// let trait_vc: Vc<Box<dyn MyTrait>> = ...;
100/// if let Some(something_vc) = ResolvedVc::try_sidecast::<Box<dyn UnrelatedTrait>>(trait_vc) {
101///     // ...
102/// }
103/// ```
104///
105/// If you have an unresolved [`Vc`] that you'd like to sidecast, you should [resolve it first].
106///
107/// This won't do any compile-time checks, so downcasting should be preferred if possible. It will
108/// return `None` at runtime if the cast fails.
109///
110///
111/// ## Reading
112///
113/// Trait object Vcs can be read by converting them to a [`TraitRef`], which allows non-turbo-tasks
114/// functions defined on the trait to be called.
115///
116/// ```ignore
117/// let trait_vc: Vc<Box<dyn MyTrait>> = ...;
118/// let trait_ref: TraitRef<Box<dyn MyTrait>> = trait_vc.into_trait_ref().await?;
119///
120/// trait_ref.non_turbo_tasks_function();
121/// ```
122///
123/// [`TraitRef`]: crate::TraitRef
124pub trait VcValueTrait: NonLocalValue + Send + Sync + 'static {
125    // The concrete type of the value_trait implementing VcValueTrait
126    type ValueTrait: ?Sized;
127
128    /// Returns the type id of the trait object.
129    fn get_trait_type_id() -> TraitTypeId;
130
131    /// Returns the vtable for an implementation of this trait.
132    /// Panics if ValueTypeId does not implement the trait.
133    fn get_impl_vtables() -> &'static VTableRegistry<Self::ValueTrait>;
134}
135
136/// Marker trait that indicates that a [`Vc<Self>`][crate::Vc] can be upcasted to a
137/// [`Vc<T>`][crate::Vc].
138///
139/// See [`VcValueTrait`] for example usage.
140///
141/// # Safety
142///
143/// The implementor of this trait must ensure that `Self` implements the
144/// trait `T`.
145pub unsafe trait Upcast<T>
146where
147    T: VcValueTrait + ?Sized,
148{
149}
150
151/// A specialization of [`Upcast`] that ensures that the upcast is strict meaning that `T !== Self`.
152///
153/// See [`VcValueTrait`] for example usage.
154///
155/// # Safety
156///
157/// The implementor of this trait must ensure that `Self` implements the
158/// trait `T` and that `Self` is not equal to `T`.
159pub unsafe trait UpcastStrict<T>: Upcast<T>
160where
161    T: VcValueTrait + ?Sized,
162{
163}
164
165/// Marker trait that indicates that a [`Vc<Self>`][crate::Vc] can accept all
166/// methods declared on a [`Vc<T>`][crate::Vc].
167///
168/// # Safety
169///
170/// The implementor of this trait must ensure that `Self` implements the
171/// trait `T`.
172pub unsafe trait Dynamic<T>
173where
174    T: VcValueTrait + ?Sized,
175{
176}