diff --git a/crates/turbo-tasks-macros/src/derive/task_input_macro.rs b/crates/turbo-tasks-macros/src/derive/task_input_macro.rs index 04c60ee76389a3..a6c0169096c669 100644 --- a/crates/turbo-tasks-macros/src/derive/task_input_macro.rs +++ b/crates/turbo-tasks-macros/src/derive/task_input_macro.rs @@ -123,7 +123,7 @@ pub fn derive_task_input(input: TokenStream) -> TokenStream { _ => return Err(anyhow::anyhow!("invalid discriminant for {}", stringify!(#ident))), }) }, - _ => Err(anyhow::anyhow!("invalid task input type, expected list")), + _ => Err(anyhow::anyhow!("invalid task input type, expected list (enum)")), } }, quote! { @@ -155,7 +155,7 @@ pub fn derive_task_input(input: TokenStream) -> TokenStream { #try_from_expansion Ok(#ident #destructuring) }, - _ => Err(anyhow::anyhow!("invalid task input type, expected list")), + _ => Err(anyhow::anyhow!("invalid task input type, expected list (struct)")), } }, quote! { diff --git a/crates/turbo-tasks-macros/src/func.rs b/crates/turbo-tasks-macros/src/func.rs index 3e1a414cfa0651..6c8129cd634b4e 100644 --- a/crates/turbo-tasks-macros/src/func.rs +++ b/crates/turbo-tasks-macros/src/func.rs @@ -326,7 +326,7 @@ impl TurboFn { *#trait_type_id_ident, std::borrow::Cow::Borrowed(stringify!(#ident)), #converted_this, - vec![#converted_inputs], + turbo_tasks::TaskInput::into_concrete((#converted_inputs)), ) ) } @@ -352,7 +352,7 @@ impl TurboFn { turbo_tasks::dynamic_this_call( *#native_function_id_ident, #converted_this, - vec![#converted_inputs], + turbo_tasks::TaskInput::into_concrete((#converted_inputs)), ) ) } @@ -363,7 +363,7 @@ impl TurboFn { <#output as turbo_tasks::task::TaskOutput>::try_from_raw_vc( turbo_tasks::dynamic_call( *#native_function_id_ident, - vec![#converted_inputs], + turbo_tasks::TaskInput::into_concrete((#converted_inputs)), ) ) } diff --git a/crates/turbo-tasks-memory/src/memory_backend.rs b/crates/turbo-tasks-memory/src/memory_backend.rs index 404a43f5a7a084..5b3ac2a7b101e5 100644 --- a/crates/turbo-tasks-memory/src/memory_backend.rs +++ b/crates/turbo-tasks-memory/src/memory_backend.rs @@ -548,12 +548,12 @@ impl Backend for MemoryBackend { PersistentTaskType::ResolveNative { fn_type: function_id, this: _, - args: _, + arg: _, } | PersistentTaskType::Native { fn_type: function_id, this: _, - args: _, + arg: _, } => { stats.increment_cache_hit(*function_id); } @@ -561,7 +561,7 @@ impl Backend for MemoryBackend { trait_type, method_name: name, this, - args: _, + arg: _, } => { // HACK: Resolve the this argument (`self`) in order to attribute the cache hit // to the concrete trait implementation, rather than the dynamic trait method. @@ -595,7 +595,7 @@ impl Backend for MemoryBackend { PersistentTaskType::Native { fn_type: function_id, this: _, - args: _, + arg: _, } => { stats.increment_cache_miss(*function_id); } diff --git a/crates/turbo-tasks-memory/src/task.rs b/crates/turbo-tasks-memory/src/task.rs index af0b69892707cd..559acea4735dcd 100644 --- a/crates/turbo-tasks-memory/src/task.rs +++ b/crates/turbo-tasks-memory/src/task.rs @@ -587,14 +587,14 @@ impl Task { PersistentTaskType::Native { fn_type: native_fn, this: _, - args: _, + arg: _, } => { format!("[{}] {}", id, registry::get_function(*native_fn).name) } PersistentTaskType::ResolveNative { fn_type: native_fn, this: _, - args: _, + arg: _, } => { format!( "[{}] [resolve] {}", @@ -606,7 +606,7 @@ impl Task { trait_type, method_name: fn_name, this: _, - args: _, + arg: _, } => { format!( "[{}] [resolve trait] {} in trait {}", @@ -757,7 +757,7 @@ impl Task { PersistentTaskType::Native { fn_type: native_fn, this, - args: inputs, + arg: inputs, } => { let func = registry::get_function(*native_fn); let span = func.span(); @@ -770,7 +770,7 @@ impl Task { PersistentTaskType::ResolveNative { fn_type: ref native_fn_id, this, - args: inputs, + arg: inputs, } => { let native_fn_id = *native_fn_id; let func = registry::get_function(native_fn_id); @@ -791,7 +791,7 @@ impl Task { trait_type: trait_type_id, method_name: name, this, - args: inputs, + arg: inputs, } => { let trait_type_id = *trait_type_id; let trait_type = registry::get_trait(trait_type_id); diff --git a/crates/turbo-tasks-testing/src/lib.rs b/crates/turbo-tasks-testing/src/lib.rs index 7224e7db52fc92..054bb00d3dee61 100644 --- a/crates/turbo-tasks-testing/src/lib.rs +++ b/crates/turbo-tasks-testing/src/lib.rs @@ -41,10 +41,10 @@ impl VcStorage { &self, func: turbo_tasks::FunctionId, this_arg: Option, - inputs: Vec, + arg: turbo_tasks::ConcreteTaskInput, ) -> RawVc { let this = self.this.upgrade().unwrap(); - let func = registry::get_function(func).bind(this_arg, &inputs); + let func = registry::get_function(func).bind(this_arg, &arg); let handle = tokio::runtime::Handle::current(); let future = func(); let i = { @@ -84,24 +84,24 @@ impl TurboTasksCallApi for VcStorage { fn dynamic_call( &self, func: turbo_tasks::FunctionId, - inputs: Vec, + arg: turbo_tasks::ConcreteTaskInput, ) -> RawVc { - self.dynamic_call(func, None, inputs) + self.dynamic_call(func, None, arg) } fn dynamic_this_call( &self, func: turbo_tasks::FunctionId, this_arg: RawVc, - inputs: Vec, + arg: turbo_tasks::ConcreteTaskInput, ) -> RawVc { - self.dynamic_call(func, Some(this_arg), inputs) + self.dynamic_call(func, Some(this_arg), arg) } fn native_call( &self, _func: turbo_tasks::FunctionId, - _inputs: Vec, + _arg: turbo_tasks::ConcreteTaskInput, ) -> RawVc { unreachable!() } @@ -110,7 +110,7 @@ impl TurboTasksCallApi for VcStorage { &self, _func: turbo_tasks::FunctionId, _this: RawVc, - _inputs: Vec, + _arg: turbo_tasks::ConcreteTaskInput, ) -> RawVc { unreachable!() } @@ -120,7 +120,7 @@ impl TurboTasksCallApi for VcStorage { _trait_type: turbo_tasks::TraitTypeId, _trait_fn_name: Cow<'static, str>, _this: RawVc, - _inputs: Vec, + _arg: turbo_tasks::ConcreteTaskInput, ) -> RawVc { unreachable!() } diff --git a/crates/turbo-tasks/src/backend.rs b/crates/turbo-tasks/src/backend.rs index 69aa087822de64..37009669609ff3 100644 --- a/crates/turbo-tasks/src/backend.rs +++ b/crates/turbo-tasks/src/backend.rs @@ -4,7 +4,6 @@ use std::{ fmt, fmt::{Debug, Display, Write}, future::Future, - mem::take, pin::Pin, sync::Arc, time::Duration, @@ -71,7 +70,7 @@ pub enum PersistentTaskType { Native { fn_type: FunctionId, this: Option, - args: Vec, + arg: ConcreteTaskInput, }, /// A resolve task, which resolves arguments and calls the function with @@ -79,7 +78,7 @@ pub enum PersistentTaskType { ResolveNative { fn_type: FunctionId, this: Option, - args: Vec, + arg: ConcreteTaskInput, }, /// A trait method resolve task. It resolves the first (`self`) argument and @@ -90,7 +89,7 @@ pub enum PersistentTaskType { trait_type: TraitTypeId, method_name: Cow<'static, str>, this: RawVc, - args: Vec, + arg: ConcreteTaskInput, }, } @@ -106,95 +105,19 @@ impl PersistentTaskType { Self::Native { fn_type: _, this: _, - args: inputs, - } => inputs.shrink_to_fit(), + arg, + } => arg.shrink_to_fit(), Self::ResolveNative { fn_type: _, this: _, - args: inputs, - } => inputs.shrink_to_fit(), + arg, + } => arg.shrink_to_fit(), Self::ResolveTrait { trait_type: _, method_name: _, this: _, - args: inputs, - } => inputs.shrink_to_fit(), - } - } - - pub fn len(&self) -> usize { - match self { - PersistentTaskType::Native { - fn_type: _, - this: _, - args: v, - } - | PersistentTaskType::ResolveNative { - fn_type: _, - this: _, - args: v, - } - | PersistentTaskType::ResolveTrait { - trait_type: _, - method_name: _, - this: _, - args: v, - } => v.len(), - } - } - - pub fn is_empty(&self) -> bool { - match self { - PersistentTaskType::Native { - fn_type: _, - this: _, - args: v, - } - | PersistentTaskType::ResolveNative { - fn_type: _, - this: _, - args: v, - } - | PersistentTaskType::ResolveTrait { - trait_type: _, - method_name: _, - this: _, - args: v, - } => v.is_empty(), - } - } - - pub fn partial(&self, len: usize) -> Self { - match self { - PersistentTaskType::Native { - fn_type: f, - this, - args: v, - } => PersistentTaskType::Native { - fn_type: *f, - this: *this, - args: v[..len].to_vec(), - }, - PersistentTaskType::ResolveNative { - fn_type: f, - this, - args: v, - } => PersistentTaskType::ResolveNative { - fn_type: *f, - this: *this, - args: v[..len].to_vec(), - }, - PersistentTaskType::ResolveTrait { - trait_type: f, - method_name: n, - this, - args: v, - } => PersistentTaskType::ResolveTrait { - trait_type: *f, - method_name: n.clone(), - this: *this, - args: v[..len].to_vec(), - }, + arg, + } => arg.shrink_to_fit(), } } @@ -208,18 +131,18 @@ impl PersistentTaskType { PersistentTaskType::Native { fn_type: native_fn, this: _, - args: _, + arg: _, } | PersistentTaskType::ResolveNative { fn_type: native_fn, this: _, - args: _, + arg: _, } => Cow::Borrowed(®istry::get_function(*native_fn).name), PersistentTaskType::ResolveTrait { trait_type: trait_id, method_name: fn_name, this: _, - args: _, + arg: _, } => format!("{}::{}", registry::get_trait(*trait_id).name, fn_name).into(), } } @@ -450,19 +373,17 @@ impl PersistentTaskType { pub async fn run_resolve_native( fn_id: FunctionId, mut this: Option, - mut inputs: Vec, + arg: ConcreteTaskInput, turbo_tasks: Arc>, ) -> Result { if let Some(this) = this.as_mut() { *this = this.resolve().await?; } - for input in inputs.iter_mut() { - *input = take(input).resolve().await?; - } + let arg = arg.resolve().await?; Ok(if let Some(this) = this { - turbo_tasks.this_call(fn_id, this, inputs) + turbo_tasks.this_call(fn_id, this, arg) } else { - turbo_tasks.native_call(fn_id, inputs) + turbo_tasks.native_call(fn_id, arg) }) } @@ -482,7 +403,7 @@ impl PersistentTaskType { trait_type: TraitTypeId, name: Cow<'static, str>, this: RawVc, - mut inputs: Vec, + arg: ConcreteTaskInput, turbo_tasks: Arc>, ) -> Result { let this = this.resolve().await?; @@ -494,10 +415,8 @@ impl PersistentTaskType { }; let native_fn = Self::resolve_trait_method_from_value(trait_type, this_ty, name)?; - for input in inputs.iter_mut() { - *input = take(input).resolve().await?; - } - Ok(turbo_tasks.dynamic_this_call(native_fn, this, inputs)) + let arg = arg.resolve().await?; + Ok(turbo_tasks.dynamic_this_call(native_fn, this, arg)) } /// Shared helper used by [`Self::resolve_trait_method`] and @@ -541,22 +460,22 @@ impl PersistentTaskType { PersistentTaskType::Native { fn_type: fn_id, this, - args: inputs, + arg, } => { let native_fn = registry::get_function(fn_id); - let bound = native_fn.bind(this, &inputs); + let bound = native_fn.bind(this, &arg); (bound)() } PersistentTaskType::ResolveNative { fn_type: fn_id, this, - args: inputs, + arg: inputs, } => Box::pin(Self::run_resolve_native(fn_id, this, inputs, turbo_tasks)), PersistentTaskType::ResolveTrait { trait_type, method_name: name, this, - args: inputs, + arg: inputs, } => Box::pin(Self::run_resolve_trait( trait_type, name, @@ -590,7 +509,7 @@ pub(crate) mod tests { PersistentTaskType::Native { fn_type: *MOCK_FUNC_TASK_FUNCTION_ID, this: None, - args: Vec::new() + arg: Default::default() } .get_name(), "mock_func_task", @@ -600,7 +519,7 @@ pub(crate) mod tests { trait_type: *MOCKTRAIT_TRAIT_TYPE_ID, method_name: "mock_method_task".into(), this: RawVc::TaskOutput(unsafe { TaskId::new_unchecked(1) }), - args: Vec::new() + arg: Default::default() } .get_name(), "MockTrait::mock_method_task", diff --git a/crates/turbo-tasks/src/manager.rs b/crates/turbo-tasks/src/manager.rs index 3ee524950bd1fc..8a49db0d2fafd1 100644 --- a/crates/turbo-tasks/src/manager.rs +++ b/crates/turbo-tasks/src/manager.rs @@ -39,21 +39,16 @@ use crate::{ }; pub trait TurboTasksCallApi: Sync + Send { - fn dynamic_call(&self, func: FunctionId, inputs: Vec) -> RawVc; - fn dynamic_this_call( - &self, - func: FunctionId, - this: RawVc, - inputs: Vec, - ) -> RawVc; - fn native_call(&self, func: FunctionId, inputs: Vec) -> RawVc; - fn this_call(&self, func: FunctionId, this: RawVc, inputs: Vec) -> RawVc; + fn dynamic_call(&self, func: FunctionId, arg: ConcreteTaskInput) -> RawVc; + fn dynamic_this_call(&self, func: FunctionId, this: RawVc, arg: ConcreteTaskInput) -> RawVc; + fn native_call(&self, func: FunctionId, arg: ConcreteTaskInput) -> RawVc; + fn this_call(&self, func: FunctionId, this: RawVc, arg: ConcreteTaskInput) -> RawVc; fn trait_call( &self, trait_type: TraitTypeId, trait_fn_name: Cow<'static, str>, this: RawVc, - inputs: Vec, + arg: ConcreteTaskInput, ) -> RawVc; fn run_once( @@ -375,12 +370,12 @@ impl TurboTasks { /// Call a native function with arguments. /// All inputs must be resolved. - pub(crate) fn native_call(&self, func: FunctionId, inputs: Vec) -> RawVc { + pub(crate) fn native_call(&self, func: FunctionId, arg: ConcreteTaskInput) -> RawVc { RawVc::TaskOutput(self.backend.get_or_create_persistent_task( PersistentTaskType::Native { fn_type: func, this: None, - args: inputs, + arg, }, current_task("turbo_function calls"), self, @@ -389,17 +384,12 @@ impl TurboTasks { /// Call a native function with arguments. /// All inputs must be resolved. - pub(crate) fn this_call( - &self, - func: FunctionId, - this: RawVc, - inputs: Vec, - ) -> RawVc { + pub(crate) fn this_call(&self, func: FunctionId, this: RawVc, arg: ConcreteTaskInput) -> RawVc { RawVc::TaskOutput(self.backend.get_or_create_persistent_task( PersistentTaskType::Native { fn_type: func, this: Some(this), - args: inputs, + arg, }, current_task("turbo_function calls"), self, @@ -408,15 +398,15 @@ impl TurboTasks { /// Calls a native function with arguments. Resolves arguments when needed /// with a wrapper task. - pub fn dynamic_call(&self, func: FunctionId, inputs: Vec) -> RawVc { - if inputs.iter().all(|i| i.is_resolved()) { - self.native_call(func, inputs) + pub fn dynamic_call(&self, func: FunctionId, arg: ConcreteTaskInput) -> RawVc { + if arg.is_resolved() { + self.native_call(func, arg) } else { RawVc::TaskOutput(self.backend.get_or_create_persistent_task( PersistentTaskType::ResolveNative { fn_type: func, this: None, - args: inputs, + arg, }, current_task("turbo_function calls"), self, @@ -430,16 +420,16 @@ impl TurboTasks { &self, func: FunctionId, this: RawVc, - inputs: Vec, + arg: ConcreteTaskInput, ) -> RawVc { - if this.is_resolved() && inputs.iter().all(|i| i.is_resolved()) { - self.this_call(func, this, inputs) + if this.is_resolved() && arg.is_resolved() { + self.this_call(func, this, arg) } else { RawVc::TaskOutput(self.backend.get_or_create_persistent_task( PersistentTaskType::ResolveNative { fn_type: func, this: Some(this), - args: inputs, + arg, }, current_task("turbo_function calls"), self, @@ -454,7 +444,7 @@ impl TurboTasks { trait_type: TraitTypeId, mut trait_fn_name: Cow<'static, str>, this: RawVc, - inputs: Vec, + arg: ConcreteTaskInput, ) -> RawVc { // avoid creating a wrapper task if self is already resolved // for resolved cells we already know the value type so we can lookup the @@ -462,7 +452,7 @@ impl TurboTasks { if let RawVc::TaskCell(_, CellId { type_id, .. }) = this { match get_trait_method(trait_type, type_id, trait_fn_name) { Ok(native_fn) => { - return self.dynamic_this_call(native_fn, this, inputs); + return self.dynamic_this_call(native_fn, this, arg); } Err(name) => { trait_fn_name = name; @@ -476,7 +466,7 @@ impl TurboTasks { trait_type, method_name: trait_fn_name, this, - args: inputs, + arg, }, current_task("turbo_function calls"), self, @@ -856,31 +846,26 @@ impl TurboTasks { } impl TurboTasksCallApi for TurboTasks { - fn dynamic_call(&self, func: FunctionId, inputs: Vec) -> RawVc { - self.dynamic_call(func, inputs) + fn dynamic_call(&self, func: FunctionId, arg: ConcreteTaskInput) -> RawVc { + self.dynamic_call(func, arg) } - fn dynamic_this_call( - &self, - func: FunctionId, - this: RawVc, - inputs: Vec, - ) -> RawVc { - self.dynamic_this_call(func, this, inputs) + fn dynamic_this_call(&self, func: FunctionId, this: RawVc, arg: ConcreteTaskInput) -> RawVc { + self.dynamic_this_call(func, this, arg) } - fn native_call(&self, func: FunctionId, inputs: Vec) -> RawVc { - self.native_call(func, inputs) + fn native_call(&self, func: FunctionId, arg: ConcreteTaskInput) -> RawVc { + self.native_call(func, arg) } - fn this_call(&self, func: FunctionId, this: RawVc, inputs: Vec) -> RawVc { - self.this_call(func, this, inputs) + fn this_call(&self, func: FunctionId, this: RawVc, arg: ConcreteTaskInput) -> RawVc { + self.this_call(func, this, arg) } fn trait_call( &self, trait_type: TraitTypeId, trait_fn_name: Cow<'static, str>, this: RawVc, - inputs: Vec, + arg: ConcreteTaskInput, ) -> RawVc { - self.trait_call(trait_type, trait_fn_name, this, inputs) + self.trait_call(trait_type, trait_fn_name, this, arg) } #[track_caller] @@ -1355,14 +1340,14 @@ pub async fn run_once_with_reason( } /// Calls [`TurboTasks::dynamic_call`] for the current turbo tasks instance. -pub fn dynamic_call(func: FunctionId, inputs: Vec) -> RawVc { - with_turbo_tasks(|tt| tt.dynamic_call(func, inputs)) +pub fn dynamic_call(func: FunctionId, arg: ConcreteTaskInput) -> RawVc { + with_turbo_tasks(|tt| tt.dynamic_call(func, arg)) } /// Calls [`TurboTasks::dynamic_this_call`] for the current turbo tasks /// instance. -pub fn dynamic_this_call(func: FunctionId, this: RawVc, inputs: Vec) -> RawVc { - with_turbo_tasks(|tt| tt.dynamic_this_call(func, this, inputs)) +pub fn dynamic_this_call(func: FunctionId, this: RawVc, arg: ConcreteTaskInput) -> RawVc { + with_turbo_tasks(|tt| tt.dynamic_this_call(func, this, arg)) } /// Calls [`TurboTasks::trait_call`] for the current turbo tasks instance. @@ -1370,9 +1355,9 @@ pub fn trait_call( trait_type: TraitTypeId, trait_fn_name: Cow<'static, str>, this: RawVc, - inputs: Vec, + arg: ConcreteTaskInput, ) -> RawVc { - with_turbo_tasks(|tt| tt.trait_call(trait_type, trait_fn_name, this, inputs)) + with_turbo_tasks(|tt| tt.trait_call(trait_type, trait_fn_name, this, arg)) } pub fn turbo_tasks() -> Arc { diff --git a/crates/turbo-tasks/src/native_function.rs b/crates/turbo-tasks/src/native_function.rs index c43910288fc990..23ec8d2ded9914 100644 --- a/crates/turbo-tasks/src/native_function.rs +++ b/crates/turbo-tasks/src/native_function.rs @@ -55,8 +55,8 @@ impl NativeFunction { } /// Creates a functor for execution from a fixed set of inputs. - pub fn bind(&'static self, this: Option, inputs: &[ConcreteTaskInput]) -> NativeTaskFn { - match (self.implementation).functor(this, inputs) { + pub fn bind(&'static self, this: Option, arg: &ConcreteTaskInput) -> NativeTaskFn { + match (self.implementation).functor(this, arg) { Ok(functor) => functor, Err(err) => { let err = SharedError::new(err); diff --git a/crates/turbo-tasks/src/task/concrete_task_input.rs b/crates/turbo-tasks/src/task/concrete_task_input.rs index e0982858c744af..7d67d995765355 100644 --- a/crates/turbo-tasks/src/task/concrete_task_input.rs +++ b/crates/turbo-tasks/src/task/concrete_task_input.rs @@ -396,6 +396,16 @@ impl ConcreteTaskInput { } } + pub fn shrink_to_fit(&mut self) { + match self { + ConcreteTaskInput::List(list) => { + list.shrink_to_fit(); + list.iter_mut().for_each(|i| i.shrink_to_fit()); + } + _ => {} + } + } + pub fn get_task_id(&self) -> Option { match self { ConcreteTaskInput::TaskOutput(t) | ConcreteTaskInput::TaskCell(t, _) => Some(*t), diff --git a/crates/turbo-tasks/src/task/function.rs b/crates/turbo-tasks/src/task/function.rs index aa436bf6cef398..042218c6ae5526 100644 --- a/crates/turbo-tasks/src/task/function.rs +++ b/crates/turbo-tasks/src/task/function.rs @@ -23,7 +23,7 @@ use std::{future::Future, marker::PhantomData, pin::Pin}; -use anyhow::{bail, Context, Result}; +use anyhow::Result; use super::{TaskInput, TaskOutput}; use crate::{ConcreteTaskInput, RawVc, Vc, VcRead, VcValueType}; @@ -32,7 +32,7 @@ pub type NativeTaskFuture = Pin> + Send>>; pub type NativeTaskFn = Box NativeTaskFuture + Send + Sync>; pub trait TaskFn: Send + Sync + 'static { - fn functor(&self, this: Option, inputs: &[ConcreteTaskInput]) -> Result; + fn functor(&self, this: Option, arg: &ConcreteTaskInput) -> Result; } pub trait IntoTaskFn { @@ -93,8 +93,8 @@ where Mode: TaskFnMode, Inputs: TaskInputs, { - fn functor(&self, this: Option, inputs: &[ConcreteTaskInput]) -> Result { - TaskFnInputFunction::functor(&self.task_fn, this, inputs) + fn functor(&self, this: Option, arg: &ConcreteTaskInput) -> Result { + TaskFnInputFunction::functor(&self.task_fn, this, arg) } } @@ -110,19 +110,19 @@ where Mode: TaskFnMode, Inputs: TaskInputs, { - fn functor(&self, this: Option, inputs: &[ConcreteTaskInput]) -> Result { - TaskFnInputFunctionWithThis::functor(&self.task_fn, this, inputs) + fn functor(&self, this: Option, arg: &ConcreteTaskInput) -> Result { + TaskFnInputFunctionWithThis::functor(&self.task_fn, this, arg) } } trait TaskFnInputFunction: Send + Sync + Clone + 'static { - fn functor(&self, this: Option, inputs: &[ConcreteTaskInput]) -> Result; + fn functor(&self, this: Option, arg: &ConcreteTaskInput) -> Result; } trait TaskFnInputFunctionWithThis: Send + Sync + Clone + 'static { - fn functor(&self, this: Option, inputs: &[ConcreteTaskInput]) -> Result; + fn functor(&self, this: Option, arg: &ConcreteTaskInput) -> Result; } pub trait TaskInputs: Send + Sync + 'static {} @@ -155,36 +155,8 @@ macro_rules! task_inputs_impl { } } -macro_rules! as_concrete_task_input { - ( $arg:ident ) => { - ConcreteTaskInput - }; -} - macro_rules! task_fn_impl { - ( $helper_module:ident $async_fn_trait:ident $arg_len:literal $( $arg:ident )* ) => { - mod $helper_module { - use super::*; - - // this is a non-generic helper method to allow code-sharing across monomorphized - // instances of this function - pub fn get_args( - inputs: &[ConcreteTaskInput], - ) -> Result<($(&as_concrete_task_input!($arg),)*)> { - get_args_iter(inputs.iter()) - } - - fn get_args_iter( - mut iter: std::slice::Iter<'_, ConcreteTaskInput>, - ) -> Result<($(&as_concrete_task_input!($arg),)*)> { - let args = ($(next_arg(&mut iter, stringify!($arg))?,)*); - if iter.next().is_some() { - bail!("task was called with too many arguments"); - } - Ok(args) - } - } - + ( $async_fn_trait:ident $arg_len:literal $( $arg:ident )* ) => { impl TaskFnInputFunction for F where $($arg: TaskInput + 'static,)* @@ -192,13 +164,11 @@ macro_rules! task_fn_impl { Output: TaskOutput + 'static, { #[allow(non_snake_case)] - fn functor(&self, _this: Option, inputs: &[ConcreteTaskInput]) -> Result { - let ($($arg,)*) = $helper_module::get_args(inputs)?; + fn functor(&self, _this: Option, arg: &ConcreteTaskInput) -> Result { + #[allow(unused_parens)] + let ($($arg),*) = <($($arg),*) as TaskInput>::try_from_concrete(arg)?; let task_fn = self.clone(); - $( - let $arg = $arg::try_from_concrete($arg)?; - )* Ok(Box::new(move || { let task_fn = task_fn.clone(); @@ -221,13 +191,11 @@ macro_rules! task_fn_impl { Output: TaskOutput + 'static, { #[allow(non_snake_case)] - fn functor(&self, _this: Option, inputs: &[ConcreteTaskInput]) -> Result { - let ($($arg,)*) = $helper_module::get_args(inputs)?; + fn functor(&self, _this: Option, arg: &ConcreteTaskInput) -> Result { + #[allow(unused_parens)] + let ($($arg),*) = <($($arg),*) as TaskInput>::try_from_concrete(arg)?; let task_fn = self.clone(); - $( - let $arg = $arg::try_from_concrete($arg)?; - )* Ok(Box::new(move || { let task_fn = task_fn.clone(); @@ -250,14 +218,12 @@ macro_rules! task_fn_impl { Output: TaskOutput + 'static, { #[allow(non_snake_case)] - fn functor(&self, this: Option, inputs: &[ConcreteTaskInput]) -> Result { + fn functor(&self, this: Option, arg: &ConcreteTaskInput) -> Result { let task_fn = self.clone(); let recv = Vc::::from(this.expect("Method need to have a `self` argument")); - let ($($arg,)*) = $helper_module::get_args(inputs)?; - $( - let $arg = $arg::try_from_concrete($arg)?; - )* + #[allow(unused_parens)] + let ($($arg),*) = <($($arg),*) as TaskInput>::try_from_concrete(arg)?; Ok(Box::new(move || { let task_fn = task_fn.clone(); @@ -282,14 +248,12 @@ macro_rules! task_fn_impl { Output: TaskOutput + 'static, { #[allow(non_snake_case)] - fn functor(&self, this: Option, inputs: &[ConcreteTaskInput]) -> Result { + fn functor(&self, this: Option, arg: &ConcreteTaskInput) -> Result { let task_fn = self.clone(); let recv = Vc::::from(this.expect("Method need to have a `self` argument")); - let ($($arg,)*) = $helper_module::get_args(inputs)?; - $( - let $arg = $arg::try_from_concrete($arg)?; - )* + #[allow(unused_parens)] + let ($($arg),*) = <($($arg),*) as TaskInput>::try_from_concrete(arg)?; Ok(Box::new(move || { let task_fn = task_fn.clone(); @@ -326,14 +290,12 @@ macro_rules! task_fn_impl { F: for<'a> $async_fn_trait<&'a Recv, $($arg,)*> + Clone + Send + Sync + 'static, { #[allow(non_snake_case)] - fn functor(&self, this: Option, inputs: &[ConcreteTaskInput]) -> Result { + fn functor(&self, this: Option, arg: &ConcreteTaskInput) -> Result { let task_fn = self.clone(); let recv = Vc::::from(this.expect("Method need to have a `self` argument")); - let ($($arg,)*) = $helper_module::get_args(inputs)?; - $( - let $arg = $arg::try_from_concrete($arg)?; - )* + #[allow(unused_parens)] + let ($($arg),*) = <($($arg),*) as TaskInput>::try_from_concrete(arg)?; Ok(Box::new(move || { let task_fn = task_fn.clone(); @@ -357,14 +319,12 @@ macro_rules! task_fn_impl { F: $async_fn_trait, $($arg,)*> + Clone + Send + Sync + 'static, { #[allow(non_snake_case)] - fn functor(&self, this: Option, inputs: &[ConcreteTaskInput]) -> Result { + fn functor(&self, this: Option, arg: &ConcreteTaskInput) -> Result { let task_fn = self.clone(); let recv = Vc::::from(this.expect("Method need to have a `self` argument")); - let ($($arg,)*) = $helper_module::get_args(inputs)?; - $( - let $arg = $arg::try_from_concrete($arg)?; - )* + #[allow(unused_parens)] + let ($($arg),*) = <($($arg),*) as TaskInput>::try_from_concrete(arg)?; Ok(Box::new(move || { let task_fn = task_fn.clone(); @@ -381,23 +341,23 @@ macro_rules! task_fn_impl { }; } -task_fn_impl! { async_fn_0 AsyncFn0 0 } -task_fn_impl! { async_fn_1 AsyncFn1 1 A1 } -task_fn_impl! { async_fn_2 AsyncFn2 2 A1 A2 } -task_fn_impl! { async_fn_3 AsyncFn3 3 A1 A2 A3 } -task_fn_impl! { async_fn_4 AsyncFn4 4 A1 A2 A3 A4 } -task_fn_impl! { async_fn_5 AsyncFn5 5 A1 A2 A3 A4 A5 } -task_fn_impl! { async_fn_6 AsyncFn6 6 A1 A2 A3 A4 A5 A6 } -task_fn_impl! { async_fn_7 AsyncFn7 7 A1 A2 A3 A4 A5 A6 A7 } -task_fn_impl! { async_fn_8 AsyncFn8 8 A1 A2 A3 A4 A5 A6 A7 A8 } -task_fn_impl! { async_fn_9 AsyncFn9 9 A1 A2 A3 A4 A5 A6 A7 A8 A9 } -task_fn_impl! { async_fn_10 AsyncFn10 10 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 } -task_fn_impl! { async_fn_11 AsyncFn11 11 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 } -task_fn_impl! { async_fn_12 AsyncFn12 12 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 } -task_fn_impl! { async_fn_13 AsyncFn13 13 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 } -task_fn_impl! { async_fn_14 AsyncFn14 14 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 } -task_fn_impl! { async_fn_15 AsyncFn15 15 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 } -task_fn_impl! { async_fn_16 AsyncFn16 16 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 } +task_fn_impl! { AsyncFn0 0 } +task_fn_impl! { AsyncFn1 1 A1 } +task_fn_impl! { AsyncFn2 2 A1 A2 } +task_fn_impl! { AsyncFn3 3 A1 A2 A3 } +task_fn_impl! { AsyncFn4 4 A1 A2 A3 A4 } +task_fn_impl! { AsyncFn5 5 A1 A2 A3 A4 A5 } +task_fn_impl! { AsyncFn6 6 A1 A2 A3 A4 A5 A6 } +task_fn_impl! { AsyncFn7 7 A1 A2 A3 A4 A5 A6 A7 } +task_fn_impl! { AsyncFn8 8 A1 A2 A3 A4 A5 A6 A7 A8 } +task_fn_impl! { AsyncFn9 9 A1 A2 A3 A4 A5 A6 A7 A8 A9 } +task_fn_impl! { AsyncFn10 10 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 } +task_fn_impl! { AsyncFn11 11 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 } +task_fn_impl! { AsyncFn12 12 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 } +task_fn_impl! { AsyncFn13 13 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 } +task_fn_impl! { AsyncFn14 14 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 } +task_fn_impl! { AsyncFn15 15 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 } +task_fn_impl! { AsyncFn16 16 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 } // There needs to be one more implementation than task_fn_impl to account for // the receiver. @@ -420,14 +380,6 @@ task_inputs_impl! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 } task_inputs_impl! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 } task_inputs_impl! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 } -fn next_arg<'a>( - iter: &mut std::slice::Iter<'a, ConcreteTaskInput>, - arg_name: &'static str, -) -> Result<&'a ConcreteTaskInput> { - iter.next() - .with_context(move || format!("task is missing argument {}", arg_name)) -} - #[cfg(test)] mod tests { use super::*; diff --git a/crates/turbo-tasks/src/task/task_input.rs b/crates/turbo-tasks/src/task/task_input.rs index 87008c290eb34a..c1d45a7729275f 100644 --- a/crates/turbo-tasks/src/task/task_input.rs +++ b/crates/turbo-tasks/src/task/task_input.rs @@ -320,6 +320,19 @@ where } } +impl TaskInput for () { + fn try_from_concrete(input: &ConcreteTaskInput) -> Result { + match input { + ConcreteTaskInput::Nothing => Ok(()), + _ => bail!("invalid task input type, expected Nothing"), + } + } + + fn into_concrete(self) -> ConcreteTaskInput { + ConcreteTaskInput::Nothing + } +} + macro_rules! tuple_impls { ( $( $name:ident )+ ) => { impl<$($name: TaskInput),+> TaskInput for ($($name,)+) @@ -335,7 +348,7 @@ macro_rules! tuple_impls { )+ Ok(($($name,)+)) } - _ => bail!("invalid task input type, expected list"), + _ => bail!("invalid task input type {input:?}, expected tuple {}", stringify!(($($name,)+))), } } @@ -362,6 +375,10 @@ tuple_impls! { A B C D E F G H I } tuple_impls! { A B C D E F G H I J } tuple_impls! { A B C D E F G H I J K } tuple_impls! { A B C D E F G H I J K L } +tuple_impls! { A B C D E F G H I J K L M } +tuple_impls! { A B C D E F G H I J K L M N } +tuple_impls! { A B C D E F G H I J K L M N O } +tuple_impls! { A B C D E F G H I J K L M N O P} #[cfg(test)] mod tests {