Skip to content

Commit

Permalink
Add Send bound to T in Vc<T> to make type error less cryptic (v…
Browse files Browse the repository at this point in the history
…ercel/turborepo#5871)

### Description

Currently, the diagnostics for `T` in `Vc<T>` not implementing `Send` is
too cryptic.

### Testing Instructions

<!--
  Give a quick description of steps to test your changes.
-->


Closes WEB-1498
  • Loading branch information
kdy1 committed Sep 5, 2023
1 parent 91d2dd3 commit 6fb9556
Show file tree
Hide file tree
Showing 22 changed files with 117 additions and 62 deletions.
10 changes: 9 additions & 1 deletion crates/turbo-tasks-macros/src/generic_type_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use turbo_tasks_macros_shared::{get_type_ident, GenericTypeInput};
use crate::value_macro::value_type_and_register;

pub fn generic_type(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as GenericTypeInput);
let mut input = parse_macro_input!(input as GenericTypeInput);

for param in &input.generics.params {
match param {
Expand All @@ -33,6 +33,14 @@ pub fn generic_type(input: TokenStream) -> TokenStream {
}
}

// Add Send bound to input generics.

for param in &mut input.generics.params {
if let GenericParam::Type(param) = param {
param.bounds.push(syn::parse_quote! { std::marker::Send });
}
}

let (impl_generics, _, where_clause) = input.generics.split_for_impl();

let repr = replace_generics_with_unit(input.generics.params.iter(), &input.ty);
Expand Down
2 changes: 1 addition & 1 deletion crates/turbo-tasks-macros/src/value_impl_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ pub fn value_impl(args: TokenStream, input: TokenStream) -> TokenStream {
#[doc(hidden)]
#[allow(non_camel_case_types)]
// #[turbo_tasks::async_trait]
trait #inline_extension_trait_ident {
trait #inline_extension_trait_ident: std::marker::Send {
#[allow(declare_interior_mutable_const)]
#[doc(hidden)]
const #native_function_ident: #native_function_ty;
Expand Down
4 changes: 2 additions & 2 deletions crates/turbo-tasks-macros/src/value_trait_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ pub fn value_trait(args: TokenStream, input: TokenStream) -> TokenStream {
#[doc(hidden)]
#[allow(non_camel_case_types)]
// #[turbo_tasks::async_trait]
trait #inline_extension_trait_ident {
trait #inline_extension_trait_ident: std::marker::Send {
#[allow(declare_interior_mutable_const)]
const #native_function_ident: #native_function_ty;
#[allow(declare_interior_mutable_const)]
Expand Down Expand Up @@ -197,7 +197,7 @@ pub fn value_trait(args: TokenStream, input: TokenStream) -> TokenStream {
let expanded = quote! {
#[must_use]
#(#attrs)*
#vis #trait_token #trait_ident: #(#supertraits)+*
#vis #trait_token #trait_ident: std::marker::Send + #(#supertraits)+*
{
#(#items)*
}
Expand Down
18 changes: 15 additions & 3 deletions crates/turbo-tasks/src/generics/index_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ async fn index_map_is_empty(index_map: Vc<IndexMap<Vc<()>, Vc<()>>>) -> Result<V
Ok(Vc::cell(index_map.is_empty()))
}

impl<K, V> Vc<IndexMap<Vc<K>, Vc<V>>> {
impl<K, V> Vc<IndexMap<Vc<K>, Vc<V>>>
where
K: Send,
V: Send,
{
/// See [`IndexMap::len`].
pub fn len(self) -> Vc<usize> {
index_map_len(Self::to_repr(self))
Expand All @@ -40,7 +44,11 @@ fn index_map_default() -> Vc<IndexMap<Vc<()>, Vc<()>>> {
Vc::cell(Default::default())
}

impl<K, V> ValueDefault for IndexMap<Vc<K>, Vc<V>> {
impl<K, V> ValueDefault for IndexMap<Vc<K>, Vc<V>>
where
K: Send,
V: Send,
{
fn value_default() -> Vc<Self> {
// Safety: `index_map_default` creates an empty map, which is a valid
// representation of any index set of `Vc`.
Expand All @@ -60,7 +68,11 @@ async fn index_map_dbg_depth(
.await
}

impl<K, V> ValueDebug for IndexMap<Vc<K>, Vc<V>> {
impl<K, V> ValueDebug for IndexMap<Vc<K>, Vc<V>>
where
K: Send,
V: Send,
{
fn dbg(self: Vc<Self>) -> Vc<ValueDebugString> {
index_map_dbg_depth(Vc::<Self>::to_repr(self), usize::MAX)
}
Expand Down
15 changes: 12 additions & 3 deletions crates/turbo-tasks/src/generics/index_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ async fn index_set_is_empty(index_set: Vc<IndexSet<Vc<()>>>) -> Result<Vc<bool>>
Ok(Vc::cell(index_set.is_empty()))
}

impl<T> Vc<IndexSet<Vc<T>>> {
impl<T> Vc<IndexSet<Vc<T>>>
where
T: Send,
{
/// See [`IndexSet::len`].
pub fn len(self) -> Vc<usize> {
index_set_len(Self::to_repr(self))
Expand All @@ -40,7 +43,10 @@ fn index_set_default() -> Vc<IndexSet<Vc<()>>> {
Vc::cell(Default::default())
}

impl<T> ValueDefault for IndexSet<Vc<T>> {
impl<T> ValueDefault for IndexSet<Vc<T>>
where
T: Send,
{
fn value_default() -> Vc<Self> {
// Safety: `index_set_default` creates an empty set, which is a valid
// representation of any index set of `Vc`.
Expand All @@ -60,7 +66,10 @@ async fn index_set_dbg_depth(
.await
}

impl<T> ValueDebug for IndexSet<Vc<T>> {
impl<T> ValueDebug for IndexSet<Vc<T>>
where
T: Send,
{
fn dbg(self: Vc<Self>) -> Vc<ValueDebugString> {
index_set_dbg_depth(Vc::<Self>::to_repr(self), usize::MAX)
}
Expand Down
15 changes: 12 additions & 3 deletions crates/turbo-tasks/src/generics/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ async fn option_is_some(option: Vc<Option<Vc<()>>>) -> Result<Vc<bool>> {
Ok(Vc::cell(option.is_some()))
}

impl<T> Vc<Option<Vc<T>>> {
impl<T> Vc<Option<Vc<T>>>
where
T: Send,
{
/// See [`Option::is_none`].
pub fn is_none(self) -> Vc<bool> {
option_is_none(Self::to_repr(self))
Expand All @@ -39,7 +42,10 @@ fn option_default() -> Vc<Option<Vc<()>>> {
Vc::cell(Default::default())
}

impl<T> ValueDefault for Option<Vc<T>> {
impl<T> ValueDefault for Option<Vc<T>>
where
T: Send,
{
fn value_default() -> Vc<Self> {
// Safety: `option_default` creates a None variant, which is a valid
// representation of any option of `Vc`.
Expand All @@ -59,7 +65,10 @@ async fn option_dbg_depth(
.await
}

impl<T> ValueDebug for Option<Vc<T>> {
impl<T> ValueDebug for Option<Vc<T>>
where
T: Send,
{
fn dbg(self: Vc<Self>) -> Vc<ValueDebugString> {
option_dbg_depth(Vc::<Self>::to_repr(self), usize::MAX)
}
Expand Down
15 changes: 12 additions & 3 deletions crates/turbo-tasks/src/generics/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ async fn vec_is_empty(vec: Vc<Vec<Vc<()>>>) -> Result<Vc<bool>> {
Ok(Vc::cell(vec.is_empty()))
}

impl<T> Vc<Vec<Vc<T>>> {
impl<T> Vc<Vec<Vc<T>>>
where
T: Send,
{
/// See [`Vec::len`].
pub fn len(self) -> Vc<usize> {
vec_len(Self::to_repr(self))
Expand All @@ -39,7 +42,10 @@ fn vec_default() -> Vc<Vec<Vc<()>>> {
Vc::cell(Default::default())
}

impl<T> ValueDefault for Vec<Vc<T>> {
impl<T> ValueDefault for Vec<Vc<T>>
where
T: Send,
{
fn value_default() -> Vc<Self> {
// Safety: `vec_default` creates an empty vector, which is a valid
// representation of any vector of `Vc`s.
Expand All @@ -55,7 +61,10 @@ async fn vec_dbg_depth(vec: Vc<Vec<Vc<()>>>, depth: usize) -> Result<Vc<ValueDeb
.await
}

impl<T> ValueDebug for Vec<Vc<T>> {
impl<T> ValueDebug for Vec<Vc<T>>
where
T: Send,
{
fn dbg(self: Vc<Self>) -> Vc<ValueDebugString> {
vec_dbg_depth(Vc::<Self>::to_repr(self), usize::MAX)
}
Expand Down
4 changes: 3 additions & 1 deletion crates/turbo-tasks/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ impl<B: Backend + 'static> TurboTasks<B> {
/// Creates a new root task
pub fn spawn_root_task<T, F, Fut>(&self, functor: F) -> TaskId
where
T: Send,
F: Fn() -> Fut + Send + Sync + Clone + 'static,
Fut: Future<Output = Result<Vc<T>>> + Send,
{
Expand All @@ -361,6 +362,7 @@ impl<B: Backend + 'static> TurboTasks<B> {
#[track_caller]
pub fn spawn_once_task<T, Fut>(&self, future: Fut) -> TaskId
where
T: Send,
Fut: Future<Output = Result<Vc<T>>> + Send + 'static,
{
let id = self.backend.create_transient_task(
Expand Down Expand Up @@ -1398,7 +1400,7 @@ pub fn notify_scheduled_tasks() {
with_turbo_tasks(|tt| tt.notify_scheduled_tasks())
}

pub fn emit<T: VcValueTrait>(collectible: Vc<T>) {
pub fn emit<T: VcValueTrait + Send>(collectible: Vc<T>) {
with_turbo_tasks(|tt| tt.emit_collectible(T::get_trait_type_id(), collectible.node))
}

Expand Down
2 changes: 1 addition & 1 deletion crates/turbo-tasks/src/raw_vc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ impl<T: VcValueTrait> CollectiblesFuture<T> {
}
}

impl<T: VcValueTrait> Future for CollectiblesFuture<T> {
impl<T: VcValueTrait + Send> Future for CollectiblesFuture<T> {
type Output = Result<AutoSet<Vc<T>>>;

fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
Expand Down
5 changes: 4 additions & 1 deletion crates/turbo-tasks/src/task/task_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,10 @@ where
}
}

impl<T> TaskInput for Vc<T> {
impl<T> TaskInput for Vc<T>
where
T: Send,
{
fn try_from_concrete(input: &ConcreteTaskInput) -> Result<Self> {
match input {
ConcreteTaskInput::TaskCell(task, index) => Ok(Vc {
Expand Down
2 changes: 1 addition & 1 deletion crates/turbo-tasks/src/task/task_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub trait TaskOutput {

impl<T> TaskOutput for Vc<T>
where
T: ?Sized,
T: ?Sized + Send,
{
type Return = Vc<T>;

Expand Down
4 changes: 2 additions & 2 deletions crates/turbo-tasks/src/trait_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ where

impl<T> TraitRef<T>
where
T: VcValueTrait + ?Sized,
T: VcValueTrait + ?Sized + Send,
{
/// Returns a new cell that points to a value that implements the value
/// trait `T`.
Expand Down Expand Up @@ -136,7 +136,7 @@ pub trait IntoTraitRef {

impl<T> IntoTraitRef for Vc<T>
where
T: VcValueTrait + ?Sized,
T: VcValueTrait + ?Sized + Send,
{
type ValueTrait = T;

Expand Down
Loading

0 comments on commit 6fb9556

Please sign in to comment.