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(never_type)]
37#![feature(downcast_unchecked)]
38#![feature(ptr_metadata)]
39#![feature(sync_unsafe_cell)]
40#![feature(vec_into_raw_parts)]
41#![feature(async_fn_traits)]
42
43pub mod backend;
44mod capture_future;
45mod collectibles;
46mod completion;
47pub mod debug;
48mod display;
49pub mod duration_span;
50mod effect;
51pub mod event;
52pub mod graph;
53mod id;
54mod id_factory;
55mod invalidation;
56mod join_iter_ext;
57mod key_value_pair;
58#[doc(hidden)]
59pub mod macro_helpers;
60mod magic_any;
61mod manager;
62mod marker_trait;
63pub mod message_queue;
64mod native_function;
65mod once_map;
66mod output;
67pub mod panic_hooks;
68pub mod parallel;
69pub mod persisted_graph;
70pub mod primitives;
71mod raw_vc;
72mod read_options;
73mod read_ref;
74pub mod registry;
75pub mod scope;
76mod serialization_invalidation;
77pub mod small_duration;
78mod spawn;
79mod state;
80pub mod task;
81mod task_execution_reason;
82pub mod task_statistics;
83pub mod trace;
84mod trait_ref;
85mod triomphe_utils;
86pub mod util;
87mod value;
88mod value_type;
89mod vc;
90
91use std::hash::BuildHasherDefault;
92
93pub use anyhow::{Error, Result};
94use auto_hash_map::AutoSet;
95pub use capture_future::TurboTasksPanic;
96pub use collectibles::CollectiblesSource;
97pub use completion::{Completion, Completions};
98pub use display::ValueToString;
99pub use effect::{ApplyEffectsContext, Effects, apply_effects, effect, get_effects};
100pub use id::{
101    ExecutionId, LocalTaskId, SessionId, TRANSIENT_TASK_BIT, TaskId, TraitTypeId, ValueTypeId,
102};
103pub use invalidation::{
104    InvalidationReason, InvalidationReasonKind, InvalidationReasonSet, Invalidator, get_invalidator,
105};
106pub use join_iter_ext::{JoinIterExt, TryFlatJoinIterExt, TryJoinIterExt};
107pub use key_value_pair::KeyValuePair;
108pub use magic_any::MagicAny;
109pub use manager::{
110    CurrentCellRef, ReadConsistency, ReadTracking, TaskPersistence, TurboTasks, TurboTasksApi,
111    TurboTasksBackendApi, TurboTasksCallApi, Unused, UpdateInfo, dynamic_call, emit, mark_finished,
112    mark_root, mark_session_dependent, mark_stateful, prevent_gc, run, run_once,
113    run_once_with_reason, trait_call, turbo_tasks, turbo_tasks_scope,
114};
115pub use output::OutputContent;
116pub use raw_vc::{CellId, RawVc, ReadRawVcFuture, ResolveTypeError};
117pub use read_options::{ReadCellOptions, ReadOutputOptions};
118pub use read_ref::ReadRef;
119use rustc_hash::FxHasher;
120pub use serialization_invalidation::SerializationInvalidator;
121pub use shrink_to_fit::ShrinkToFit;
122pub use spawn::{
123    JoinHandle, block_for_future, block_in_place, spawn, spawn_blocking, spawn_thread,
124};
125pub use state::{State, TransientState};
126pub use task::{SharedReference, TypedSharedReference, task_input::TaskInput};
127pub use task_execution_reason::TaskExecutionReason;
128pub use trait_ref::{IntoTraitRef, TraitRef};
129pub use turbo_tasks_macros::{TaskInput, function, value_impl};
130pub use value::{TransientInstance, TransientValue};
131pub use value_type::{TraitMethod, TraitType, ValueType};
132pub use vc::{
133    Dynamic, NonLocalValue, OperationValue, OperationVc, OptionVcExt, ReadVcFuture, ResolvedVc,
134    Upcast, UpcastStrict, ValueDefault, Vc, VcCast, VcCellCompareMode, VcCellNewMode,
135    VcDefaultRead, VcRead, VcTransparentRead, VcValueTrait, VcValueTraitCast, VcValueType,
136    VcValueTypeCast,
137};
138
139pub type SliceMap<K, V> = Box<[(K, V)]>;
140
141pub type FxIndexSet<T> = indexmap::IndexSet<T, BuildHasherDefault<FxHasher>>;
142pub type FxIndexMap<K, V> = indexmap::IndexMap<K, V, BuildHasherDefault<FxHasher>>;
143pub type FxDashMap<K, V> = dashmap::DashMap<K, V, BuildHasherDefault<FxHasher>>;
144
145// Copied from indexmap! and indexset!
146#[macro_export]
147macro_rules! fxindexmap {
148    (@single $($x:tt)*) => (());
149    (@count $($rest:expr),*) => (<[()]>::len(&[$($crate::fxindexmap!(@single $rest)),*]));
150
151    ($($key:expr => $value:expr,)+) => { $crate::fxindexmap!($($key => $value),+) };
152    ($($key:expr => $value:expr),*) => {
153        {
154            let _cap = $crate::fxindexmap!(@count $($key),*);
155            let mut _map = $crate::FxIndexMap::with_capacity_and_hasher(_cap, Default::default());
156            $(
157                _map.insert($key, $value);
158            )*
159            _map
160        }
161    };
162}
163#[macro_export]
164macro_rules! fxindexset {
165    (@single $($x:tt)*) => (());
166    (@count $($rest:expr),*) => (<[()]>::len(&[$($crate::fxindexset!(@single $rest)),*]));
167
168    ($($value:expr,)+) => { $crate::fxindexset!($($value),+) };
169    ($($value:expr),*) => {
170        {
171            let _cap = $crate::fxindexset!(@count $($value),*);
172            let mut _set = $crate::FxIndexSet::with_capacity_and_hasher(_cap, Default::default());
173            $(
174                _set.insert($value);
175            )*
176            _set
177        }
178    };
179}
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 a (potentially lazy) memoized computation. Each [`Vc`]'s value is placed
185/// into a cell associated with the current [`TaskId`]. That [`Vc`] object can be `await`ed to get
186/// [a read-only 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///
206/// Avoiding unnecessary invalidation is important to reduce downstream recomputation of tasks that
207/// depend on this cell's value.
208///
209/// Use `"new"` only if a correct implementation of [`Eq`] is not possible, would be expensive (e.g.
210/// would require comparing a large collection), or if you're implementing a low-level primitive
211/// that intentionally forces recomputation.
212///
213/// ## `eq = "..."`
214///
215/// By default, we `#[derive(PartialEq, Eq)]`. [`Eq`] is required by `cell = "compare"`. This
216/// argument allows overriding that default implementation behavior.
217///
218/// - **`"manual"`:** Prevents deriving [`Eq`] and [`PartialEq`] so you can do it manually.
219///
220/// ## `serialization = "..."`
221///
222/// Affects serialization via [`serde::Serialize`] and [`serde::Deserialize`]. Serialization is
223/// required for filesystem cache of tasks.
224///
225/// - **`"auto"` *(default)*:** Derives the serialization traits and enables serialization.
226/// - **`"custom"`:** Prevents deriving the serialization traits, but still enables serialization
227///   (you must manually implement [`serde::Serialize`] and [`serde::Deserialize`]).
228/// - **`"none"`:** Disables serialization and prevents deriving the traits.
229///
230/// ## `shared`
231///
232/// Makes the `cell()` method public so everyone can use it.
233///
234/// ## `transparent`
235///
236/// This attribute is only valid on single-element unit structs. When this value is set:
237///
238/// 1. The struct will use [`#[repr(transparent)]`][repr-transparent].
239/// 1. Read operations (`vc.await?`) return a [`ReadRef`] containing the inner type, rather than the
240///    outer struct. Internally, this is accomplished using [`VcTransparentRead`] for the
241///    [`VcValueType::Read`] associated type.
242/// 1. Construction of the type must be performed using [`Vc::cell(inner)`][Vc::cell], rather than
243///    using the `.cell()` method on the outer type (`outer.cell()`).
244/// 1. The [`ValueDebug`][crate::debug::ValueDebug] implementation will defer to the inner type.
245///
246/// This is commonly used to create [`VcValueType`] wrappers for foreign or generic types, such as
247/// [`Vec`] or [`Option`].
248///
249/// [repr-transparent]: https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
250///
251/// ## `local`
252///
253/// Skip the implementation of [`NonLocalValue`] for this type.
254///
255/// If not specified, we apply the [`#[derive(NonLocalValue)]`][macro@NonLocalValue] macro, which
256/// asserts that this struct has no fields containing [`Vc`] by implementing the [`NonLocalValue`]
257/// marker trait. Compile-time assertions are generated on every field, checking that they are also
258/// [`NonLocalValue`]s.
259#[rustfmt::skip]
260pub use turbo_tasks_macros::value;
261
262/// Allows this trait to be used as part of a trait object inside of a value
263/// cell, in the form of `Vc<dyn MyTrait>`.
264///
265/// ## Arguments
266///
267/// Example: `#[turbo_tasks::value_trait(no_debug, resolved)]`
268///
269/// ### 'no_debug`
270///
271/// Disables the automatic implementation of [`ValueDebug`][crate::debug::ValueDebug].
272///
273/// Example: `#[turbo_tasks::value_trait(no_debug)]`
274///
275/// ### 'resolved`
276///
277/// Adds [`NonLocalValue`] as a supertrait of this trait.
278///
279/// Example: `#[turbo_tasks::value_trait(resolved)]`
280#[rustfmt::skip]
281pub use turbo_tasks_macros::value_trait;
282
283pub type TaskIdSet = AutoSet<TaskId, BuildHasherDefault<FxHasher>, 2>;
284
285pub mod test_helpers {
286    pub use super::manager::{current_task_for_testing, with_turbo_tasks_for_testing};
287}