@@ -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.
3983pub 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