diff --git a/turbopack/crates/turbo-tasks-backend/tests/operation_vc.rs b/turbopack/crates/turbo-tasks-backend/tests/operation_vc.rs new file mode 120000 index 0000000000000..0fe3b98a6abc6 --- /dev/null +++ b/turbopack/crates/turbo-tasks-backend/tests/operation_vc.rs @@ -0,0 +1 @@ +../../turbo-tasks-testing/tests/operation_vc.rs \ No newline at end of file diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method.stderr b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method.stderr deleted file mode 100644 index 7eb76986142c3..0000000000000 --- a/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method.stderr +++ /dev/null @@ -1,48 +0,0 @@ -error: methods taking `self` are not supported with `operation` - --> tests/function/fail_operation_method.rs:13:17 - | -13 | fn self_ref(&self) -> Vc<()> { - | ^^^^^ - -error: methods taking `self` are not supported with `operation` - --> tests/function/fail_operation_method.rs:18:28 - | -18 | fn arbitrary_self_type(self: OperationVc) -> Vc<()> { - | ^^^^^^^^^^^^^^^^^^^^^^^ - -error: methods taking `self` are not supported with `operation` - --> tests/function/fail_operation_method.rs:23:36 - | -23 | fn arbitrary_self_type_base_vc(self: Vc) -> Vc<()> { - | ^^^^^^^^^^^^^^ - -error[E0307]: invalid `self` parameter type: `OperationVc` - --> tests/function/fail_operation_method.rs:18:34 - | -18 | fn arbitrary_self_type(self: OperationVc) -> Vc<()> { - | ^^^^^^^^^^^^^^^^^ - | - = note: type of `self` must be `Self` or a type that dereferences to it - = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) - -error[E0277]: the trait bound `Vc: OperationValue` is not satisfied - --> tests/function/fail_operation_method.rs:23:42 - | -23 | fn arbitrary_self_type_base_vc(self: Vc) -> Vc<()> { - | ^^^^^^^^ the trait `OperationValue` is not implemented for `Vc` - | - = help: the following other types implement trait `OperationValue`: - &T - &mut T - () - (A, Z, Y, X, W, V, U, T) - (B, A, Z, Y, X, W, V, U, T) - (C, B, A, Z, Y, X, W, V, U, T) - (D, C, B, A, Z, Y, X, W, V, U, T) - (E, D, C, B, A, Z, Y, X, W, V, U, T) - and $N others -note: required by a bound in `assert_argument_is_operation_value` - --> $WORKSPACE/turbopack/crates/turbo-tasks/src/macro_helpers.rs - | - | pub fn assert_argument_is_operation_value() {} - | ^^^^^^^^^^^^^^ required by this bound in `assert_argument_is_operation_value` diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_ref.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_ref.rs new file mode 100644 index 0000000000000..0468a282a641a --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_ref.rs @@ -0,0 +1,18 @@ +#![allow(dead_code)] +#![feature(arbitrary_self_types)] +#![feature(arbitrary_self_types_pointers)] + +use turbo_tasks::Vc; + +#[turbo_tasks::value] +struct Foobar; + +#[turbo_tasks::value_impl] +impl Foobar { + #[turbo_tasks::function(operation)] + fn self_ref(&self) -> Vc<()> { + Vc::cell(()) + } +} + +fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_ref.stderr b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_ref.stderr new file mode 100644 index 0000000000000..9fb7a9cf20145 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_ref.stderr @@ -0,0 +1,5 @@ +error: methods taking `self` are not supported with `operation` + --> tests/function/fail_operation_method_self_ref.rs:13:17 + | +13 | fn self_ref(&self) -> Vc<()> { + | ^^^^^ diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_type.rs similarity index 60% rename from turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method.rs rename to turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_type.rs index 15fe791cbb3f5..b1ca57b83d0f4 100644 --- a/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method.rs +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_type.rs @@ -9,20 +9,10 @@ struct Foobar; #[turbo_tasks::value_impl] impl Foobar { - #[turbo_tasks::function(operation)] - fn self_ref(&self) -> Vc<()> { - Vc::cell(()) - } - #[turbo_tasks::function(operation)] fn arbitrary_self_type(self: OperationVc) -> Vc<()> { Vc::cell(()) } - - #[turbo_tasks::function(operation)] - fn arbitrary_self_type_base_vc(self: Vc) -> Vc<()> { - Vc::cell(()) - } } fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_type.stderr b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_type.stderr new file mode 100644 index 0000000000000..a57091f4d8046 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_type.stderr @@ -0,0 +1,37 @@ +error: methods taking `self` are not supported with `operation` + --> tests/function/fail_operation_method_self_type.rs:13:28 + | +13 | fn arbitrary_self_type(self: OperationVc) -> Vc<()> { + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0307]: invalid `self` parameter type: `OperationVc` + --> tests/function/fail_operation_method_self_type.rs:13:34 + | +13 | fn arbitrary_self_type(self: OperationVc) -> Vc<()> { + | ^^^^^^^^^^^^^^^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0277]: the trait bound `Foobar: NonLocalValue` is not satisfied + --> tests/function/fail_operation_method_self_type.rs:13:34 + | +13 | fn arbitrary_self_type(self: OperationVc) -> Vc<()> { + | ^^^^^^^^^^^^^^^^^ the trait `NonLocalValue` is not implemented for `Foobar`, which is required by `OperationVc: NonLocalValue` + | + = help: the following other types implement trait `NonLocalValue`: + &T + &mut T + () + (A, Z, Y, X, W, V, U, T) + (B, A, Z, Y, X, W, V, U, T) + (C, B, A, Z, Y, X, W, V, U, T) + (D, C, B, A, Z, Y, X, W, V, U, T) + (E, D, C, B, A, Z, Y, X, W, V, U, T) + and $N others + = note: required for `OperationVc` to implement `NonLocalValue` +note: required by a bound in `assert_argument_is_non_local_value` + --> $WORKSPACE/turbopack/crates/turbo-tasks/src/macro_helpers.rs + | + | pub fn assert_argument_is_non_local_value() {} + | ^^^^^^^^^^^^^ required by this bound in `assert_argument_is_non_local_value` diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_type_base_vc.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_type_base_vc.rs new file mode 100644 index 0000000000000..aff8c2ec0522c --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_type_base_vc.rs @@ -0,0 +1,18 @@ +#![allow(dead_code)] +#![feature(arbitrary_self_types)] +#![feature(arbitrary_self_types_pointers)] + +use turbo_tasks::Vc; + +#[turbo_tasks::value] +struct Foobar; + +#[turbo_tasks::value_impl] +impl Foobar { + #[turbo_tasks::function(operation)] + fn arbitrary_self_type_base_vc(self: Vc) -> Vc<()> { + Vc::cell(()) + } +} + +fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_type_base_vc.stderr b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_type_base_vc.stderr new file mode 100644 index 0000000000000..ff17cba4aaca0 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_method_self_type_base_vc.stderr @@ -0,0 +1,27 @@ +error: methods taking `self` are not supported with `operation` + --> tests/function/fail_operation_method_self_type_base_vc.rs:13:36 + | +13 | fn arbitrary_self_type_base_vc(self: Vc) -> Vc<()> { + | ^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `Vc: NonLocalValue` is not satisfied + --> tests/function/fail_operation_method_self_type_base_vc.rs:13:42 + | +13 | fn arbitrary_self_type_base_vc(self: Vc) -> Vc<()> { + | ^^^^^^^^ the trait `NonLocalValue` is not implemented for `Vc` + | + = help: the following other types implement trait `NonLocalValue`: + &T + &mut T + () + (A, Z, Y, X, W, V, U, T) + (B, A, Z, Y, X, W, V, U, T) + (C, B, A, Z, Y, X, W, V, U, T) + (D, C, B, A, Z, Y, X, W, V, U, T) + (E, D, C, B, A, Z, Y, X, W, V, U, T) + and $N others +note: required by a bound in `assert_argument_is_non_local_value` + --> $WORKSPACE/turbopack/crates/turbo-tasks/src/macro_helpers.rs + | + | pub fn assert_argument_is_non_local_value() {} + | ^^^^^^^^^^^^^ required by this bound in `assert_argument_is_non_local_value` diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_vc_arg.stderr b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_vc_arg.stderr index 5e1b622244445..401362a874dd8 100644 --- a/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_vc_arg.stderr +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/function/fail_operation_vc_arg.stderr @@ -1,10 +1,10 @@ -error[E0277]: the trait bound `Vc: OperationValue` is not satisfied +error[E0277]: the trait bound `Vc: NonLocalValue` is not satisfied --> tests/function/fail_operation_vc_arg.rs:7:26 | 7 | async fn multiply(value: Vc, coefficient: ResolvedVc) -> Result> { - | ^^^^^^^ the trait `OperationValue` is not implemented for `Vc` + | ^^^^^^^ the trait `NonLocalValue` is not implemented for `Vc` | - = help: the following other types implement trait `OperationValue`: + = help: the following other types implement trait `NonLocalValue`: &T &mut T () @@ -14,30 +14,8 @@ error[E0277]: the trait bound `Vc: OperationValue` is not satisfied (D, C, B, A, Z, Y, X, W, V, U, T) (E, D, C, B, A, Z, Y, X, W, V, U, T) and $N others -note: required by a bound in `assert_argument_is_operation_value` +note: required by a bound in `assert_argument_is_non_local_value` --> $WORKSPACE/turbopack/crates/turbo-tasks/src/macro_helpers.rs | - | pub fn assert_argument_is_operation_value() {} - | ^^^^^^^^^^^^^^ required by this bound in `assert_argument_is_operation_value` - -error[E0277]: the trait bound `ResolvedVc: OperationValue` is not satisfied - --> tests/function/fail_operation_vc_arg.rs:7:48 - | -7 | async fn multiply(value: Vc, coefficient: ResolvedVc) -> Result> { - | ^^^^^^^^^^^^^^^ the trait `OperationValue` is not implemented for `ResolvedVc` - | - = help: the following other types implement trait `OperationValue`: - &T - &mut T - () - (A, Z, Y, X, W, V, U, T) - (B, A, Z, Y, X, W, V, U, T) - (C, B, A, Z, Y, X, W, V, U, T) - (D, C, B, A, Z, Y, X, W, V, U, T) - (E, D, C, B, A, Z, Y, X, W, V, U, T) - and $N others -note: required by a bound in `assert_argument_is_operation_value` - --> $WORKSPACE/turbopack/crates/turbo-tasks/src/macro_helpers.rs - | - | pub fn assert_argument_is_operation_value() {} - | ^^^^^^^^^^^^^^ required by this bound in `assert_argument_is_operation_value` + | pub fn assert_argument_is_non_local_value() {} + | ^^^^^^^^^^^^^ required by this bound in `assert_argument_is_non_local_value` diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/function/pass_operation_accepts_resolved.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/function/pass_operation_accepts_resolved.rs new file mode 100644 index 0000000000000..9d3a1ee298b9f --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/function/pass_operation_accepts_resolved.rs @@ -0,0 +1,21 @@ +use anyhow::Result; +use turbo_tasks::{OperationVc, ResolvedVc, Vc}; + +#[turbo_tasks::function(operation)] +fn bare_op_fn() -> Vc { + Vc::cell(21) +} + +// operations can take `ResolvedVc`s too (anything that's a `NonLocalValue`). +#[turbo_tasks::function(operation)] +async fn multiply(value: OperationVc, coefficient: ResolvedVc) -> Result> { + Ok(Vc::cell((*value.connect().await?) * (*coefficient.await?))) +} + +#[allow(dead_code)] +fn use_operations() { + let twenty_one: OperationVc = bare_op_fn(); + let _fourty_two: OperationVc = multiply(twenty_one, ResolvedVc::cell(2)); +} + +fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros/src/func.rs b/turbopack/crates/turbo-tasks-macros/src/func.rs index 6e2313c5617d5..0e72c964ac3aa 100644 --- a/turbopack/crates/turbo-tasks-macros/src/func.rs +++ b/turbopack/crates/turbo-tasks-macros/src/func.rs @@ -301,7 +301,13 @@ impl TurboFn<'_> { subpat: None, })), colon_token: Default::default(), - ty: Box::new(expand_task_input_type(&input.ty).into_owned()), + ty: if self.operation { + // operations shouldn't have their arguments rewritten, they require all + // arguments are explicitly `NonLocalValue`s + Box::new(input.ty.clone()) + } else { + Box::new(expand_task_input_type(&input.ty).into_owned()) + }, }) }) .collect(); @@ -349,6 +355,11 @@ impl TurboFn<'_> { .map(|(idx, arg)| match arg { FnArg::Receiver(_) => (arg.clone(), None), FnArg::Typed(pat_type) => { + if self.operation { + // operations shouldn't have their arguments rewritten, they require all + // arguments are explicitly `NonLocalValue`s + return (arg.clone(), None); + } let Cow::Owned(expanded_ty) = expand_task_input_type(&pat_type.ty) else { // common-case: skip if no type conversion is needed return (arg.clone(), None); @@ -530,7 +541,7 @@ impl TurboFn<'_> { let ty = &pat_type.ty; assertions.push(quote_spanned! { ty.span() => - turbo_tasks::macro_helpers::assert_argument_is_operation_value::<#ty>(); + turbo_tasks::macro_helpers::assert_argument_is_non_local_value::<#ty>(); }); } } diff --git a/turbopack/crates/turbo-tasks-memory/tests/operation_vc.rs b/turbopack/crates/turbo-tasks-memory/tests/operation_vc.rs new file mode 120000 index 0000000000000..0fe3b98a6abc6 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/tests/operation_vc.rs @@ -0,0 +1 @@ +../../turbo-tasks-testing/tests/operation_vc.rs \ No newline at end of file diff --git a/turbopack/crates/turbo-tasks-testing/tests/operation_vc.rs b/turbopack/crates/turbo-tasks-testing/tests/operation_vc.rs new file mode 100644 index 0000000000000..d4cefdc009e4d --- /dev/null +++ b/turbopack/crates/turbo-tasks-testing/tests/operation_vc.rs @@ -0,0 +1,36 @@ +#![feature(arbitrary_self_types)] +#![feature(arbitrary_self_types_pointers)] +#![allow(clippy::needless_return)] // tokio macro-generated code doesn't respect this + +use anyhow::Result; +use turbo_tasks::{OperationVc, ResolvedVc, Vc}; +use turbo_tasks_testing::{register, run, Registration}; + +static REGISTRATION: Registration = register!(); + +#[turbo_tasks::function(operation)] +fn bare_op_fn() -> Vc { + Vc::cell(21) +} + +// operations can take `ResolvedVc`s too (anything that's a `NonLocalValue`). +#[turbo_tasks::function(operation)] +async fn multiply(value: OperationVc, coefficient: ResolvedVc) -> Result> { + Ok(Vc::cell((*value.connect().await?) * (*coefficient.await?))) +} + +#[turbo_tasks::function] +fn use_operations() -> Vc { + let twenty_one: OperationVc = bare_op_fn(); + let fourty_two: OperationVc = multiply(twenty_one, ResolvedVc::cell(2)); + fourty_two.connect() +} + +#[tokio::test] +async fn test_use_operations() -> Result<()> { + run(®ISTRATION, || async { + assert_eq!(*use_operations().await?, 42); + Ok(()) + }) + .await +} diff --git a/turbopack/crates/turbo-tasks/src/macro_helpers.rs b/turbopack/crates/turbo-tasks/src/macro_helpers.rs index 2b61170f938a2..1ccccdd660919 100644 --- a/turbopack/crates/turbo-tasks/src/macro_helpers.rs +++ b/turbopack/crates/turbo-tasks/src/macro_helpers.rs @@ -12,7 +12,7 @@ pub use super::{ }; use crate::{ debug::ValueDebugFormatString, shrink_to_fit::ShrinkToFit, task::TaskOutput, NonLocalValue, - OperationValue, RawVc, TaskInput, TaskPersistence, Vc, + RawVc, TaskInput, TaskPersistence, Vc, }; #[inline(never)] @@ -52,7 +52,7 @@ where { } -pub fn assert_argument_is_operation_value() {} +pub fn assert_argument_is_non_local_value() {} #[macro_export] macro_rules! stringify_path {