turbo_tasks/vc/
cell_mode.rs1use std::{any::type_name, marker::PhantomData};
2
3use turbo_tasks_hash::DeterministicHash;
4
5use super::{read::VcRead, traits::VcValueType};
6use crate::{
7 RawVc, Vc, backend::VerificationMode, keyed::KeyedEq, manager::find_cell_by_type,
8 task::shared_reference::TypedSharedReference,
9};
10
11type VcReadTarget<T> = <<T as VcValueType>::Read as VcRead<T>>::Target;
12
13pub trait VcCellMode<T>
18where
19 T: VcValueType,
20{
21 fn cell(value: VcReadTarget<T>) -> Vc<T>;
23
24 fn raw_cell(value: TypedSharedReference) -> RawVc;
31}
32
33pub struct VcCellNewMode<T> {
35 _phantom: PhantomData<T>,
36}
37
38impl<T> VcCellMode<T> for VcCellNewMode<T>
39where
40 T: VcValueType,
41{
42 fn cell(inner: VcReadTarget<T>) -> Vc<T> {
43 let cell = find_cell_by_type::<T>();
44 cell.update(
45 <T::Read as VcRead<T>>::target_to_value(inner),
46 VerificationMode::Skip,
47 );
48 Vc {
49 node: cell.into(),
50 _t: PhantomData,
51 }
52 }
53
54 fn raw_cell(content: TypedSharedReference) -> RawVc {
55 debug_assert_type::<T>(&content);
56 let cell = find_cell_by_type::<T>();
57 cell.update_with_shared_reference(content.reference, VerificationMode::Skip);
58 cell.into()
59 }
60}
61
62pub struct VcCellCompareMode<T> {
65 _phantom: PhantomData<T>,
66}
67
68impl<T> VcCellMode<T> for VcCellCompareMode<T>
69where
70 T: VcValueType + PartialEq,
71{
72 fn cell(inner: VcReadTarget<T>) -> Vc<T> {
73 let cell = find_cell_by_type::<T>();
74 cell.compare_and_update(<T::Read as VcRead<T>>::target_to_value(inner));
75 Vc {
76 node: cell.into(),
77 _t: PhantomData,
78 }
79 }
80
81 fn raw_cell(content: TypedSharedReference) -> RawVc {
82 debug_assert_type::<T>(&content);
83 let cell = find_cell_by_type::<T>();
84 cell.compare_and_update_with_shared_reference::<T>(content.reference);
85 cell.into()
86 }
87}
88
89pub struct VcCellKeyedCompareMode<T> {
92 _phantom: PhantomData<T>,
93}
94
95impl<T> VcCellMode<T> for VcCellKeyedCompareMode<T>
96where
97 T: VcValueType + PartialEq,
98 VcReadTarget<T>: KeyedEq,
99 <VcReadTarget<T> as KeyedEq>::Key: std::hash::Hash,
100{
101 fn cell(inner: VcReadTarget<T>) -> Vc<T> {
102 let cell = find_cell_by_type::<T>();
103 cell.keyed_compare_and_update(<T::Read as VcRead<T>>::target_to_value(inner));
104 Vc {
105 node: cell.into(),
106 _t: PhantomData,
107 }
108 }
109
110 fn raw_cell(content: TypedSharedReference) -> RawVc {
111 debug_assert_type::<T>(&content);
112 let cell = find_cell_by_type::<T>();
113 cell.keyed_compare_and_update_with_shared_reference::<T>(content.reference);
114 cell.into()
115 }
116}
117
118fn debug_assert_type<T: VcValueType>(content: &TypedSharedReference) {
119 debug_assert!(
120 (*content.reference.0).is::<T>(),
121 "SharedReference for type {} must contain data matching that type",
122 type_name::<T>(),
123 );
124}
125
126pub struct VcCellHashedCompareMode<T> {
130 _phantom: PhantomData<T>,
131}
132
133impl<T> VcCellMode<T> for VcCellHashedCompareMode<T>
134where
135 T: VcValueType + PartialEq + DeterministicHash,
136{
137 fn cell(inner: VcReadTarget<T>) -> Vc<T> {
138 let cell = find_cell_by_type::<T>();
139 cell.hashed_compare_and_update(<T::Read as VcRead<T>>::target_to_value(inner));
140 Vc {
141 node: cell.into(),
142 _t: PhantomData,
143 }
144 }
145
146 fn raw_cell(content: TypedSharedReference) -> RawVc {
147 debug_assert_type::<T>(&content);
148 let cell = find_cell_by_type::<T>();
149 cell.hashed_compare_and_update_with_shared_reference::<T>(content.reference);
150 cell.into()
151 }
152}