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