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