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