Skip to main content

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