turbo_tasks/lib.rs
1//! A task scheduling and caching system that is focused on incremental
2//! execution.
3//!
4//! It defines 4 primitives:
5//! - **[Functions][macro@crate::function]:** Units of execution, invalidation, and reexecution.
6//! - **[Values][macro@crate::value]:** Data created, stored, and returned by functions.
7//! - **[Traits][macro@crate::value_trait]:** Traits that define a set of functions on values.
8//! - **[Collectibles][crate::TurboTasks::emit_collectible]:** Values emitted in functions that
9//! bubble up the call graph and can be collected in parent functions.
10//!
11//! It also defines some derived elements from that:
12//! - **[Tasks][book-tasks]:** An instance of a function together with its arguments.
13//! - **[Cells][book-cells]:** The locations associated with tasks where values are stored. The
14//! contents of a cell can change after the reexecution of a function.
15//! - **[`Vc`s ("Value Cells")][Vc]:** A reference to a cell or a return value of a function.
16//!
17//! A [`Vc`] can be read to get [a read-only reference][ReadRef] to the stored data, representing a
18//! snapshot of that cell at that point in time.
19//!
20//! On execution of functions, `turbo-tasks` will track which [`Vc`]s are read. Once any of these
21//! change, `turbo-tasks` will invalidate the task created from the function's execution and it will
22//! eventually be scheduled and reexecuted.
23//!
24//! Collectibles go through a similar process.
25//!
26//! [book-cells]: https://turbopack-rust-docs.vercel.sh/turbo-engine/cells.html
27//! [book-tasks]: https://turbopack-rust-docs.vercel.sh/turbo-engine/tasks.html
28
29#![feature(trivial_bounds)]
30#![feature(min_specialization)]
31#![feature(try_trait_v2)]
32#![deny(unsafe_op_in_unsafe_fn)]
33#![feature(error_generic_member_access)]
34#![feature(arbitrary_self_types)]
35#![feature(arbitrary_self_types_pointers)]
36#![feature(new_zeroed_alloc)]
37#![feature(never_type)]
38#![feature(downcast_unchecked)]
39#![feature(ptr_metadata)]
40
41pub mod backend;
42mod capture_future;
43mod collectibles;
44mod completion;
45pub mod debug;
46mod display;
47pub mod duration_span;
48mod effect;
49pub mod event;
50pub mod graph;
51mod id;
52mod id_factory;
53mod invalidation;
54mod join_iter_ext;
55mod key_value_pair;
56#[doc(hidden)]
57pub mod macro_helpers;
58mod magic_any;
59mod manager;
60mod marker_trait;
61pub mod message_queue;
62mod native_function;
63mod no_move_vec;
64mod once_map;
65mod output;
66pub mod panic_hooks;
67pub mod persisted_graph;
68pub mod primitives;
69mod raw_vc;
70mod read_options;
71mod read_ref;
72pub mod registry;
73mod scope;
74mod serialization_invalidation;
75pub mod small_duration;
76mod state;
77pub mod task;
78mod task_execution_reason;
79pub mod task_statistics;
80pub mod trace;
81mod trait_ref;
82mod triomphe_utils;
83pub mod util;
84mod value;
85mod value_type;
86mod vc;
87
88use std::hash::BuildHasherDefault;
89
90pub use anyhow::{Error, Result};
91use auto_hash_map::AutoSet;
92pub use capture_future::TurboTasksPanic;
93pub use collectibles::CollectiblesSource;
94pub use completion::{Completion, Completions};
95pub use display::ValueToString;
96pub use effect::{ApplyEffectsContext, Effects, apply_effects, effect, get_effects};
97pub use id::{
98 ExecutionId, LocalTaskId, SessionId, TRANSIENT_TASK_BIT, TaskId, TraitTypeId, ValueTypeId,
99};
100pub use invalidation::{
101 DynamicEqHash, InvalidationReason, InvalidationReasonKind, InvalidationReasonSet, Invalidator,
102 get_invalidator,
103};
104pub use join_iter_ext::{JoinIterExt, TryFlatJoinIterExt, TryJoinIterExt};
105pub use key_value_pair::KeyValuePair;
106pub use magic_any::MagicAny;
107pub use manager::{
108 CurrentCellRef, ReadConsistency, TaskPersistence, TurboTasks, TurboTasksApi,
109 TurboTasksBackendApi, TurboTasksBackendApiExt, TurboTasksCallApi, Unused, UpdateInfo,
110 dynamic_call, emit, mark_finished, mark_root, mark_session_dependent, mark_stateful,
111 prevent_gc, run_once, run_once_with_reason, spawn_blocking, spawn_thread, trait_call,
112 turbo_tasks, turbo_tasks_scope,
113};
114pub use output::OutputContent;
115pub use raw_vc::{CellId, RawVc, ReadRawVcFuture, ResolveTypeError};
116pub use read_options::ReadCellOptions;
117pub use read_ref::ReadRef;
118use rustc_hash::FxHasher;
119pub use scope::scope;
120pub use serialization_invalidation::SerializationInvalidator;
121pub use shrink_to_fit::ShrinkToFit;
122pub use state::{State, TransientState};
123pub use task::{SharedReference, TypedSharedReference, task_input::TaskInput};
124pub use task_execution_reason::TaskExecutionReason;
125pub use trait_ref::{IntoTraitRef, TraitRef};
126pub use turbo_tasks_macros::{TaskInput, function, value_impl};
127pub use value::{TransientInstance, TransientValue};
128pub use value_type::{TraitMethod, TraitType, ValueType};
129pub use vc::{
130 Dynamic, NonLocalValue, OperationValue, OperationVc, OptionVcExt, ReadVcFuture, ResolvedVc,
131 Upcast, ValueDefault, Vc, VcCast, VcCellNewMode, VcCellSharedMode, VcDefaultRead, VcRead,
132 VcTransparentRead, VcValueTrait, VcValueTraitCast, VcValueType, VcValueTypeCast,
133};
134
135pub type SliceMap<K, V> = Box<[(K, V)]>;
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/// Implements [`VcValueType`] for the given `struct` or `enum`. These value types can be used
178/// inside of a "value cell" as [`Vc<...>`][Vc].
179///
180/// A [`Vc`] represents a (potentially lazy) memoized computation. Each [`Vc`]'s value is placed
181/// into a cell associated with the current [`TaskId`]. That [`Vc`] object can be `await`ed to get
182/// [a read-only reference to the value contained in the cell][ReadRef].
183///
184/// This macro accepts multiple comma-separated arguments. For example:
185///
186/// ```
187/// # #![feature(arbitrary_self_types)]
188// # #![feature(arbitrary_self_types_pointers)]
189/// #[turbo_tasks::value(transparent, into = "shared")]
190/// struct Foo(Vec<u32>);
191/// ```
192///
193/// ## `cell = "..."`
194///
195/// Controls when a cell is invalidated upon recomputation of a task. Internally, this is performed
196/// by setting the [`VcValueType::CellMode`] associated type.
197///
198/// - **`"new"`:** Always overrides the value in the cell, invalidating all dependent tasks.
199/// - **`"shared"` *(default)*:** Compares with the existing value in the cell, before overriding it.
200/// Requires the value to implement [`Eq`].
201///
202/// Avoiding unnecessary invalidation is important to reduce downstream recomputation of tasks that
203/// depend on this cell's value.
204///
205/// Use `"new"` only if a correct implementation of [`Eq`] is not possible, would be expensive (e.g.
206/// would require comparing a large collection), or if you're implementing a low-level primitive
207/// that intentionally forces recomputation.
208///
209/// ## `eq = "..."`
210///
211/// By default, we `#[derive(PartialEq, Eq)]`. [`Eq`] is required by `cell = "shared"`. This
212/// argument allows overriding that default implementation behavior.
213///
214/// - **`"manual"`:** Prevents deriving [`Eq`] and [`PartialEq`] so you can do it manually.
215///
216/// ## `into = "..."`
217///
218/// This macro always implements a `.cell()` method on your type with the signature:
219///
220/// ```ignore
221/// /// Wraps the value in a cell.
222/// fn cell(self) -> Vc<Self>;
223/// ```
224///
225/// This argument controls the visibility of the `.cell()` method, as well as whether a
226/// [`From<T> for Vc<T>`][From] implementation is generated.
227///
228/// - **`"new"` or `"shared"`:** Exposes both `.cell()` and [`From`]/[`Into`] implementations. Both
229/// of these values (`"new"` or `"shared"`) do the same thing (for legacy reasons).
230/// - **`"none"` *(default)*:** Makes `.cell()` private and prevents implementing [`From`]/[`Into`].
231///
232/// You should use the default value of `"none"` when providing your own public constructor methods.
233///
234/// The naming of this field and it's values are due to legacy reasons.
235///
236/// ## `serialization = "..."`
237///
238/// Affects serialization via [`serde::Serialize`] and [`serde::Deserialize`]. Serialization is
239/// required for persistent caching of tasks to disk.
240///
241/// - **`"auto"` *(default)*:** Derives the serialization traits and enables serialization.
242/// - **`"custom"`:** Prevents deriving the serialization traits, but still enables serialization
243/// (you must manually implement [`serde::Serialize`] and [`serde::Deserialize`]).
244/// - **`"none"`:** Disables serialization and prevents deriving the traits.
245///
246/// ## `shared`
247///
248/// Sets both `cell = "shared"` *(already the default)* and `into = "shared"`, exposing the
249/// `.cell()` method and adding a [`From`]/[`Into`] implementation.
250///
251/// ## `transparent`
252///
253/// This attribute is only valid on single-element unit structs. When this value is set:
254///
255/// 1. The struct will use [`#[repr(transparent)]`][repr-transparent].
256/// 1. Read operations (`vc.await?`) return a [`ReadRef`] containing the inner type, rather than the
257/// outer struct. Internally, this is accomplished using [`VcTransparentRead`] for the
258/// [`VcValueType::Read`] associated type.
259/// 1. Construction of the type must be performed using [`Vc::cell(inner)`][Vc::cell], rather than
260/// using the `.cell()` method on the outer type (`outer.cell()`).
261/// 1. The [`ValueDebug`][crate::debug::ValueDebug] implementation will defer to the inner type.
262///
263/// This is commonly used to create [`VcValueType`] wrappers for foreign or generic types, such as
264/// [`Vec`] or [`Option`].
265///
266/// [repr-transparent]: https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
267///
268/// ## `local`
269///
270/// Skip the implementation of [`NonLocalValue`] for this type.
271///
272/// If not specified, we apply the [`#[derive(NonLocalValue)]`][macro@NonLocalValue] macro, which
273/// asserts that this struct has no fields containing [`Vc`] by implementing the [`NonLocalValue`]
274/// marker trait. Compile-time assertions are generated on every field, checking that they are also
275/// [`NonLocalValue`]s.
276#[rustfmt::skip]
277pub use turbo_tasks_macros::value;
278
279/// Allows this trait to be used as part of a trait object inside of a value
280/// cell, in the form of `Vc<dyn MyTrait>`.
281///
282/// ## Arguments
283///
284/// Example: `#[turbo_tasks::value_trait(no_debug, resolved)]`
285///
286/// ### 'no_debug`
287///
288/// Disables the automatic implementation of [`ValueDebug`][crate::debug::ValueDebug].
289///
290/// Example: `#[turbo_tasks::value_trait(no_debug)]`
291///
292/// ### 'resolved`
293///
294/// Adds [`NonLocalValue`] as a supertrait of this trait.
295///
296/// Example: `#[turbo_tasks::value_trait(resolved)]`
297#[rustfmt::skip]
298pub use turbo_tasks_macros::value_trait;
299
300pub type TaskIdSet = AutoSet<TaskId, BuildHasherDefault<FxHasher>, 2>;
301
302pub mod test_helpers {
303 pub use super::manager::{current_task_for_testing, with_turbo_tasks_for_testing};
304}
305
306pub fn register() {
307 include!(concat!(env!("OUT_DIR"), "/register.rs"));
308}