Skip to content

Commit fc6bd9e

Browse files
authored
docs(turbopack): Merge task input docs from mdbook into rustdocs (#91136)
Copying content from https://turbopack-rust-docs.vercel.sh/turbo-engine/task_inputs.html Removed some AI slop and some outdated stuff (`Value` is gone, we implemented `TaskInput` on `Arc`). Added a note about serialization of reference counted types. Rendered: ![Screenshot 2026-03-09 at 21-07-44 TaskInput in turbo_tasks - Rust.png](https://app.graphite.com/user-attachments/assets/9035cabc-8781-485a-bb0c-155de8c4a8b3.png)
1 parent 0b1604a commit fc6bd9e

2 files changed

Lines changed: 74 additions & 1 deletion

File tree

turbopack/crates/turbo-tasks/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ pub use anyhow::{Error, Result};
7171
use auto_hash_map::AutoSet;
7272
use rustc_hash::FxHasher;
7373
pub use shrink_to_fit::ShrinkToFit;
74-
pub use turbo_tasks_macros::{TaskInput, turbobail, turbofmt, value_impl};
74+
pub use turbo_tasks_macros::{turbobail, turbofmt, value_impl};
7575

7676
pub use crate::{
7777
capture_future::TurboTasksPanic,
@@ -309,6 +309,10 @@ pub use turbo_tasks_macros::value_trait;
309309
#[rustfmt::skip]
310310
pub use turbo_tasks_macros::task_storage;
311311

312+
/// Refer to [the trait documentation][trait@TaskInput] for usage.
313+
#[rustfmt::skip]
314+
pub use turbo_tasks_macros::TaskInput;
315+
312316
pub type TaskIdSet = AutoSet<TaskId, BuildHasherDefault<FxHasher>, 2>;
313317

314318
pub mod test_helpers {

turbopack/crates/turbo-tasks/src/task/task_input.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,89 @@ use crate::{
3131
/// Trait to implement in order for a type to be accepted as a
3232
/// [`#[turbo_tasks::function]`][crate::function] argument.
3333
///
34+
/// ## Serialization
35+
///
36+
/// For persistent caching of a task, arguments must be serializable. All `TaskInput`s must
37+
/// implement the bincode [`Encode`] and [`Decode`] traits.
38+
///
3439
/// Transient task inputs are required to implement [`Encode`] and [`Decode`], but are allowed to
3540
/// panic at runtime. This requirement could be lifted in the future.
3641
///
3742
/// Bincode encoding must be deterministic and compatible with [`Eq`] comparisons. If two
3843
/// `TaskInput`s compare equal they must also encode to the same bytes.
44+
///
45+
/// ## Hash and Eq
46+
///
47+
/// Arguments are used as part of keys in a `HashMap`, so they must implement of [`PartialEq`],
48+
/// [`Eq`], and [`Hash`] traits.
49+
///
50+
/// ## [`Vc<T>`][Vc]
51+
///
52+
/// A [`Vc`] is a pointer to a cell. It implements `TaskInput` and serves as a "pass by reference"
53+
/// argument:
54+
///
55+
/// - **Memoization**: [`Vc`] is keyed by pointer for memoization purposes. Identical values in
56+
/// different cells are treated as distinct.
57+
/// - **Singleton Pattern**: To ensure memoization efficiency, the singleton pattern can be employed
58+
/// to guarantee that identical values yield the same `Vc`. For more info see [Singleton Pattern
59+
/// Guide][singleton].
60+
///
61+
/// [singleton]: https://turbopack-rust-docs.vercel.sh/turbo-engine/singleton.html
62+
///
63+
/// ## Deriving `TaskInput`
64+
///
65+
/// Structs or enums can be made into task inputs by deriving `TaskInput`:
66+
///
67+
/// ```rust
68+
/// #[derive(TaskInput)]
69+
/// struct MyStruct {
70+
/// // Fields go here...
71+
/// }
72+
/// ```
73+
///
74+
/// Derived `TaskInput` types **passed by value**. When called, arguments are moved into a `Box`,
75+
/// and then cloned before being passed into the function. If the task is invalidated, the
76+
/// `TaskInput` is cloned again to allow the function to be re-executed. It's recommended to ensure
77+
/// that these types are cheap to clone.
78+
///
79+
/// Reference-counted types like [`Arc`] are cheap to clone, but each reference contained in a
80+
/// `TaskInput` will be serialized independently in the persistent cache, and may consume extra disk
81+
/// space. If an [`Arc`] points to a large type, consider wrapping that type in [`Vc`], so that only
82+
/// one copy of the value will be serialized.
3983
pub trait TaskInput:
4084
Send + Sync + Clone + Debug + PartialEq + Eq + Hash + TraceRawVcs + Encode + Decode<()>
4185
{
86+
/// This method should resolve any [`Vc`]s nested inside of this object, cloning the object in
87+
/// the process. If the input is unresolved ([`TaskInput::is_resolved`]) a "local" resolution
88+
/// task is created that runs this method.
4289
fn resolve_input(&self) -> impl Future<Output = Result<Self>> + Send + '_ {
4390
async { Ok(self.clone()) }
4491
}
92+
93+
/// This should return `true` if there are any unresolved [`Vc`]s in the type.
94+
///
95+
/// Note that [`Vc`]s can sometimes be internally resolved, so you should call
96+
/// [`Vc::is_resolved`] (or rely on the derive macro for this trait) instead of returning `true`
97+
/// for any [`Vc`]. [`ResolvedVc::is_resolved`] always returns `true`.
98+
///
99+
/// If this returns `true`, a "local" resolution task calling [`TaskInput::resolve_input`] will
100+
/// be spawned before the function accepting the arguments is run.
101+
///
102+
/// If this returns `false`, the `TaskInput` will be [cloned][Clone] instead of resolved, and
103+
/// the function's task will be spawned directly without a resolution step.
45104
fn is_resolved(&self) -> bool {
46105
true
47106
}
107+
108+
/// This should return true if this object contains a [`Vc`] (or any subtype of [`Vc`]) pointing
109+
/// to a cell owned by a transient task.
110+
///
111+
/// Any function called with a transient `TaskInput` will be transient. Any [`Vc`] constructed
112+
/// in a transient task or in a top-level [`run_once`][crate::run_once] closure will be
113+
/// transient.
114+
///
115+
/// Internally, a [`Vc`] can be determined to be transient by comparing the owning task's id
116+
/// with the [`TRANSIENT_TASK_BIT`][crate::TRANSIENT_TASK_BIT] mask.
48117
fn is_transient(&self) -> bool;
49118
}
50119

0 commit comments

Comments
 (0)