Skip to content

Commit

Permalink
Create a minimum viable ResolvedVc type (vercel/turborepo#8661)
Browse files Browse the repository at this point in the history
### Description

We want a way to more strongly guarantee that a `Vc` is resolved for the sake of "local" tasks.

This introduces it in a low-risk way with zero breaking changes. Eventually, we'd want to eliminate `.resolve()` or make `.resolve()` return `ResolvedVc` instead of using a separate `.to_resolved()` method.

Some rough notes about why here: https://www.notion.so/vercel/Resolved-Vcs-Vc-Lifetimes-Local-Vcs-and-Vc-Refcounts-49d666d3f9594017b5b312b87ddc5bff

### Testing Instructions

Tested as a part of vercel/turborepo#8678
  • Loading branch information
bgw authored Jul 9, 2024
1 parent b5637dc commit 1a12966
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
6 changes: 3 additions & 3 deletions crates/turbo-tasks/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ pub use turbo_tasks_macros::{function, value, value_impl, value_trait, TaskInput
pub use value::{TransientInstance, TransientValue, Value};
pub use value_type::{TraitMethod, TraitType, ValueType};
pub use vc::{
Dynamic, TypedForInput, Upcast, ValueDefault, Vc, VcCast, VcCellNewMode, VcCellSharedMode,
VcDefaultRead, VcRead, VcTransparentRead, VcValueTrait, VcValueTraitCast, VcValueType,
VcValueTypeCast,
Dynamic, ResolvedVc, TypedForInput, Upcast, ValueDefault, Vc, VcCast, VcCellNewMode,
VcCellSharedMode, VcDefaultRead, VcRead, VcTransparentRead, VcValueTrait, VcValueTraitCast,
VcValueType, VcValueTypeCast,
};

pub use crate::rcstr::RcStr;
Expand Down
24 changes: 20 additions & 4 deletions crates/turbo-tasks/src/vc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ pub(crate) mod cast;
mod cell_mode;
pub(crate) mod default;
mod read;
pub(crate) mod resolved;
mod traits;

use std::{any::Any, marker::PhantomData, ops::Deref};
use std::{
any::Any,
hash::{Hash, Hasher},
marker::PhantomData,
ops::Deref,
};

use anyhow::Result;
use auto_hash_map::AutoSet;
Expand All @@ -16,6 +22,7 @@ pub use self::{
cell_mode::{VcCellNewMode, VcCellSharedMode},
default::ValueDefault,
read::{ReadVcFuture, VcDefaultRead, VcRead, VcTransparentRead},
resolved::ResolvedVc,
traits::{Dynamic, TypedForInput, Upcast, VcValueTrait, VcValueType},
};
use crate::{
Expand Down Expand Up @@ -205,11 +212,11 @@ where
}
}

impl<T> core::hash::Hash for Vc<T>
impl<T> Hash for Vc<T>
where
T: ?Sized + Send,
{
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
fn hash<H: Hasher>(&self, state: &mut H) {
self.node.hash(state);
}
}
Expand Down Expand Up @@ -363,13 +370,22 @@ where
///
/// This is async and will rethrow any fatal error that happened during task
/// execution.
pub async fn resolve(self) -> Result<Self> {
pub async fn resolve(self) -> Result<Vc<T>> {
Ok(Self {
node: self.node.resolve().await?,
_t: PhantomData,
})
}

/// Resolve the reference until it points to a cell directly, and wrap the
/// result in a [`ResolvedVc`], which strongly guarantees that the
/// [`Vc`] was resolved.
pub async fn to_resolved(self) -> Result<ResolvedVc<T>> {
Ok(ResolvedVc {
node: self.resolve().await?,
})
}

/// Resolve the reference until it points to a cell directly in a strongly
/// consistent way.
///
Expand Down
34 changes: 34 additions & 0 deletions crates/turbo-tasks/src/vc/resolved.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use std::{
hash::{Hash, Hasher},
ops::Deref,
};

use crate::vc::Vc;

#[derive(Copy, Clone)]
pub struct ResolvedVc<T>
where
T: ?Sized + Send,
{
pub(crate) node: Vc<T>,
}

impl<T> Deref for ResolvedVc<T>
where
T: ?Sized + Send,
{
type Target = Vc<T>;

fn deref(&self) -> &Self::Target {
&self.node
}
}

impl<T> Hash for ResolvedVc<T>
where
T: ?Sized + Send,
{
fn hash<H: Hasher>(&self, state: &mut H) {
self.node.hash(state);
}
}

0 comments on commit 1a12966

Please sign in to comment.