turbo_tasks/vc/
cell_mode.rs1use std::{any::type_name, marker::PhantomData};
2
3use super::{read::VcRead, traits::VcValueType};
4use crate::{
5 RawVc, Vc, backend::VerificationMode, keyed::Keyed, manager::find_cell_by_type,
6 task::shared_reference::TypedSharedReference,
7};
8
9type VcReadTarget<T> = <<T as VcValueType>::Read as VcRead<T>>::Target;
10
11pub trait VcCellMode<T>
16where
17 T: VcValueType,
18{
19 fn cell(value: VcReadTarget<T>) -> Vc<T>;
21
22 fn raw_cell(value: TypedSharedReference) -> RawVc;
29}
30
31pub struct VcCellNewMode<T> {
33 _phantom: PhantomData<T>,
34}
35
36impl<T> VcCellMode<T> for VcCellNewMode<T>
37where
38 T: VcValueType,
39{
40 fn cell(inner: VcReadTarget<T>) -> Vc<T> {
41 let cell = find_cell_by_type::<T>();
42 cell.update(
43 <T::Read as VcRead<T>>::target_to_value(inner),
44 VerificationMode::Skip,
45 );
46 Vc {
47 node: cell.into(),
48 _t: PhantomData,
49 }
50 }
51
52 fn raw_cell(content: TypedSharedReference) -> RawVc {
53 debug_assert_type::<T>(&content);
54 let cell = find_cell_by_type::<T>();
55 cell.update_with_shared_reference(content.reference, VerificationMode::Skip);
56 cell.into()
57 }
58}
59
60pub struct VcCellCompareMode<T> {
63 _phantom: PhantomData<T>,
64}
65
66impl<T> VcCellMode<T> for VcCellCompareMode<T>
67where
68 T: VcValueType + PartialEq,
69{
70 fn cell(inner: VcReadTarget<T>) -> Vc<T> {
71 let cell = find_cell_by_type::<T>();
72 cell.compare_and_update(<T::Read as VcRead<T>>::target_to_value(inner));
73 Vc {
74 node: cell.into(),
75 _t: PhantomData,
76 }
77 }
78
79 fn raw_cell(content: TypedSharedReference) -> RawVc {
80 debug_assert_type::<T>(&content);
81 let cell = find_cell_by_type::<T>();
82 cell.compare_and_update_with_shared_reference::<T>(content.reference);
83 cell.into()
84 }
85}
86
87pub struct VcCellKeyedCompareMode<T> {
90 _phantom: PhantomData<T>,
91}
92
93impl<T> VcCellMode<T> for VcCellKeyedCompareMode<T>
94where
95 T: VcValueType + PartialEq,
96 VcReadTarget<T>: Keyed,
97 <VcReadTarget<T> as Keyed>::Key: std::hash::Hash,
98{
99 fn cell(inner: VcReadTarget<T>) -> Vc<T> {
100 let cell = find_cell_by_type::<T>();
101 cell.keyed_compare_and_update(<T::Read as VcRead<T>>::target_to_value(inner));
102 Vc {
103 node: cell.into(),
104 _t: PhantomData,
105 }
106 }
107
108 fn raw_cell(content: TypedSharedReference) -> RawVc {
109 debug_assert_type::<T>(&content);
110 let cell = find_cell_by_type::<T>();
111 cell.keyed_compare_and_update_with_shared_reference::<T>(content.reference);
112 cell.into()
113 }
114}
115
116fn debug_assert_type<T: VcValueType>(content: &TypedSharedReference) {
117 debug_assert!(
118 (*content.reference.0).is::<T>(),
119 "SharedReference for type {} must contain data matching that type",
120 type_name::<T>(),
121 );
122}