turbo_tasks/lib.rs
1#![doc = include_str!("../README.md")]
2#![feature(trivial_bounds)]
3#![feature(min_specialization)]
4#![deny(unsafe_op_in_unsafe_fn)]
5#![feature(error_generic_member_access)]
6#![feature(arbitrary_self_types)]
7#![feature(arbitrary_self_types_pointers)]
8#![feature(ptr_metadata)]
9#![feature(sync_unsafe_cell)]
10#![feature(async_fn_traits)]
11#![feature(impl_trait_in_assoc_type)]
12#![feature(const_type_name)]
13
14pub mod backend;
15mod capture_future;
16mod collectibles;
17mod completion;
18pub mod debug;
19#[doc = include_str!("../FORMATTING.md")]
20pub mod display;
21pub mod duration_span;
22mod dyn_task_inputs;
23mod effect;
24mod error;
25pub mod event;
26pub mod graph;
27mod id;
28mod id_factory;
29mod invalidation;
30mod join_iter_ext;
31pub mod keyed;
32mod local_task_tracker;
33#[doc(hidden)]
34pub mod macro_helpers;
35mod manager;
36pub mod mapped_read_ref;
37mod marker_trait;
38pub mod message_queue;
39mod native_function;
40mod once_map;
41mod output;
42pub mod panic_hooks;
43pub mod parallel;
44pub mod primitives;
45mod priority_runner;
46mod raw_vc;
47mod read_options;
48mod read_ref;
49pub mod registry;
50pub mod scope;
51mod serialization_invalidation;
52pub mod small_duration;
53mod spawn;
54mod state;
55pub mod task;
56#[cfg(feature = "task_dirty_cause")]
57mod task_dirty_cause;
58mod task_execution_reason;
59pub mod task_statistics;
60mod tiny_vec;
61pub mod trace;
62mod trait_ref;
63mod triomphe_utils;
64pub mod util;
65mod value;
66mod value_type;
67mod vc;
68
69use std::hash::BuildHasherDefault;
70
71pub use anyhow::{Error, Result};
72use auto_hash_map::AutoSet;
73use rustc_hash::FxHasher;
74pub use shrink_to_fit::ShrinkToFit;
75pub use turbo_tasks_macros::{DeterministicHash, turbobail, turbofmt};
76
77#[cfg(feature = "task_dirty_cause")]
78pub use crate::task_dirty_cause::TaskDirtyCause;
79pub use crate::{
80 capture_future::TurboTasksPanic,
81 collectibles::CollectiblesSource,
82 completion::{Completion, Completions},
83 display::{ValueToString, ValueToStringRef},
84 dyn_task_inputs::{
85 DynTaskInputs, OwnedStackDynTaskInputs, StackDynTaskInputs, StackDynTaskInputsSlot,
86 },
87 effect::{Effect, EffectError, EffectStateStorage, Effects, emit_effect, take_effects},
88 error::PrettyPrintError,
89 id::{
90 ExecutionId, FunctionId, LocalTaskId, TRANSIENT_TASK_BIT, TaskId, TraitTypeId, ValueTypeId,
91 },
92 invalidation::{
93 InvalidationReason, InvalidationReasonKind, InvalidationReasonSet, Invalidator,
94 get_invalidator,
95 },
96 join_iter_ext::{JoinIterExt, TryFlatJoinIterExt, TryJoinIterExt},
97 manager::{
98 CurrentCellRef, ReadCellTracking, ReadConsistency, ReadTracking, TaskPersistence,
99 TaskPriority, TurboTasks, TurboTasksApi, TurboTasksBackendApi, TurboTasksCallApi, Unused,
100 UpdateInfo, dynamic_call, emit, get_serialization_invalidator, mark_finished,
101 mark_stateful, mark_top_level_task, prevent_gc, run, run_once, run_once_with_reason,
102 trait_call, turbo_tasks, turbo_tasks_scope, turbo_tasks_weak,
103 unmark_top_level_task_may_leak_eventually_consistent_state, with_turbo_tasks,
104 },
105 mapped_read_ref::MappedReadRef,
106 output::OutputContent,
107 raw_vc::{CellId, RawVc, ReadRawVcFuture, ResolveRawVcFuture},
108 read_options::{ReadCellOptions, ReadOutputOptions},
109 read_ref::ReadRef,
110 serialization_invalidation::SerializationInvalidator,
111 spawn::{JoinHandle, block_for_future, block_in_place, spawn, spawn_blocking, spawn_thread},
112 state::{State, parking_lot_mutex_bincode},
113 task::{
114 SharedReference, TypedSharedReference,
115 task_input::{EitherTaskInput, TaskInput},
116 },
117 task_execution_reason::TaskExecutionReason,
118 tiny_vec::TinyVec,
119 trait_ref::TraitRef,
120 value::{TransientInstance, TransientValue},
121 value_type::{Evictability, TraitMethod, TraitType, ValueType, ValueTypePersistence},
122 vc::{
123 Dynamic, NonLocalValue, OperationValue, OperationVc, OptionVcExt, ReadVcFuture,
124 ResolveOperationVcFuture, ResolveVcFuture, ResolvedVc, ToResolvedVcFuture, Upcast,
125 UpcastStrict, ValueDefault, Vc, VcCast, VcCellCompareMode, VcCellHashedCompareMode,
126 VcCellKeyedCompareMode, VcCellNewMode, VcDefaultRead, VcRead, VcTransparentRead,
127 VcValueTrait, VcValueTraitCast, VcValueType, VcValueTypeCast,
128 },
129};
130
131pub type FxIndexSet<T> = indexmap::IndexSet<T, BuildHasherDefault<FxHasher>>;
132pub type FxIndexMap<K, V> = indexmap::IndexMap<K, V, BuildHasherDefault<FxHasher>>;
133pub type FxDashMap<K, V> = dashmap::DashMap<K, V, BuildHasherDefault<FxHasher>>;
134
135// Copied from indexmap! and indexset!
136#[macro_export]
137macro_rules! fxindexmap {
138 (@single $($x:tt)*) => (());
139 (@count $($rest:expr),*) => (<[()]>::len(&[$($crate::fxindexmap!(@single $rest)),*]));
140
141 ($($key:expr => $value:expr,)+) => { $crate::fxindexmap!($($key => $value),+) };
142 ($($key:expr => $value:expr),*) => {
143 {
144 let _cap = $crate::fxindexmap!(@count $($key),*);
145 let mut _map = $crate::FxIndexMap::with_capacity_and_hasher(_cap, Default::default());
146 $(
147 _map.insert($key, $value);
148 )*
149 _map
150 }
151 };
152}
153#[macro_export]
154macro_rules! fxindexset {
155 (@single $($x:tt)*) => (());
156 (@count $($rest:expr),*) => (<[()]>::len(&[$($crate::fxindexset!(@single $rest)),*]));
157
158 ($($value:expr,)+) => { $crate::fxindexset!($($value),+) };
159 ($($value:expr),*) => {
160 {
161 let _cap = $crate::fxindexset!(@count $($value),*);
162 let mut _set = $crate::FxIndexSet::with_capacity_and_hasher(_cap, Default::default());
163 $(
164 _set.insert($value);
165 )*
166 _set
167 }
168 };
169}
170
171#[doc = include_str!("../singleton_pattern.md")]
172pub mod _singleton_pattern {}
173
174#[doc = include_str!("../function.md")]
175#[rustfmt::skip]
176pub use turbo_tasks_macros::function;
177
178/// Implements [`VcValueType`] for the given `struct` or `enum`. These value types can be used
179/// inside of a "value cell" as [`Vc<...>`][Vc].
180///
181/// A [`Vc`] represents the result of a computation. Each [`Vc`]'s value is placed into a cell
182/// associated with the current [`TaskId`]. That [`Vc`] object can be `await`ed to get [a read-only
183/// reference to the value contained in the cell][ReadRef].
184///
185/// This macro accepts multiple comma-separated arguments. For example:
186///
187/// ```
188/// # #![feature(arbitrary_self_types)]
189// # #![feature(arbitrary_self_types_pointers)]
190/// #[turbo_tasks::value(transparent, shared)]
191/// struct Foo(Vec<u32>);
192/// ```
193///
194/// ## `cell = "..."`
195///
196/// Controls when a cell is invalidated upon recomputation of a task. Internally, this is performed
197/// by setting the [`VcValueType::CellMode`] associated type.
198///
199/// - **`"new"`:** Always overrides the value in the cell, invalidating all dependent tasks.
200/// - **`"compare"` *(default)*:** Compares with the existing value in the cell, before overriding it.
201/// Requires the value to implement [`Eq`].
202/// - **`"keyed"`:** Like `"compare"`, but uses per-key invalidation for transparent map types.
203///
204/// Avoiding unnecessary invalidation is important to reduce downstream recomputation of tasks that
205/// depend on this cell's value.
206///
207/// Use `"new"` only if a correct implementation of [`Eq`] is not possible, would be expensive (e.g.
208/// would require comparing a large collection), or if you're implementing a low-level primitive
209/// that intentionally forces recomputation.
210///
211/// ## `eq = "..."`
212///
213/// By default, we `#[derive(PartialEq, Eq)]`. [`Eq`] is required by `cell = "compare"`. This
214/// argument allows overriding that default implementation behavior.
215///
216/// - **`"manual"`:** Prevents deriving [`Eq`] and [`PartialEq`] so you can do it manually.
217///
218/// ## `serialization = "..."`
219///
220/// Affects serialization via [`bincode::Encode`] and [`bincode::Decode`]. Serialization is required
221/// for the filesystem cache of tasks.
222///
223/// - **`"auto"` *(default)*:** Derives the bincode traits and enables serialization.
224/// - **`"custom"`:** Prevents deriving the bincode traits, but still enables serialization
225/// (you must manually implement [`bincode::Encode`] and [`bincode::Decode`]).
226/// - **`"hash"`:** Like `"none"` (no bincode serialization), but instead stores a hash of the cell
227/// value so that changes can be detected even when the transient cell data has been evicted
228/// from memory or was never stored in the cache—avoiding unnecessary downstream invalidation.
229/// Only valid with `cell = "compare"`.
230/// Requires the value to implement both [`Eq`] and [`DeterministicHash`][turbo_tasks_hash::DeterministicHash].
231/// - **`"none"`:** Disables serialization and prevents deriving the traits.
232///
233/// ## `hash = "..."`
234///
235/// By default, when using `serialization = "hash"`, we `#[derive(DeterministicHash)]`. This argument allows
236/// overriding that default implementation behavior.
237///
238/// - **`"manual"`:** Prevents deriving [`DeterministicHash`][turbo_tasks_hash::DeterministicHash] so you can do it manually.
239/// Only valid with `serialization = "hash"`.
240///
241/// ## `shared`
242///
243/// This flag makes the macro-generated `.cell()` method public so everyone can use it.
244///
245/// Non-transparent types are given a `.cell()` method. That method returns a `Vc` of the type.
246///
247/// This option does not apply to wrapper types that use `transparent`. Those use the public
248/// [`Vc::cell`] function for construction.
249///
250/// ## `transparent`
251///
252/// This attribute is only valid on single-element unit structs. When this value is set:
253///
254/// 1. The struct will use [`#[repr(transparent)]`][repr-transparent].
255/// 1. Read operations (`vc.await?`) return a [`ReadRef`] containing the inner type, rather than the
256/// outer struct. Internally, this is accomplished using [`VcTransparentRead`] for the
257/// [`VcValueType::Read`] associated type.
258/// 1. Construction of the type must be performed using [`Vc::cell(inner)`][Vc::cell], rather than
259/// using the `.cell()` method on the outer type (`outer.cell()`).
260/// 1. The [`ValueDebug`][crate::debug::ValueDebug] implementation will defer to the inner type.
261///
262/// This is commonly used to create [`VcValueType`] wrappers for foreign or generic types, such as
263/// [`Vec`] or [`Option`].
264///
265/// [repr-transparent]: https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
266///
267/// ## `local`
268///
269/// Skip the implementation of [`NonLocalValue`] for this type.
270///
271/// If not specified, we apply the [`#[derive(NonLocalValue)]`][macro@NonLocalValue] macro, which
272/// asserts that this struct has no fields containing [`Vc`] by implementing the [`NonLocalValue`]
273/// marker trait. Compile-time assertions are generated on every field, checking that they are also
274/// [`NonLocalValue`]s.
275#[rustfmt::skip]
276pub use turbo_tasks_macros::value;
277
278/// Allows this trait to be used as part of a trait object inside of a value cell, in the form of
279/// `Vc<Box<dyn MyTrait>>`. The annotated trait is made into a subtrait of [`VcValueTrait`].
280///
281/// ```ignore
282/// #[turbo_tasks::value_trait]
283/// pub trait MyTrait {
284///
285/// #[turbo_tasks::function]
286/// fn method(self: Vc<Self>, a: i32) -> Vc<Something>;
287///
288/// // External signature: fn method(self: Vc<Self>, a: i32) -> Vc<Something>
289/// #[turbo_tasks::function]
290/// async fn method2(&self, a: i32) -> Result<Vc<Something>> {
291/// // Default implementation
292/// }
293///
294/// // A normal trait item, not a turbo-task
295/// fn normal(&self) -> SomethingElse;
296/// }
297///
298/// #[turbo_tasks::value_trait]
299/// pub trait OtherTrait: MyTrait + ValueToString {
300/// // ...
301/// }
302///
303/// #[turbo_tasks::value_impl]
304/// impl MyTrait for MyValue {
305/// // only the external signature must match (see the docs for #[turbo_tasks::function])
306/// #[turbo_tasks::function]
307/// fn method(&self, a: i32) -> Vc<Something> {
308/// todo!()
309/// }
310///
311/// fn normal(&self) -> SomethingElse {
312/// todo!()
313/// }
314/// }
315/// ```
316///
317/// The `#[turbo_tasks::value_trait]` annotation derives [`VcValueTrait`] and registers the trait
318/// and its methods.
319///
320/// All methods annotated with [`#[turbo_tasks::function]`][function] are cached, and
321/// the external signature rewriting rules defined on that macro are applied.
322///
323/// Default implementation are supported.
324///
325/// ## Arguments
326///
327/// Example: `#[turbo_tasks::value_trait(no_debug, operation)]`
328///
329/// ### `no_debug`
330///
331/// Disables the automatic implementation of [`ValueDebug`][debug::ValueDebug].
332///
333/// Example: `#[turbo_tasks::value_trait(no_debug)]`
334///
335/// ### `Operation`
336///
337/// Adds [`OperationValue`] as a supertrait of this trait.
338///
339/// Example: `#[turbo_tasks::value_trait(operation)]`
340#[rustfmt::skip]
341pub use turbo_tasks_macros::value_trait;
342
343/// A macro used on any `impl` block for a [`VcValueType`]. This can either be an inherent
344/// implementation or a trait implementation (see [`turbo_tasks::value_trait`][value_trait] and
345/// [`VcValueTrait`]).
346///
347/// Methods should be annotated with the [`#[turbo_tasks::function]`][function] macro.
348///
349/// ```ignore
350/// #[turbo_tasks::value_impl]
351/// impl MyTrait for MyValue {
352/// #[turbo_tasks::function]
353/// fn method(&self, a: i32) -> Vc<Something> {
354/// todo!()
355/// }
356/// }
357/// ```
358#[rustfmt::skip]
359pub use turbo_tasks_macros::value_impl;
360
361/// Derives the TaskStorage struct and generates optimized storage structures.
362///
363/// This macro analyzes `field` annotations and generates:
364/// 1. A unified TaskStorage struct
365/// 2. LazyField enum for lazy_vec fields
366/// 3. Typed accessor methods on TaskStorage
367/// 4. TaskStorageAccessors trait with accessor methods
368/// 5. TaskFlags bitfield for boolean flags
369///
370/// # Field Attributes
371///
372/// All fields require two attributes:
373///
374/// ## `storage = "..."` (required)
375///
376/// Specifies how the field is stored:
377/// - `direct` - Direct field access (e.g., `Option<OutputValue>`)
378/// - `auto_set` - Uses AutoSet for small collections
379/// - `auto_map` - Uses AutoMap for key-value pairs
380/// - `counter_map` - Uses CounterMap for reference counting
381/// - `flag` - Boolean flag stored in a compact TaskFlags bitfield (field type must be `bool`)
382///
383/// ## `category = "..."` (required)
384///
385/// Specifies the data category for persistence and access:
386/// - `data` - Frequently changed, bulk I/O
387/// - `meta` - Rarely changed, small I/O
388/// - `transient` - Field is not serialized (in-memory only)
389///
390/// ## Optional Modifiers
391///
392/// - `inline` - Field is stored inline on TaskStorage (default is lazy). Only use for hot-path
393/// fields that are frequently accessed.
394/// - `default` - Use `Default::default()` semantics instead of `Option` for inline direct fields.
395/// - `filter_transient` - Filter out transient values during serialization.
396/// - Serialization methods
397#[rustfmt::skip]
398pub use turbo_tasks_macros::task_storage;
399
400/// Refer to [the trait documentation][trait@TaskInput] for usage.
401#[rustfmt::skip]
402pub use turbo_tasks_macros::TaskInput;
403
404pub type TaskIdSet = AutoSet<TaskId, BuildHasherDefault<FxHasher>, 2>;