Skip to content

Commit

Permalink
docs(turbo-tasks): Rewrite the turbo_tasks::value documentation (#7…
Browse files Browse the repository at this point in the history
…0743)

This documentation contained broken links, broken formatting,
grammatical mistakes, misleading or outdated information, incomplete
information, and lacked context one why one might use the various
arguments.

![Screenshot 2024-10-02 at 21-40-23 value in turbo_tasks -
Rust.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/HAZVitxRNnZz8QMiPn4a/4ed70252-9996-4070-843c-df510c664444.png)
  • Loading branch information
bgw authored Oct 4, 2024
1 parent 6993467 commit 7f5c64b
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 87 deletions.
77 changes: 0 additions & 77 deletions turbopack/crates/turbo-tasks-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,83 +47,6 @@ pub fn derive_task_input(input: TokenStream) -> TokenStream {
derive::derive_task_input(input)
}

/// Creates a Vc<Value> struct for a `struct` or `enum` that represent
/// that type placed into a cell in a Task.
///
/// That Vc<Value> object can be `await`ed to get a readonly reference
/// to the value contained in the cell.
///
/// ## Arguments
///
/// Example: `#[turbo_tasks::value(into = "new", eq = "manual")]`
///
/// ### `cell`
///
/// Possible values:
///
/// - "new": Always overrides the value in the cell. Invalidating all
/// dependent tasks.
/// - "shared" (default): Compares with the existing value in the cell, before
/// overriding it. Requires Value to implement [Eq].
///
/// ### `eq`
///
/// Possible values:
///
/// - "manual": Prevents deriving [Eq] so you can do it manually.
///
/// ### `into`
///
/// When provided the Vc<Value> implement `From<Value>` to allow to convert
/// a Value to a Vc<Value> by placing it into a cell in a Task.
///
/// Possible values:
///
/// - "new": Always overrides the value in the cell. Invalidating all
/// dependent tasks.
/// - "shared": Compares with the existing value in the cell, before
/// overriding it. Requires Value to implement [Eq].
/// - "none" (default): Prevents implementing `From<Value>`.
///
/// ### `serialization`
///
/// Affects serialization via [serde::Serialize] and [serde::Deserialize].
///
/// Possible values:
///
/// - "auto" (default): Derives the serialization traits and enabled serialization.
/// - "auto_for_input": Same as "auto", but also adds the marker trait [turbo_tasks::TypedForInput].
/// - "custom": Prevents deriving the serialization traits, but still enables serialization (you
/// need to manually implement [serde::Serialize] and [serde::Deserialize]).
/// - "custom_for_input":Same as "auto", but also adds the marker trait
/// [turbo_tasks::TypedForInput].
/// - "none": Disables serialization and prevents deriving the traits.
///
/// ### `shared`
///
/// Sets both `cell = "shared"` and `into = "shared"`
///
/// No value.
///
/// Example: `#[turbo_tasks::value(shared)]`
///
/// ### `transparent`
///
/// If applied to a unit struct (e.g. `struct Wrapper(Value)`) the outer struct
/// is skipped for all operations (cell, into, reading).
///
/// No value.
///
/// Example: `#[turbo_tasks::value(transparent)]`
///
/// ### `resolved`
///
/// A shorthand syntax for
/// [`#[derive(turbo_tasks::ResolvedValue)]`][macro@turbo_tasks::ResolvedValue]
///
/// Example: `#[turbo_tasks::value(resolved)]`
///
/// TODO: add more documentation: presets, traits
#[allow_internal_unstable(min_specialization, into_future, trivial_bounds)]
#[proc_macro_error]
#[proc_macro_attribute]
Expand Down
6 changes: 3 additions & 3 deletions turbopack/crates/turbo-tasks-macros/src/value_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,9 @@ pub fn value(args: TokenStream, input: TokenStream) -> TokenStream {

let into = if let IntoMode::New | IntoMode::Shared = into_mode {
quote! {
impl Into<turbo_tasks::Vc<#ident>> for #ident {
fn into(self) -> turbo_tasks::Vc<#ident> {
self.cell()
impl ::std::convert::From<#ident> for turbo_tasks::Vc<#ident> {
fn from(value: #ident) -> Self {
value.cell()
}
}
}
Expand Down
105 changes: 104 additions & 1 deletion turbopack/crates/turbo-tasks/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub use serialization_invalidation::SerializationInvalidator;
pub use state::{State, TransientState};
pub use task::{task_input::TaskInput, SharedReference};
pub use trait_ref::{IntoTraitRef, TraitRef};
pub use turbo_tasks_macros::{function, value, value_impl, value_trait, TaskInput};
pub use turbo_tasks_macros::{function, value_impl, value_trait, TaskInput};
pub use value::{TransientInstance, TransientValue, Value};
pub use value_type::{TraitMethod, TraitType, ValueType};
pub use vc::{
Expand All @@ -118,6 +118,109 @@ pub use vc::{

pub use crate::rcstr::RcStr;

/// Implements [`VcValueType`] for the given `struct` or `enum`. These value types can be used
/// inside of a "value cell" as [`Vc<...>`][Vc].
///
/// A [`Vc`] represents a (potentially lazy) memoized computation. Each [`Vc`]'s value is placed
/// into a cell associated with the current [`TaskId`]. That [`Vc`] object can be `await`ed to get
/// [a read-only reference to the value contained in the cell][ReadRef].
///
/// This macro accepts multiple comma-separated arguments. For example:
///
/// ```
/// # #![feature(arbitrary_self_types)]
/// #[turbo_tasks::value(transparent, into = "shared")]
/// struct Foo(Vec<u32>);
/// ```
///
/// ## `cell = "..."`
///
/// Controls when a cell is invalidated upon recomputation of a task. Internally, this is performed
/// by setting the [`VcValueType::CellMode`] associated type.
///
/// - **`"new"`:** Always overrides the value in the cell, invalidating all dependent tasks.
/// - **`"shared"` *(default)*:** Compares with the existing value in the cell, before overriding it.
/// Requires the value to implement [`Eq`].
///
/// Avoiding unnecessary invalidation is important to reduce downstream recomputation of tasks that
/// depend on this cell's value.
///
/// Use `"new"` only if a correct implementation of [`Eq`] is not possible, would be expensive (e.g.
/// would require comparing a large collection), or if you're implementing a low-level primitive
/// that intentionally forces recomputation.
///
/// ## `eq = "..."`
///
/// By default, we `#[derive(PartialEq, Eq)]`. [`Eq`] is required by `cell = "shared"`. This
/// argument allows overriding that default implementation behavior.
///
/// - **`"manual"`:** Prevents deriving [`Eq`] and [`PartialEq`] so you can do it manually.
///
/// ## `into = "..."`
///
/// This macro always implements a `.cell()` method on your type with the signature:
///
/// ```ignore
/// /// Wraps the value in a cell.
/// fn cell(self) -> Vc<Self>;
/// ```
///
/// This argument controls the visibility of the `.cell()` method, as well as whether a
/// [`From<T> for Vc<T>`][From] implementation is generated.
///
/// - **`"new"` or `"shared"`:** Exposes both `.cell()` and [`From`]/[`Into`] implementations. Both
/// of these values (`"new"` or `"shared"`) do the same thing (for legacy reasons).
/// - **`"none"` *(default)*:** Makes `.cell()` private and prevents implementing [`From`]/[`Into`].
///
/// You should use the default value of `"none"` when providing your own public constructor methods.
///
/// The naming of this field and it's values are due to legacy reasons.
///
/// ## `serialization = "..."`
///
/// Affects serialization via [`serde::Serialize`] and [`serde::Deserialize`]. Serialization is
/// required for persistent caching of tasks to disk.
///
/// - **`"auto"` *(default)*:** Derives the serialization traits and enables serialization.
/// - **`"auto_for_input"`:** Same as `"auto"`, but also adds the marker trait [`TypedForInput`].
/// - **`"custom"`:** Prevents deriving the serialization traits, but still enables serialization
/// (you must manually implement [`serde::Serialize`] and [`serde::Deserialize`]).
/// - **`"custom_for_input"`:** Same as `"custom"`, but also adds the marker trait
/// [`TypedForInput`].
/// - **`"none"`:** Disables serialization and prevents deriving the traits.
///
/// ## `shared`
///
/// Sets both `cell = "shared"` *(already the default)* and `into = "shared"`, exposing the
/// `.cell()` method and adding a [`From`]/[`Into`] implementation.
///
/// ## `transparent`
///
/// This attribute is only valid on single-element unit structs. When this value is set:
///
/// 1. The struct will use [`#[repr(transparent)]`][repr-transparent].
/// 1. Read operations (`vc.await?`) return a [`ReadRef`] containing the inner type, rather than the
/// outer struct. Internally, this is accomplished using [`VcTransparentRead`] for the
/// [`VcValueType::Read`] associated type.
/// 1. Construction of the type must be performed using [`Vc::cell(inner)`][Vc::cell], rather than
/// using the `.cell()` method on the outer type (`outer.cell()`).
/// 1. The [`ValueDebug`][crate::debug::ValueDebug] implementation will defer to the inner type.
///
/// This is commonly used to create [`VcValueType`] wrappers for foreign or generic types, such as
/// [`Vec`] or [`Option`].
///
/// [repr-transparent]: https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent
///
/// ## `resolved`
///
/// Applies the [`#[derive(ResolvedValue)]`][macro@ResolvedValue] macro.
///
/// Indicates that this struct has no fields containing [`Vc`] by implementing the [`ResolvedValue`]
/// marker trait. In order to safely implement [`ResolvedValue`], this inserts compile-time
/// assertions that every field in this struct has a type that is also a [`ResolvedValue`].
#[rustfmt::skip]
pub use turbo_tasks_macros::value;

pub type TaskIdSet = AutoSet<TaskId, BuildHasherDefault<FxHasher>, 2>;

pub mod test_helpers {
Expand Down
2 changes: 1 addition & 1 deletion turbopack/crates/turbo-tasks/src/vc/resolved.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ where
///
/// This trait is marked as unsafe. You should not derive it yourself, but
/// instead you should rely on [`#[turbo_tasks::value(resolved)]`][macro@
/// turbo_tasks::value] to do it for you.
/// crate::value] to do it for you.
pub unsafe trait ResolvedValue {}

unsafe impl<T: ?Sized + Send + ResolvedValue> ResolvedValue for ResolvedVc<T> {}
Expand Down
10 changes: 5 additions & 5 deletions turbopack/crates/turbo-tasks/src/vc/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ where
{
}

/// Marker trait that a turbo_tasks::value is prepared for
/// serialization as [`Value<...>`][crate::Value] input.
/// Either use [`#[turbo_tasks::value(serialization:
/// auto_for_input)]`][macro@crate::value] or avoid [`Value<...>`][crate::Value]
/// in favor of a real [Vc][crate::Vc].
/// Marker trait that a turbo_tasks::value is prepared for serialization as
/// [`Value<...>`][crate::Value] input.
///
/// Either use [`#[turbo_tasks::value(serialization = "auto_for_input")]`][macro@crate::value] or
/// avoid [`Value<...>`][crate::Value] in favor of a real [Vc][crate::Vc].
pub trait TypedForInput: VcValueType {}

0 comments on commit 7f5c64b

Please sign in to comment.