From 627eddd428ff21b50160c863f74a6e85771a2e3c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 5 Aug 2022 00:39:00 -0400 Subject: [PATCH] add a test for tracked functions --- Cargo.toml | 2 +- .../salsa-entity-macros/src/tracked_fn.rs | 23 ++++++++++- salsa-2022-tests/Cargo.toml | 16 ++++++++ salsa-2022-tests/main.rs | 6 +++ salsa-2022-tests/tracked_fn_on_input.rs | 38 +++++++++++++++++++ 5 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 salsa-2022-tests/Cargo.toml create mode 100644 salsa-2022-tests/main.rs create mode 100644 salsa-2022-tests/tracked_fn_on_input.rs diff --git a/Cargo.toml b/Cargo.toml index fa02203..df64ef8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,6 @@ parking_lot = "0.12.1" rustc-hash = "1.0" smallvec = "1.0.0" oorandom = "11" - salsa-macros = { version = "0.17.0-pre.2", path = "components/salsa-macros" } [dev-dependencies] @@ -37,4 +36,5 @@ members = [ "components/salsa-entity-mock", "components/salsa-entity-macros", "calc-example/calc", + "salsa-2022-tests" ] \ No newline at end of file diff --git a/components/salsa-entity-macros/src/tracked_fn.rs b/components/salsa-entity-macros/src/tracked_fn.rs index c1d9712..58d97d0 100644 --- a/components/salsa-entity-macros/src/tracked_fn.rs +++ b/components/salsa-entity-macros/src/tracked_fn.rs @@ -66,9 +66,10 @@ fn key_ty(item_fn: &syn::ItemFn) -> syn::Type { fn configuration_struct(item_fn: &syn::ItemFn) -> syn::ItemStruct { let fn_name = item_fn.sig.ident.clone(); let key_tuple_ty = key_ty(item_fn); + let visibility = &item_fn.vis; parse_quote! { #[allow(non_camel_case_types)] - pub struct #fn_name { + #visibility struct #fn_name { intern_map: salsa::interned::InternedIngredient, function: salsa::function::FunctionIngredient, } @@ -187,6 +188,7 @@ fn wrapper_fns( Ok((getter_fn, setter_impl)) } +/// Creates the `get` associated function. fn getter_fn( args: &Args, item_fn: &syn::ItemFn, @@ -224,6 +226,10 @@ fn getter_fn( Ok(getter_fn) } +/// Creates a `get` associated function that returns `&Value` +/// (to be used when `return_ref` is specified). +/// +/// (Helper for `getter_fn`) fn ref_getter_fn( args: &Args, item_fn: &syn::ItemFn, @@ -247,6 +253,8 @@ fn ref_getter_fn( Ok(ref_getter_fn) } +/// Creates a `set` associated function that can be used to set (given an `&mut db`) +/// the value for this function for some inputs. fn setter_fn( args: &Args, item_fn: &syn::ItemFn, @@ -288,6 +296,9 @@ fn setter_fn( }) } +/// Given a function def tagged with `#[return_ref]`, modifies `ref_getter_fn` +/// so that it returns an `&Value` instead of `Value`. May introduce a name for the +/// database lifetime if required. fn make_fn_return_ref(mut ref_getter_fn: syn::ItemFn) -> syn::Result { // The 0th input should be a `&dyn Foo`. We need to ensure // it has a named lifetime parameter. @@ -313,6 +324,9 @@ fn make_fn_return_ref(mut ref_getter_fn: syn::ItemFn) -> syn::Result syn::Result<(syn::Lifetime, &syn::Type)> { match &mut func.sig.inputs[0] { syn::FnArg::Receiver(r) => { @@ -355,6 +369,9 @@ fn db_lifetime_and_ty(func: &mut syn::ItemFn) -> syn::Result<(syn::Lifetime, &sy } } +/// Generates the `accumulated` function, which invokes `accumulated` +/// on the function ingredient to extract the values pushed (transitively) +/// into an accumulator. fn accumulated_fn( args: &Args, item_fn: &syn::ItemFn, @@ -393,6 +410,10 @@ fn accumulated_fn( Ok(accumulated_fn) } +/// Examines the function arguments and returns a tuple of: +/// +/// * the name of the database argument +/// * the name(s) of the key arguments fn fn_args(item_fn: &syn::ItemFn) -> syn::Result<(proc_macro2::Ident, Vec)> { // Check that we have no receiver and that all argments have names if item_fn.sig.inputs.len() == 0 { diff --git a/salsa-2022-tests/Cargo.toml b/salsa-2022-tests/Cargo.toml new file mode 100644 index 0000000..9631e08 --- /dev/null +++ b/salsa-2022-tests/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "salsa-2022-tests" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +salsa = { path = "../components/salsa-entity-mock", package = "salsa-entity-mock" } + +[dev-dependencies] +expect-test = "1.4.0" + +[[bin]] +name = "salsa-2022-tests" +path = "main.rs" diff --git a/salsa-2022-tests/main.rs b/salsa-2022-tests/main.rs new file mode 100644 index 0000000..7c3bca4 --- /dev/null +++ b/salsa-2022-tests/main.rs @@ -0,0 +1,6 @@ +//! This crate has the beginning of various unit tests on salsa 2022 +//! code. + +mod tracked_fn_on_input; + +fn main() {} diff --git a/salsa-2022-tests/tracked_fn_on_input.rs b/salsa-2022-tests/tracked_fn_on_input.rs new file mode 100644 index 0000000..cb98960 --- /dev/null +++ b/salsa-2022-tests/tracked_fn_on_input.rs @@ -0,0 +1,38 @@ +//! Test that a `tracked` fn on a `salsa::input` +//! compiles and executes successfully. + +#[salsa::jar(db = Db)] +struct Jar(MyInput, tracked_fn); + +trait Db: salsa::DbWithJar {} + +#[salsa::input(jar = Jar)] +struct MyInput { + field: u32, +} + +#[salsa::tracked(jar = Jar)] +fn tracked_fn(db: &dyn Db, input: MyInput) -> u32 { + input.field(db) * 2 +} + +#[test] +fn execute() { + #[salsa::db(Jar)] + #[derive(Default)] + struct Database { + storage: salsa::Storage, + } + + impl salsa::Database for Database { + fn salsa_runtime(&self) -> &salsa::Runtime { + self.storage.runtime() + } + } + + impl Db for Database {} + + let mut db = Database::default(); + let input = MyInput::new(&mut db, 22); + assert_eq!(tracked_fn(&db, input), 44); +}