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 read_options;
47mod read_ref;
48pub mod registry;
49pub mod scope;
50mod serialization_invalidation;
51pub mod small_duration;
52mod spawn;
53mod state;
54pub mod task;
55#[cfg(feature = "task_dirty_cause")]
56mod task_dirty_cause;
57mod task_execution_reason;
58pub mod task_statistics;
59mod tiny_vec;
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    tiny_vec::TinyVec,
121    trait_ref::TraitRef,
122    value::{TransientInstance, TransientValue},
123    value_type::{Evictability, TraitMethod, TraitType, ValueType, ValueTypePersistence},
124    vc::{
125        CellId, Dynamic, NonLocalValue, OperationValue, OperationVc, OptionVcExt, RawVc,
126        ReadRawVcFuture, ReadVcFuture, ResolveOperationVcFuture, ResolveRawVcFuture,
127        ResolveVcFuture, ResolvedVc, ToResolvedVcFuture, Upcast, UpcastStrict, ValueDefault, Vc,
128        VcCast, VcCellCompareMode, VcCellHashedCompareMode, VcCellKeyedCompareMode, VcCellNewMode,
129        VcDefaultRead, VcRead, VcTransparentRead, VcValueTrait, VcValueTraitCast, VcValueType,
130        VcValueTypeCast,
131    },
132};
133
134pub type FxIndexSet<T> = indexmap::IndexSet<T, BuildHasherDefault<FxHasher>>;
135pub type FxIndexMap<K, V> = indexmap::IndexMap<K, V, BuildHasherDefault<FxHasher>>;
136pub type FxDashMap<K, V> = dashmap::DashMap<K, V, BuildHasherDefault<FxHasher>>;
137
138// Copied from indexmap! and indexset!
139#[macro_export]
140macro_rules! fxindexmap {
141    (@single $($x:tt)*) => (());
142    (@count $($rest:expr),*) => (<[()]>::len(&[$($crate::fxindexmap!(@single $rest)),*]));
143
144    ($($key:expr => $value:expr,)+) => { $crate::fxindexmap!($($key => $value),+) };
145    ($($key:expr => $value:expr),*) => {
146        {
147            let _cap = $crate::fxindexmap!(@count $($key),*);
148            let mut _map = $crate::FxIndexMap::with_capacity_and_hasher(_cap, Default::default());
149            $(
150                _map.insert($key, $value);
151            )*
152            _map
153        }
154    };
155}
156#[macro_export]
157macro_rules! fxindexset {
158    (@single $($x:tt)*) => (());
159    (@count $($rest:expr),*) => (<[()]>::len(&[$($crate::fxindexset!(@single $rest)),*]));
160
161    ($($value:expr,)+) => { $crate::fxindexset!($($value),+) };
162    ($($value:expr),*) => {
163        {
164            let _cap = $crate::fxindexset!(@count $($value),*);
165            let mut _set = $crate::FxIndexSet::with_capacity_and_hasher(_cap, Default::default());
166            $(
167                _set.insert($value);
168            )*
169            _set
170        }
171    };
172}
173
174#[doc = include_str!("../singleton_pattern.md")]
175pub mod _singleton_pattern {}
176
177#[doc = include_str!("../function.md")]
178#[rustfmt::skip]
179pub use turbo_tasks_macros::function;
180
181/// Implements [`VcValueType`] for the given `struct` or `enum`. These value types can be used
182/// inside of a "value cell" as [`Vc<...>`][Vc].
183///
184/// A [`Vc`] represents the result of a computation. Each [`Vc`]'s value is placed into a cell
185/// associated with the current [`TaskId`]. That [`Vc`] object can be `await`ed to get [a read-only
186/// reference to the value contained in the cell][ReadRef].
187///
188/// This macro accepts multiple comma-separated arguments. For example:
189///
190/// ```
191/// # #![feature(arbitrary_self_types)]
192//  # #![feature(arbitrary_self_types_pointers)]
193/// #[turbo_tasks::value(transparent, shared)]
194/// struct Foo(Vec<u32>);
195/// ```
196///
197/// ## `cell = "..."`
198///
199/// Controls when a cell is invalidated upon recomputation of a task. Internally, this is performed
200/// by setting the [`VcValueType::CellMode`] associated type.
201///
202/// - **`"new"`:** Always overrides the value in the cell, invalidating all dependent tasks.
203/// - **`"compare"` *(default)*:** Compares with the existing value in the cell, before overriding it.
204///   Requires the value to implement [`Eq`].
205/// - **`"keyed"`:** Like `"compare"`, but uses per-key invalidation for transparent map types.
206///
207/// Avoiding unnecessary invalidation is important to reduce downstream recomputation of tasks that
208/// depend on this cell's value.
209///
210/// Use `"new"` only if a correct implementation of [`Eq`] is not possible, would be expensive (e.g.
211/// would require comparing a large collection), or if you're implementing a low-level primitive
212/// that intentionally forces recomputation.
213///
214/// ## `eq = "..."`
215///
216/// By default, we `#[derive(PartialEq, Eq)]`. [`Eq`] is required by `cell = "compare"`. This
217/// argument allows overriding that default implementation behavior.
218///
219/// - **`"manual"`:** Prevents deriving [`Eq`] and [`PartialEq`] so you can do it manually.
220///
221/// ## `serialization = "..."`
222///
223/// Affects serialization via [`bincode::Encode`] and [`bincode::Decode`]. Serialization is required
224/// for the filesystem cache of tasks.
225///
226/// - **`"auto"` *(default)*:** Derives the bincode traits and enables serialization.
227/// - **`"custom"`:** Prevents deriving the bincode traits, but still enables serialization
228///   (you must manually implement [`bincode::Encode`] and [`bincode::Decode`]).
229/// - **`"hash"`:** Like `"none"` (no bincode serialization), but instead stores a hash of the cell
230///   value so that changes can be detected even when the transient cell data has been evicted
231///   from memory or was never stored in the cache—avoiding unnecessary downstream invalidation.
232///   Only valid with `cell = "compare"`.
233///   Requires the value to implement both [`Eq`] and [`DeterministicHash`][turbo_tasks_hash::DeterministicHash].
234/// - **`"none"`:** Disables serialization and prevents deriving the traits.
235///
236/// ## `hash = "..."`
237///
238/// By default, when using `serialization = "hash"`, we `#[derive(DeterministicHash)]`. This argument allows
239/// overriding that default implementation behavior.
240///
241/// - **`"manual"`:** Prevents deriving [`DeterministicHash`][turbo_tasks_hash::DeterministicHash] so you can do it manually.
242///   Only valid with `serialization = "hash"`.
243///
244/// ## `shared`
245///
246/// This flag makes the macro-generated `.cell()` method public so everyone can use it.
247///
248/// Non-transparent types are given a `.cell()` method. That method returns a `Vc` of the type.
249///
250/// This option does not apply to wrapper types that use `transparent`. Those use the public
251/// [`Vc::cell`] function for construction.
252///
253/// ## `transparent`
254///
255/// This attribute is only valid on single-element unit structs. When this value is set:
256///
257/// 1. The struct will use [`#[repr(transparent)]`][repr-transparent].
258/// 1. Read operations (`vc.await?`) return a [`ReadRef`] containing the inner type, rather than the
259///    outer struct. Internally, this is accomplished using [`VcTransparentRead`] for the
260///    [`VcValueType::Read`] associated type.
261/// 1. Construction of the type must be performed using [`Vc::cell(inner)`][Vc::cell], rather than
262///    using the `.cell()` method on the outer type (`outer.cell()`).
263/// 1. The [`ValueDebug`][crate::debug::ValueDebug] implementation will defer to the inner type.
264///
265/// This is commonly used to create [`VcValueType`] wrappers for foreign or generic types, such as
266/// [`Vec`] or [`Option`].
267///
268/// [repr-transparent]: https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
269///
270/// ## `local`
271///
272/// Skip the implementation of [`NonLocalValue`] for this type.
273///
274/// If not specified, we apply the [`#[derive(NonLocalValue)]`][macro@NonLocalValue] macro, which
275/// asserts that this struct has no fields containing [`Vc`] by implementing the [`NonLocalValue`]
276/// marker trait. Compile-time assertions are generated on every field, checking that they are also
277/// [`NonLocalValue`]s.
278#[rustfmt::skip]
279pub use turbo_tasks_macros::value;
280
281/// Attribute macro for declaring a [`TaskInput`] type. Emits:
282///
283/// - `unsafe impl NonLocalValue for X {}` (unless `contains_unresolved_vcs` is set).
284/// - `impl TaskInput for X` with a field-walking `is_transient`. By default `is_resolved` and
285///   `resolve_input` use the trait defaults (`true` and a [`CloneReady`] future — 8 bytes, no
286///   async-fn envelope); when `contains_unresolved_vcs` is set, both are emitted as
287///   field-walking implementations as well.
288///
289/// Default form (most types):
290///
291/// ```ignore
292/// #[turbo_tasks::task_input]
293/// #[derive(Clone, Debug, Hash, PartialEq, Eq, TraceRawVcs, Encode, Decode)]
294/// pub struct MyTaskInput { ... }
295/// ```
296///
297/// Opt out of `NonLocalValue` when the type contains `Vc<T>` fields:
298///
299/// ```ignore
300/// #[turbo_tasks::task_input(contains_unresolved_vcs)]
301/// #[derive(Clone, Debug, Hash, PartialEq, Eq, TraceRawVcs, Encode, Decode)]
302/// pub struct VcCarrier { vc: Vc<...> }
303/// ```
304pub use turbo_tasks_macros::task_input;
305
306/// Allows this trait to be used as part of a trait object inside of a value cell, in the form of
307/// `Vc<Box<dyn MyTrait>>`. The annotated trait is made into a subtrait of [`VcValueTrait`].
308///
309/// ```ignore
310/// #[turbo_tasks::value_trait]
311/// pub trait MyTrait {
312///
313///     #[turbo_tasks::function]
314///     fn method(self: Vc<Self>, a: i32) -> Vc<Something>;
315///
316///     // External signature: fn method(self: Vc<Self>, a: i32) -> Vc<Something>
317///     #[turbo_tasks::function]
318///     async fn method2(&self, a: i32) -> Result<Vc<Something>> {
319///         // Default implementation
320///     }
321///
322///     // A normal trait item, not a turbo-task
323///     fn normal(&self) -> SomethingElse;
324/// }
325///
326/// #[turbo_tasks::value_trait]
327/// pub trait OtherTrait: MyTrait + ValueToString {
328///     // ...
329/// }
330///
331/// #[turbo_tasks::value_impl]
332/// impl MyTrait for MyValue {
333///     // only the external signature must match (see the docs for #[turbo_tasks::function])
334///     #[turbo_tasks::function]
335///     fn method(&self, a: i32) -> Vc<Something> {
336///         todo!()
337///     }
338///
339///     fn normal(&self) -> SomethingElse {
340///         todo!()
341///     }
342/// }
343/// ```
344///
345/// The `#[turbo_tasks::value_trait]` annotation derives [`VcValueTrait`] and registers the trait
346/// and its methods.
347///
348/// All methods annotated with [`#[turbo_tasks::function]`][function] are cached, and
349/// the external signature rewriting rules defined on that macro are applied.
350///
351/// Default implementation are supported.
352///
353/// ## Arguments
354///
355/// Example: `#[turbo_tasks::value_trait(no_debug, operation)]`
356///
357/// ### `no_debug`
358///
359/// Disables the automatic implementation of [`ValueDebug`][debug::ValueDebug].
360///
361/// Example: `#[turbo_tasks::value_trait(no_debug)]`
362///
363/// ### `Operation`
364///
365/// Adds [`OperationValue`] as a supertrait of this trait.
366///
367/// Example: `#[turbo_tasks::value_trait(operation)]`
368#[rustfmt::skip]
369pub use turbo_tasks_macros::value_trait;
370
371/// A macro used on any `impl` block for a [`VcValueType`]. This can either be an inherent
372/// implementation or a trait implementation (see [`turbo_tasks::value_trait`][value_trait] and
373/// [`VcValueTrait`]).
374///
375/// Methods should be annotated with the [`#[turbo_tasks::function]`][function] macro.
376///
377/// ```ignore
378/// #[turbo_tasks::value_impl]
379/// impl MyTrait for MyValue {
380///     #[turbo_tasks::function]
381///     fn method(&self, a: i32) -> Vc<Something> {
382///         todo!()
383///     }
384/// }
385/// ```
386#[rustfmt::skip]
387pub use turbo_tasks_macros::value_impl;
388
389/// Derives the TaskStorage struct and generates optimized storage structures.
390///
391/// This macro analyzes `field` annotations and generates:
392/// 1. A unified TaskStorage struct
393/// 2. LazyField enum for lazy_vec fields
394/// 3. Typed accessor methods on TaskStorage
395/// 4. TaskStorageAccessors trait with accessor methods
396/// 5. TaskFlags bitfield for boolean flags
397///
398/// # Field Attributes
399///
400/// All fields require two attributes:
401///
402/// ## `storage = "..."` (required)
403///
404/// Specifies how the field is stored:
405/// - `direct` - Direct field access (e.g., `Option<OutputValue>`)
406/// - `auto_set` - Uses AutoSet for small collections
407/// - `auto_map` - Uses AutoMap for key-value pairs
408/// - `counter_map` - Uses CounterMap for reference counting
409/// - `flag` - Boolean flag stored in a compact TaskFlags bitfield (field type must be `bool`)
410///
411/// ## `category = "..."` (required)
412///
413/// Specifies the data category for persistence and access:
414/// - `data` - Frequently changed, bulk I/O
415/// - `meta` - Rarely changed, small I/O
416/// - `transient` - Field is not serialized (in-memory only)
417///
418/// ## Optional Modifiers
419///
420/// - `inline` - Field is stored inline on TaskStorage (default is lazy). Only use for hot-path
421///   fields that are frequently accessed.
422/// - `default` - Use `Default::default()` semantics instead of `Option` for inline direct fields.
423/// - `filter_transient` - Filter out transient values during serialization.
424/// - Serialization methods
425#[rustfmt::skip]
426pub use turbo_tasks_macros::task_storage;
427
428pub type TaskIdSet = AutoSet<TaskId, BuildHasherDefault<FxHasher>, 2>;