diff --git a/crates/turbo-tasks-macros/src/generic_type_macro.rs b/crates/turbo-tasks-macros/src/generic_type_macro.rs index 4bd1b50b6e980..29ca8ab32f727 100644 --- a/crates/turbo-tasks-macros/src/generic_type_macro.rs +++ b/crates/turbo-tasks-macros/src/generic_type_macro.rs @@ -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 { @@ -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); diff --git a/crates/turbo-tasks-macros/src/value_impl_macro.rs b/crates/turbo-tasks-macros/src/value_impl_macro.rs index d04c3ca37e097..fc8773b79226a 100644 --- a/crates/turbo-tasks-macros/src/value_impl_macro.rs +++ b/crates/turbo-tasks-macros/src/value_impl_macro.rs @@ -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; diff --git a/crates/turbo-tasks-macros/src/value_trait_macro.rs b/crates/turbo-tasks-macros/src/value_trait_macro.rs index 6f2f4c1a0621d..ea89818b91825 100644 --- a/crates/turbo-tasks-macros/src/value_trait_macro.rs +++ b/crates/turbo-tasks-macros/src/value_trait_macro.rs @@ -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)] @@ -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)* } diff --git a/crates/turbo-tasks/src/generics/index_map.rs b/crates/turbo-tasks/src/generics/index_map.rs index 3858bfd2ded31..47713c95555dd 100644 --- a/crates/turbo-tasks/src/generics/index_map.rs +++ b/crates/turbo-tasks/src/generics/index_map.rs @@ -23,7 +23,11 @@ async fn index_map_is_empty(index_map: Vc, Vc<()>>>) -> Result Vc, Vc>> { +impl Vc, Vc>> +where + K: Send, + V: Send, +{ /// See [`IndexMap::len`]. pub fn len(self) -> Vc { index_map_len(Self::to_repr(self)) @@ -40,7 +44,11 @@ fn index_map_default() -> Vc, Vc<()>>> { Vc::cell(Default::default()) } -impl ValueDefault for IndexMap, Vc> { +impl ValueDefault for IndexMap, Vc> +where + K: Send, + V: Send, +{ fn value_default() -> Vc { // Safety: `index_map_default` creates an empty map, which is a valid // representation of any index set of `Vc`. @@ -60,7 +68,11 @@ async fn index_map_dbg_depth( .await } -impl ValueDebug for IndexMap, Vc> { +impl ValueDebug for IndexMap, Vc> +where + K: Send, + V: Send, +{ fn dbg(self: Vc) -> Vc { index_map_dbg_depth(Vc::::to_repr(self), usize::MAX) } diff --git a/crates/turbo-tasks/src/generics/index_set.rs b/crates/turbo-tasks/src/generics/index_set.rs index 999f695d056da..49e6bce7d4108 100644 --- a/crates/turbo-tasks/src/generics/index_set.rs +++ b/crates/turbo-tasks/src/generics/index_set.rs @@ -23,7 +23,10 @@ async fn index_set_is_empty(index_set: Vc>>) -> Result> Ok(Vc::cell(index_set.is_empty())) } -impl Vc>> { +impl Vc>> +where + T: Send, +{ /// See [`IndexSet::len`]. pub fn len(self) -> Vc { index_set_len(Self::to_repr(self)) @@ -40,7 +43,10 @@ fn index_set_default() -> Vc>> { Vc::cell(Default::default()) } -impl ValueDefault for IndexSet> { +impl ValueDefault for IndexSet> +where + T: Send, +{ fn value_default() -> Vc { // Safety: `index_set_default` creates an empty set, which is a valid // representation of any index set of `Vc`. @@ -60,7 +66,10 @@ async fn index_set_dbg_depth( .await } -impl ValueDebug for IndexSet> { +impl ValueDebug for IndexSet> +where + T: Send, +{ fn dbg(self: Vc) -> Vc { index_set_dbg_depth(Vc::::to_repr(self), usize::MAX) } diff --git a/crates/turbo-tasks/src/generics/option.rs b/crates/turbo-tasks/src/generics/option.rs index df80d26f287d3..2b4710ffd3e82 100644 --- a/crates/turbo-tasks/src/generics/option.rs +++ b/crates/turbo-tasks/src/generics/option.rs @@ -22,7 +22,10 @@ async fn option_is_some(option: Vc>>) -> Result> { Ok(Vc::cell(option.is_some())) } -impl Vc>> { +impl Vc>> +where + T: Send, +{ /// See [`Option::is_none`]. pub fn is_none(self) -> Vc { option_is_none(Self::to_repr(self)) @@ -39,7 +42,10 @@ fn option_default() -> Vc>> { Vc::cell(Default::default()) } -impl ValueDefault for Option> { +impl ValueDefault for Option> +where + T: Send, +{ fn value_default() -> Vc { // Safety: `option_default` creates a None variant, which is a valid // representation of any option of `Vc`. @@ -59,7 +65,10 @@ async fn option_dbg_depth( .await } -impl ValueDebug for Option> { +impl ValueDebug for Option> +where + T: Send, +{ fn dbg(self: Vc) -> Vc { option_dbg_depth(Vc::::to_repr(self), usize::MAX) } diff --git a/crates/turbo-tasks/src/generics/vec.rs b/crates/turbo-tasks/src/generics/vec.rs index 40dd9294feec9..4472e6b86c9de 100644 --- a/crates/turbo-tasks/src/generics/vec.rs +++ b/crates/turbo-tasks/src/generics/vec.rs @@ -22,7 +22,10 @@ async fn vec_is_empty(vec: Vc>>) -> Result> { Ok(Vc::cell(vec.is_empty())) } -impl Vc>> { +impl Vc>> +where + T: Send, +{ /// See [`Vec::len`]. pub fn len(self) -> Vc { vec_len(Self::to_repr(self)) @@ -39,7 +42,10 @@ fn vec_default() -> Vc>> { Vc::cell(Default::default()) } -impl ValueDefault for Vec> { +impl ValueDefault for Vec> +where + T: Send, +{ fn value_default() -> Vc { // Safety: `vec_default` creates an empty vector, which is a valid // representation of any vector of `Vc`s. @@ -55,7 +61,10 @@ async fn vec_dbg_depth(vec: Vc>>, depth: usize) -> Result ValueDebug for Vec> { +impl ValueDebug for Vec> +where + T: Send, +{ fn dbg(self: Vc) -> Vc { vec_dbg_depth(Vc::::to_repr(self), usize::MAX) } diff --git a/crates/turbo-tasks/src/manager.rs b/crates/turbo-tasks/src/manager.rs index 92ab4e4367556..6aa0b6bd12031 100644 --- a/crates/turbo-tasks/src/manager.rs +++ b/crates/turbo-tasks/src/manager.rs @@ -341,6 +341,7 @@ impl TurboTasks { /// Creates a new root task pub fn spawn_root_task(&self, functor: F) -> TaskId where + T: Send, F: Fn() -> Fut + Send + Sync + Clone + 'static, Fut: Future>> + Send, { @@ -361,6 +362,7 @@ impl TurboTasks { #[track_caller] pub fn spawn_once_task(&self, future: Fut) -> TaskId where + T: Send, Fut: Future>> + Send + 'static, { let id = self.backend.create_transient_task( @@ -1398,7 +1400,7 @@ pub fn notify_scheduled_tasks() { with_turbo_tasks(|tt| tt.notify_scheduled_tasks()) } -pub fn emit(collectible: Vc) { +pub fn emit(collectible: Vc) { with_turbo_tasks(|tt| tt.emit_collectible(T::get_trait_type_id(), collectible.node)) } diff --git a/crates/turbo-tasks/src/raw_vc.rs b/crates/turbo-tasks/src/raw_vc.rs index 7413406821938..63d15ac888c37 100644 --- a/crates/turbo-tasks/src/raw_vc.rs +++ b/crates/turbo-tasks/src/raw_vc.rs @@ -436,7 +436,7 @@ impl CollectiblesFuture { } } -impl Future for CollectiblesFuture { +impl Future for CollectiblesFuture { type Output = Result>>; fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll { diff --git a/crates/turbo-tasks/src/task/task_input.rs b/crates/turbo-tasks/src/task/task_input.rs index 1b3f044d47b8d..56061ee4d150b 100644 --- a/crates/turbo-tasks/src/task/task_input.rs +++ b/crates/turbo-tasks/src/task/task_input.rs @@ -167,7 +167,10 @@ where } } -impl TaskInput for Vc { +impl TaskInput for Vc +where + T: Send, +{ fn try_from_concrete(input: &ConcreteTaskInput) -> Result { match input { ConcreteTaskInput::TaskCell(task, index) => Ok(Vc { diff --git a/crates/turbo-tasks/src/task/task_output.rs b/crates/turbo-tasks/src/task/task_output.rs index 41d36c2826f72..c14ed7507f67e 100644 --- a/crates/turbo-tasks/src/task/task_output.rs +++ b/crates/turbo-tasks/src/task/task_output.rs @@ -15,7 +15,7 @@ pub trait TaskOutput { impl TaskOutput for Vc where - T: ?Sized, + T: ?Sized + Send, { type Return = Vc; diff --git a/crates/turbo-tasks/src/trait_ref.rs b/crates/turbo-tasks/src/trait_ref.rs index c9bd2eafab2f1..db254e793c4a5 100644 --- a/crates/turbo-tasks/src/trait_ref.rs +++ b/crates/turbo-tasks/src/trait_ref.rs @@ -104,7 +104,7 @@ where impl TraitRef where - T: VcValueTrait + ?Sized, + T: VcValueTrait + ?Sized + Send, { /// Returns a new cell that points to a value that implements the value /// trait `T`. @@ -136,7 +136,7 @@ pub trait IntoTraitRef { impl IntoTraitRef for Vc where - T: VcValueTrait + ?Sized, + T: VcValueTrait + ?Sized + Send, { type ValueTrait = T; diff --git a/crates/turbo-tasks/src/vc/mod.rs b/crates/turbo-tasks/src/vc/mod.rs index 5a7f9b151d2d4..bc17ee448f91f 100644 --- a/crates/turbo-tasks/src/vc/mod.rs +++ b/crates/turbo-tasks/src/vc/mod.rs @@ -39,7 +39,7 @@ use crate::{ #[must_use] pub struct Vc where - T: ?Sized, + T: ?Sized + Send, { pub(crate) node: RawVc, #[doc(hidden)] @@ -176,7 +176,7 @@ where #[doc(hidden)] impl Deref for Vc where - T: ?Sized, + T: ?Sized + Send, { type Target = VcDeref; @@ -190,14 +190,14 @@ where } } -impl Copy for Vc where T: ?Sized {} +impl Copy for Vc where T: ?Sized + Send {} -unsafe impl Send for Vc where T: ?Sized {} -unsafe impl Sync for Vc where T: ?Sized {} +unsafe impl Send for Vc where T: ?Sized + Send {} +unsafe impl Sync for Vc where T: ?Sized + Send {} impl Clone for Vc where - T: ?Sized, + T: ?Sized + Send, { fn clone(&self) -> Self { *self @@ -206,7 +206,7 @@ where impl core::hash::Hash for Vc where - T: ?Sized, + T: ?Sized + Send, { fn hash(&self, state: &mut H) { self.node.hash(state); @@ -215,18 +215,18 @@ where impl PartialEq> for Vc where - T: ?Sized, + T: ?Sized + Send, { fn eq(&self, other: &Self) -> bool { self.node == other.node } } -impl Eq for Vc where T: ?Sized {} +impl Eq for Vc where T: ?Sized + Send {} impl PartialOrd> for Vc where - T: ?Sized, + T: ?Sized + Send, { fn partial_cmp(&self, other: &Self) -> Option { self.node.partial_cmp(&other.node) @@ -235,7 +235,7 @@ where impl Ord for Vc where - T: ?Sized, + T: ?Sized + Send, { fn cmp(&self, other: &Self) -> std::cmp::Ordering { self.node.cmp(&other.node) @@ -244,7 +244,7 @@ where impl Serialize for Vc where - T: ?Sized, + T: ?Sized + Send, { fn serialize(&self, serializer: S) -> Result { self.node.serialize(serializer) @@ -253,7 +253,7 @@ where impl<'de, T> Deserialize<'de> for Vc where - T: ?Sized, + T: ?Sized + Send, { fn deserialize>(deserializer: D) -> Result { Ok(Vc { @@ -265,7 +265,10 @@ where // TODO(alexkirsz) This should not be implemented for Vc. Instead, users should // use the `ValueDebug` implementation to get a `D: Debug`. -impl std::fmt::Debug for Vc { +impl std::fmt::Debug for Vc +where + T: Send, +{ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("Vc").field("node", &self.node).finish() } @@ -294,7 +297,7 @@ where impl Vc where - T: ?Sized, + T: ?Sized + Send, { /// Connects the operation pointed to by this `Vc` to the current task. pub fn connect(vc: Self) { @@ -337,7 +340,7 @@ where pub fn upcast(vc: Self) -> Vc where T: Upcast, - K: VcValueTrait + ?Sized, + K: VcValueTrait + ?Sized + Send, { Vc { node: vc.node, @@ -348,7 +351,7 @@ where impl Vc where - T: ?Sized, + T: ?Sized + Send, { /// Resolve the reference until it points to a cell directly. /// @@ -386,7 +389,7 @@ where impl Vc where - T: VcValueTrait + ?Sized, + T: VcValueTrait + ?Sized + Send, { /// Attempts to sidecast the given `Vc>` to a `Vc>`. /// This operation also resolves the `Vc`. @@ -398,7 +401,7 @@ where /// removing the need for a `Result` return type. pub async fn try_resolve_sidecast(vc: Self) -> Result>, ResolveTypeError> where - K: VcValueTrait + ?Sized, + K: VcValueTrait + ?Sized + Send, { let raw_vc: RawVc = vc.node; let raw_vc = raw_vc @@ -418,7 +421,7 @@ where pub async fn try_resolve_downcast(vc: Self) -> Result>, ResolveTypeError> where K: Upcast, - K: VcValueTrait + ?Sized, + K: VcValueTrait + ?Sized + Send, { let raw_vc: RawVc = vc.node; let raw_vc = raw_vc @@ -453,7 +456,7 @@ where impl CollectiblesSource for Vc where - T: ?Sized, + T: ?Sized + Send, { fn take_collectibles(self) -> CollectiblesFuture { self.node.take_collectibles() @@ -466,7 +469,7 @@ where impl From for Vc where - T: ?Sized, + T: ?Sized + Send, { fn from(node: RawVc) -> Self { Self { @@ -478,7 +481,7 @@ where impl TraceRawVcs for Vc where - T: ?Sized, + T: ?Sized + Send, { fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { TraceRawVcs::trace_raw_vcs(&self.node, trace_context); @@ -487,7 +490,7 @@ where impl ValueDebugFormat for Vc where - T: ?Sized, + T: ?Sized + Send, T: Upcast>, { fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString { @@ -534,11 +537,11 @@ where } } -impl Unpin for Vc where T: ?Sized {} +impl Unpin for Vc where T: ?Sized + Send {} impl Default for Vc where - T: ValueDefault, + T: ValueDefault + Send, { fn default() -> Self { T::value_default() diff --git a/crates/turbo-tasks/src/vc/traits.rs b/crates/turbo-tasks/src/vc/traits.rs index 67e52e942924f..a2b07dc72e770 100644 --- a/crates/turbo-tasks/src/vc/traits.rs +++ b/crates/turbo-tasks/src/vc/traits.rs @@ -34,9 +34,9 @@ pub trait VcValueTrait { /// /// The implementor of this trait must ensure that `Self` implements the /// trait `T`. -pub unsafe trait Upcast +pub unsafe trait Upcast: Send where - T: VcValueTrait + ?Sized, + T: VcValueTrait + ?Sized + Send, { } @@ -47,9 +47,9 @@ where /// /// The implementor of this trait must ensure that `Self` implements the /// trait `T`. -pub unsafe trait Dynamic +pub unsafe trait Dynamic: Send where - T: VcValueTrait + ?Sized, + T: VcValueTrait + ?Sized + Send, { } diff --git a/crates/turbopack-core/src/chunk/evaluate.rs b/crates/turbopack-core/src/chunk/evaluate.rs index bd16032de8ef8..e39110a0a11bc 100644 --- a/crates/turbopack-core/src/chunk/evaluate.rs +++ b/crates/turbopack-core/src/chunk/evaluate.rs @@ -17,7 +17,7 @@ use crate::{ #[turbo_tasks::value_trait] pub trait EvaluatableAsset: Asset + Module + ChunkableModule {} -pub trait EvaluatableAssetExt { +pub trait EvaluatableAssetExt: Send { fn to_evaluatable( self: Vc, asset_context: Vc>, diff --git a/crates/turbopack-core/src/chunk/mod.rs b/crates/turbopack-core/src/chunk/mod.rs index 8c33d7568a7ea..984cccb5cee39 100644 --- a/crates/turbopack-core/src/chunk/mod.rs +++ b/crates/turbopack-core/src/chunk/mod.rs @@ -338,7 +338,7 @@ async fn reference_to_graph_nodes( )>, > where - I: FromChunkableModule, + I: Send + FromChunkableModule, { let Some(chunkable_module_reference) = Vc::try_resolve_downcast::>(reference).await? @@ -503,7 +503,7 @@ struct ChunkContentVisit { _phantom: PhantomData, } -type ChunkItemToGraphNodesEdges = impl Iterator< +type ChunkItemToGraphNodesEdges = impl Iterator< Item = ( Option<(Vc>, ChunkingType)>, ChunkContentGraphNode>, @@ -515,7 +515,7 @@ type ChunkItemToGraphNodesFuture = impl Visit>, ()> for ChunkContentVisit> where - I: FromChunkableModule, + I: Send + FromChunkableModule, { type Edge = ( Option<(Vc>, ChunkingType)>, diff --git a/crates/turbopack-core/src/issue/mod.rs b/crates/turbopack-core/src/issue/mod.rs index 5f30f8f19605c..74be2821950c5 100644 --- a/crates/turbopack-core/src/issue/mod.rs +++ b/crates/turbopack-core/src/issue/mod.rs @@ -744,7 +744,7 @@ where } } -pub async fn handle_issues( +pub async fn handle_issues( source: Vc, issue_reporter: Vc>, min_failing_severity: Vc, diff --git a/crates/turbopack-core/src/resolve/origin.rs b/crates/turbopack-core/src/resolve/origin.rs index a565c5c3f4a5a..522fbcc11652e 100644 --- a/crates/turbopack-core/src/resolve/origin.rs +++ b/crates/turbopack-core/src/resolve/origin.rs @@ -30,7 +30,7 @@ pub trait ResolveOrigin { // TODO it would be nice if these methods can be moved to the trait to allow // overriding it, but currently we explicitly disallow it due to the way // transitions work. Maybe transitions should be decorators on ResolveOrigin? -pub trait ResolveOriginExt { +pub trait ResolveOriginExt: Send { /// Resolve to an asset from that origin. Custom resolve options can be /// passed. Otherwise provide `origin.resolve_options()` unmodified. fn resolve_asset( diff --git a/crates/turbopack-core/src/version.rs b/crates/turbopack-core/src/version.rs index bb891a42dc6ef..3eb6df2f45bb7 100644 --- a/crates/turbopack-core/src/version.rs +++ b/crates/turbopack-core/src/version.rs @@ -105,7 +105,7 @@ impl From for Vc> { } } -pub trait VersionedContentExt { +pub trait VersionedContentExt: Send { fn versioned(self: Vc) -> Vc>; } diff --git a/crates/turbopack-dev-server/src/source/mod.rs b/crates/turbopack-dev-server/src/source/mod.rs index b47843f49b67c..6ec9413441644 100644 --- a/crates/turbopack-dev-server/src/source/mod.rs +++ b/crates/turbopack-dev-server/src/source/mod.rs @@ -420,7 +420,7 @@ pub trait ContentSource { } } -pub trait ContentSourceExt { +pub trait ContentSourceExt: Send { fn issue_file_path( self: Vc, file_path: Vc, diff --git a/crates/turbopack-dev-server/src/update/stream.rs b/crates/turbopack-dev-server/src/update/stream.rs index 4a471fd74c37e..488bbe61bf2f3 100644 --- a/crates/turbopack-dev-server/src/update/stream.rs +++ b/crates/turbopack-dev-server/src/update/stream.rs @@ -23,7 +23,7 @@ use crate::source::{resolve::ResolveSourceRequestResult, ProxyResult}; type GetContentFn = Box Vc + Send + Sync>; -async fn peek_issues(source: Vc) -> Result>> { +async fn peek_issues(source: Vc) -> Result>> { let captured = source.peek_issues_with_path().await?.await?; captured.get_plain_issues().await diff --git a/crates/turbopack-ecmascript/src/chunk/item.rs b/crates/turbopack-ecmascript/src/chunk/item.rs index d5bf8626bf021..7d4210af21b2d 100644 --- a/crates/turbopack-ecmascript/src/chunk/item.rs +++ b/crates/turbopack-ecmascript/src/chunk/item.rs @@ -179,7 +179,7 @@ pub trait EcmascriptChunkItem: ChunkItem { fn chunking_context(self: Vc) -> Vc>; } -pub trait EcmascriptChunkItemExt { +pub trait EcmascriptChunkItemExt: Send { /// Returns the module id of this chunk item. fn id(self: Vc) -> Vc;