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