Skip to main content

turbo_tasks/
lib.rs

1#![doc = include_str!("../README.md")]
2#![feature(trivial_bounds)]
3#![feature(min_specialization)]
4#![feature(try_trait_v2)]
5#![deny(unsafe_op_in_unsafe_fn)]
6#![feature(error_generic_member_access)]
7#![feature(arbitrary_self_types)]
8#![feature(arbitrary_self_types_pointers)]
9#![feature(never_type)]
10#![feature(downcast_unchecked)]
11#![feature(ptr_metadata)]
12#![feature(sync_unsafe_cell)]
13#![feature(async_fn_traits)]
14#![feature(impl_trait_in_assoc_type)]
15#![feature(const_type_name)]
16
17pub mod backend;
18mod capture_future;
19mod collectibles;
20mod completion;
21pub mod debug;
22#[doc = include_str!("../FORMATTING.md")]
23pub mod display;
24pub mod duration_span;
25mod effect;
26mod error;
27pub mod event;
28pub mod graph;
29mod id;
30mod id_factory;
31mod invalidation;
32mod join_iter_ext;
33pub mod keyed;
34#[doc(hidden)]
35pub mod macro_helpers;
36mod magic_any;
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 raw_vc;
49mod read_options;
50mod read_ref;
51pub mod registry;
52pub mod scope;
53mod serialization_invalidation;
54pub mod small_duration;
55mod spawn;
56mod state;
57pub mod task;
58mod task_execution_reason;
59pub mod task_statistics;
60pub mod trace;
61mod trait_ref;
62mod triomphe_utils;
63pub mod util;
64mod value;
65mod value_type;
66mod vc;
67
68use std::hash::BuildHasherDefault;
69
70pub use anyhow::{Error, Result};
71use auto_hash_map::AutoSet;
72use rustc_hash::FxHasher;
73pub use shrink_to_fit::ShrinkToFit;
74pub use turbo_tasks_macros::{TaskInput, function, turbobail, turbofmt, value_impl};
75
76pub use crate::{
77    capture_future::TurboTasksPanic,
78    collectibles::CollectiblesSource,
79    completion::{Completion, Completions},
80    display::{ValueToString, ValueToStringRef},
81    effect::{ApplyEffectsContext, Effects, apply_effects, effect, get_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    magic_any::MagicAny,
90    manager::{
91        CurrentCellRef, ReadCellTracking, ReadConsistency, ReadTracking, TaskPersistence,
92        TaskPriority, TurboTasks, TurboTasksApi, TurboTasksBackendApi, TurboTasksCallApi, Unused,
93        UpdateInfo, dynamic_call, emit, get_serialization_invalidator, mark_finished,
94        mark_session_dependent, mark_stateful, mark_top_level_task, prevent_gc, run, run_once,
95        run_once_with_reason, trait_call, turbo_tasks, turbo_tasks_scope, turbo_tasks_weak,
96        unmark_top_level_task_may_leak_eventually_consistent_state, with_turbo_tasks,
97    },
98    mapped_read_ref::MappedReadRef,
99    output::OutputContent,
100    raw_vc::{CellId, RawVc, ReadRawVcFuture},
101    read_options::{ReadCellOptions, ReadOutputOptions},
102    read_ref::ReadRef,
103    serialization_invalidation::SerializationInvalidator,
104    spawn::{JoinHandle, block_for_future, block_in_place, spawn, spawn_blocking, spawn_thread},
105    state::{State, TransientState},
106    task::{
107        SharedReference, TypedSharedReference,
108        task_input::{EitherTaskInput, TaskInput},
109    },
110    task_execution_reason::TaskExecutionReason,
111    trait_ref::{IntoTraitRef, TraitRef},
112    value::{TransientInstance, TransientValue},
113    value_type::{TraitMethod, TraitType, ValueType},
114    vc::{
115        Dynamic, NonLocalValue, OperationValue, OperationVc, OptionVcExt, ReadVcFuture, ResolvedVc,
116        Upcast, UpcastStrict, ValueDefault, Vc, VcCast, VcCellCompareMode, VcCellKeyedCompareMode,
117        VcCellNewMode, VcDefaultRead, VcRead, VcTransparentRead, VcValueTrait, VcValueTraitCast,
118        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/// Implements [`VcValueType`] for the given `struct` or `enum`. These value types can be used
163/// inside of a "value cell" as [`Vc<...>`][Vc].
164///
165/// A [`Vc`] represents a (potentially lazy) memoized computation. Each [`Vc`]'s value is placed
166/// into a cell associated with the current [`TaskId`]. That [`Vc`] object can be `await`ed to get
167/// [a read-only reference to the value contained in the cell][ReadRef].
168///
169/// This macro accepts multiple comma-separated arguments. For example:
170///
171/// ```
172/// # #![feature(arbitrary_self_types)]
173//  # #![feature(arbitrary_self_types_pointers)]
174/// #[turbo_tasks::value(transparent, shared)]
175/// struct Foo(Vec<u32>);
176/// ```
177///
178/// ## `cell = "..."`
179///
180/// Controls when a cell is invalidated upon recomputation of a task. Internally, this is performed
181/// by setting the [`VcValueType::CellMode`] associated type.
182///
183/// - **`"new"`:** Always overrides the value in the cell, invalidating all dependent tasks.
184/// - **`"compare"` *(default)*:** Compares with the existing value in the cell, before overriding it.
185///   Requires the value to implement [`Eq`].
186///
187/// Avoiding unnecessary invalidation is important to reduce downstream recomputation of tasks that
188/// depend on this cell's value.
189///
190/// Use `"new"` only if a correct implementation of [`Eq`] is not possible, would be expensive (e.g.
191/// would require comparing a large collection), or if you're implementing a low-level primitive
192/// that intentionally forces recomputation.
193///
194/// ## `eq = "..."`
195///
196/// By default, we `#[derive(PartialEq, Eq)]`. [`Eq`] is required by `cell = "compare"`. This
197/// argument allows overriding that default implementation behavior.
198///
199/// - **`"manual"`:** Prevents deriving [`Eq`] and [`PartialEq`] so you can do it manually.
200///
201/// ## `serialization = "..."`
202///
203/// Affects serialization via [`serde::Serialize`] and [`serde::Deserialize`]. Serialization is
204/// required for filesystem cache of tasks.
205///
206/// - **`"auto"` *(default)*:** Derives the serialization traits and enables serialization.
207/// - **`"custom"`:** Prevents deriving the serialization traits, but still enables serialization
208///   (you must manually implement [`serde::Serialize`] and [`serde::Deserialize`]).
209/// - **`"none"`:** Disables serialization and prevents deriving the traits.
210///
211/// ## `shared`
212///
213/// Makes the `cell()` method public so everyone can use it.
214///
215/// ## `transparent`
216///
217/// This attribute is only valid on single-element unit structs. When this value is set:
218///
219/// 1. The struct will use [`#[repr(transparent)]`][repr-transparent].
220/// 1. Read operations (`vc.await?`) return a [`ReadRef`] containing the inner type, rather than the
221///    outer struct. Internally, this is accomplished using [`VcTransparentRead`] for the
222///    [`VcValueType::Read`] associated type.
223/// 1. Construction of the type must be performed using [`Vc::cell(inner)`][Vc::cell], rather than
224///    using the `.cell()` method on the outer type (`outer.cell()`).
225/// 1. The [`ValueDebug`][crate::debug::ValueDebug] implementation will defer to the inner type.
226///
227/// This is commonly used to create [`VcValueType`] wrappers for foreign or generic types, such as
228/// [`Vec`] or [`Option`].
229///
230/// [repr-transparent]: https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
231///
232/// ## `local`
233///
234/// Skip the implementation of [`NonLocalValue`] for this type.
235///
236/// If not specified, we apply the [`#[derive(NonLocalValue)]`][macro@NonLocalValue] macro, which
237/// asserts that this struct has no fields containing [`Vc`] by implementing the [`NonLocalValue`]
238/// marker trait. Compile-time assertions are generated on every field, checking that they are also
239/// [`NonLocalValue`]s.
240#[rustfmt::skip]
241pub use turbo_tasks_macros::value;
242
243/// Allows this trait to be used as part of a trait object inside of a value
244/// cell, in the form of `Vc<dyn MyTrait>`.
245///
246/// ## Arguments
247///
248/// Example: `#[turbo_tasks::value_trait(no_debug, resolved)]`
249///
250/// ### 'no_debug`
251///
252/// Disables the automatic implementation of [`ValueDebug`][crate::debug::ValueDebug].
253///
254/// Example: `#[turbo_tasks::value_trait(no_debug)]`
255///
256/// ### 'resolved`
257///
258/// Adds [`NonLocalValue`] as a supertrait of this trait.
259///
260/// Example: `#[turbo_tasks::value_trait(resolved)]`
261#[rustfmt::skip]
262pub use turbo_tasks_macros::value_trait;
263
264/// Derives the TaskStorage struct and generates optimized storage structures.
265///
266/// This macro analyzes `field` annotations and generates:
267/// 1. A unified TaskStorage struct
268/// 2. LazyField enum for lazy_vec fields
269/// 3. Typed accessor methods on TaskStorage
270/// 4. TaskStorageAccessors trait with accessor methods
271/// 5. TaskFlags bitfield for boolean flags
272///
273/// # Field Attributes
274///
275/// All fields require two attributes:
276///
277/// ## `storage = "..."` (required)
278///
279/// Specifies how the field is stored:
280/// - `direct` - Direct field access (e.g., `Option<OutputValue>`)
281/// - `auto_set` - Uses AutoSet for small collections
282/// - `auto_map` - Uses AutoMap for key-value pairs
283/// - `counter_map` - Uses CounterMap for reference counting
284/// - `flag` - Boolean flag stored in a compact TaskFlags bitfield (field type must be `bool`)
285///
286/// ## `category = "..."` (required)
287///
288/// Specifies the data category for persistence and access:
289/// - `data` - Frequently changed, bulk I/O
290/// - `meta` - Rarely changed, small I/O
291/// - `transient` - Field is not serialized (in-memory only)
292///
293/// ## Optional Modifiers
294///
295/// - `inline` - Field is stored inline on TaskStorage (default is lazy). Only use for hot-path
296///   fields that are frequently accessed.
297/// - `default` - Use `Default::default()` semantics instead of `Option` for inline direct fields.
298/// - `filter_transient` - Filter out transient values during serialization.
299/// - Serialization methods
300#[rustfmt::skip]
301pub use turbo_tasks_macros::task_storage;
302
303pub type TaskIdSet = AutoSet<TaskId, BuildHasherDefault<FxHasher>, 2>;
304
305pub mod test_helpers {
306    pub use super::manager::{current_task_for_testing, with_turbo_tasks_for_testing};
307}