diff --git a/components/salsa-macros/src/tracked_fn.rs b/components/salsa-macros/src/tracked_fn.rs index c01056e..e105c40 100644 --- a/components/salsa-macros/src/tracked_fn.rs +++ b/components/salsa-macros/src/tracked_fn.rs @@ -304,7 +304,7 @@ impl Macro { fn cycle_recovery(&self) -> (TokenStream, TokenStream) { if let Some(recovery_fn) = &self.args.recovery_fn { - (recovery_fn.to_token_stream(), quote!(Fallback)) + (quote!((#recovery_fn)), quote!(Fallback)) } else { ( quote!((salsa::plumbing::unexpected_cycle_recovery!)), diff --git a/src/database.rs b/src/database.rs index e7413ed..ad6e24b 100644 --- a/src/database.rs +++ b/src/database.rs @@ -33,6 +33,14 @@ pub trait Database: DatabaseGen { fn report_untracked_read(&self) { self.runtime().report_untracked_read(); } + + /// Execute `op` with the database in thread-local storage for debug print-outs. + fn attach(&self, op: impl FnOnce(&Self) -> R) -> R + where + Self: Sized, + { + attach_database(self, || op(self)) + } } thread_local! { diff --git a/tests/accumulate-from-tracked-fn.rs b/tests/accumulate-from-tracked-fn.rs index c66ac42..f79800f 100644 --- a/tests/accumulate-from-tracked-fn.rs +++ b/tests/accumulate-from-tracked-fn.rs @@ -6,6 +6,7 @@ mod common; use common::{HasLogger, Logger}; use expect_test::expect; +use salsa::{Accumulator, Setter}; use test_log::test; #[salsa::db] @@ -18,6 +19,7 @@ struct List { } #[salsa::accumulator] +#[derive(Copy, Clone, Debug)] struct Integers(u32); #[salsa::tracked] @@ -31,13 +33,13 @@ fn compute(db: &dyn Db, input: List) { let result = if let Some(next) = input.next(db) { let next_integers = compute::accumulated::(db, next); eprintln!("{:?}", next_integers); - let v = input.value(db) + next_integers.iter().sum::(); + let v = input.value(db) + next_integers.iter().map(|a| a.0).sum::(); eprintln!("input={:?} v={:?}", input.value(db), v); v } else { input.value(db) }; - Integers::push(db, result); + Integers(result).accumulate(db); eprintln!("pushed result {:?}", result); } diff --git a/tests/accumulate-reuse-workaround.rs b/tests/accumulate-reuse-workaround.rs index 8289b50..bb496f9 100644 --- a/tests/accumulate-reuse-workaround.rs +++ b/tests/accumulate-reuse-workaround.rs @@ -6,12 +6,11 @@ mod common; use common::{HasLogger, Logger}; use expect_test::expect; +use salsa::{Accumulator, Setter}; use test_log::test; -#[salsa::jar(db = Db)] -struct Jar(List, Integers, compute, accumulated); - -trait Db: salsa::DbWithJar + HasLogger {} +#[salsa::db] +trait Db: salsa::Database + HasLogger {} #[salsa::input] struct List { @@ -20,6 +19,7 @@ struct List { } #[salsa::accumulator] +#[derive(Clone, Copy, Debug)] struct Integers(u32); #[salsa::tracked] @@ -27,7 +27,7 @@ fn compute(db: &dyn Db, input: List) -> u32 { db.push_log(format!("compute({:?})", input,)); // always pushes 0 - Integers::push(db, 0); + Integers(0).accumulate(db); let result = if let Some(next) = input.next(db) { let next_integers = accumulated(db, next); @@ -45,19 +45,24 @@ fn compute(db: &dyn Db, input: List) -> u32 { fn accumulated(db: &dyn Db, input: List) -> Vec { db.push_log(format!("accumulated({:?})", input,)); compute::accumulated::(db, input) + .into_iter() + .map(|a| a.0) + .collect() } -#[salsa::db(Jar)] +#[salsa::db] #[derive(Default)] struct Database { storage: salsa::Storage, logger: Logger, } +#[salsa::db] impl salsa::Database for Database { fn salsa_event(&self, _event: salsa::Event) {} } +#[salsa::db] impl Db for Database {} impl HasLogger for Database { diff --git a/tests/accumulate-reuse.rs b/tests/accumulate-reuse.rs index 3f83d51..492f342 100644 --- a/tests/accumulate-reuse.rs +++ b/tests/accumulate-reuse.rs @@ -79,7 +79,7 @@ fn test1() { // When we mutate `l1`, we should re-execute `compute` for `l1`, // but we should not have to re-execute `compute` for `l2`. - // The only inpout for `compute(l1)` is the accumulated values from `l1`, + // The only input for `compute(l1)` is the accumulated values from `l1`, // which have not changed. l1.set_value(&mut db).to(2); assert_eq!(compute(&db, l2), 2); diff --git a/tests/accumulate.rs b/tests/accumulate.rs index cef66ea..4a6d94a 100644 --- a/tests/accumulate.rs +++ b/tests/accumulate.rs @@ -6,12 +6,11 @@ mod common; use common::{HasLogger, Logger}; use expect_test::expect; +use salsa::{Accumulator, Setter}; use test_log::test; -#[salsa::jar(db = Db)] -struct Jar(MyInput, Logs, push_logs, push_a_logs, push_b_logs); - -trait Db: salsa::DbWithJar + HasLogger {} +#[salsa::db] +trait Db: salsa::Database + HasLogger {} #[salsa::input] struct MyInput { @@ -20,6 +19,7 @@ struct MyInput { } #[salsa::accumulator] +#[derive(Clone, Debug)] struct Logs(String); #[salsa::tracked] @@ -48,7 +48,7 @@ fn push_a_logs(db: &dyn Db, input: MyInput) { db.push_log(format!("push_a_logs({})", field_a)); for i in 0..field_a { - Logs::push(db, format!("log_a({} of {})", i, field_a)); + Logs(format!("log_a({} of {})", i, field_a)).accumulate(db); } } @@ -58,21 +58,23 @@ fn push_b_logs(db: &dyn Db, input: MyInput) { db.push_log(format!("push_b_logs({})", field_a)); for i in 0..field_a { - Logs::push(db, format!("log_b({} of {})", i, field_a)); + Logs(format!("log_b({} of {})", i, field_a)).accumulate(db); } } -#[salsa::db(Jar)] +#[salsa::db] #[derive(Default)] struct Database { storage: salsa::Storage, logger: Logger, } +#[salsa::db] impl salsa::Database for Database { fn salsa_event(&self, _event: salsa::Event) {} } +#[salsa::db] impl Db for Database {} impl HasLogger for Database { diff --git a/tests/compile-fail/accumulator_fields_incompatibles.rs b/tests/compile-fail/accumulator_fields_incompatibles.rs index b4371a7..cdfc870 100644 --- a/tests/compile-fail/accumulator_fields_incompatibles.rs +++ b/tests/compile-fail/accumulator_fields_incompatibles.rs @@ -4,12 +4,12 @@ struct Jar(AccTwoUnnamedFields, AccNamedField); trait Db: salsa::DbWithJar {} // accumulator with more than one unnamed fields -#[salsa::accumulator(jar = Jar)] +#[salsa::accumulator] struct AccTwoUnnamedFields (u32, u32); // accumulator with named fields -#[salsa::accumulator(jar = Jar)] +#[salsa::accumulator] struct AccNamedField { field: u32, } diff --git a/tests/compile-fail/get-set-on-private-field.rs b/tests/compile-fail/get-set-on-private-field.rs index d8e9bbb..7fd7791 100644 --- a/tests/compile-fail/get-set-on-private-field.rs +++ b/tests/compile-fail/get-set-on-private-field.rs @@ -4,7 +4,7 @@ pub struct Jar(a::MyInput); mod a { use crate::Jar; - #[salsa::input(jar = Jar)] + #[salsa::input] pub struct MyInput { field: u32, } diff --git a/tests/compile-fail/input_struct_id_fields_no_setters.rs b/tests/compile-fail/input_struct_id_fields_no_setters.rs index 6f808de..59c4959 100644 --- a/tests/compile-fail/input_struct_id_fields_no_setters.rs +++ b/tests/compile-fail/input_struct_id_fields_no_setters.rs @@ -1,10 +1,9 @@ - #[salsa::jar(db = Db)] struct Jar(MyInput); trait Db: salsa::DbWithJar {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: u32, #[id] @@ -21,11 +20,10 @@ impl salsa::Database for Database {} impl Db for Database {} - fn main() { let mut db = Database::default(); let input = MyInput::new(&mut db, 3, 4); // should not compile as `id_one` should not have a setter // compile error: method `set_id_one` not found in scope input.set_id_one(1); -} \ No newline at end of file +} diff --git a/tests/compile-fail/lru_can_not_be_used_with_specify.rs b/tests/compile-fail/lru_can_not_be_used_with_specify.rs index e025b00..528d216 100644 --- a/tests/compile-fail/lru_can_not_be_used_with_specify.rs +++ b/tests/compile-fail/lru_can_not_be_used_with_specify.rs @@ -3,7 +3,7 @@ struct Jar(MyInput, lru_can_not_be_used_with_specify); trait Db: salsa::DbWithJar {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: u32, } diff --git a/tests/compile-fail/panic-when-reading-fields-of-tracked-structs-from-older-revisions.rs b/tests/compile-fail/panic-when-reading-fields-of-tracked-structs-from-older-revisions.rs index 6a973a3..3e02641 100644 --- a/tests/compile-fail/panic-when-reading-fields-of-tracked-structs-from-older-revisions.rs +++ b/tests/compile-fail/panic-when-reading-fields-of-tracked-structs-from-older-revisions.rs @@ -5,17 +5,17 @@ struct Jar(MyInput, MyTracked<'_>, tracked_fn); trait Db: salsa::DbWithJar {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] struct MyTracked<'db> { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn tracked_fn<'db>(db: &'db dyn Db, input: MyInput) -> MyTracked<'db> { MyTracked::new(db, input.field(db) / 2) } diff --git a/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-input.rs b/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-input.rs index 981bc40..cd30abb 100644 --- a/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-input.rs +++ b/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-input.rs @@ -7,12 +7,12 @@ struct Jar(MyInput, MyTracked<'_>, tracked_fn); trait Db: salsa::DbWithJar {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] struct MyTracked<'db> { field: u32, } diff --git a/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-interned.rs b/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-interned.rs index eaa56c6..3aebde2 100644 --- a/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-interned.rs +++ b/tests/compile-fail/specify-does-not-work-if-the-key-is-a-salsa-interned.rs @@ -7,12 +7,12 @@ struct Jar(MyInterned<'_>, MyTracked<'_>, tracked_fn); trait Db: salsa::DbWithJar {} -#[salsa::interned(jar = Jar)] +#[salsa::interned] struct MyInterned<'db> { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] struct MyTracked<'db> { field: u32, } diff --git a/tests/compile-fail/tracked_fn_incompatibles.rs b/tests/compile-fail/tracked_fn_incompatibles.rs index 3fcc928..0c1c7f4 100644 --- a/tests/compile-fail/tracked_fn_incompatibles.rs +++ b/tests/compile-fail/tracked_fn_incompatibles.rs @@ -11,7 +11,7 @@ struct Jar( trait Db: salsa::DbWithJar {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: u32, } @@ -31,10 +31,10 @@ fn tracked_fn_with_constructor(db: &dyn Db, input: MyInput) -> u32 { input.field(db) * 2 } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn tracked_fn_with_one_input(db: &dyn Db) -> u32 {} -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn tracked_fn_with_receiver_not_applied_to_impl_block(&self, db: &dyn Db) -> u32 {} #[salsa::tracked(jar = Jar, specify)] diff --git a/tests/compile-fail/tracked_fn_incompatibles.stderr b/tests/compile-fail/tracked_fn_incompatibles.stderr index 46f1973..3add9ce 100644 --- a/tests/compile-fail/tracked_fn_incompatibles.stderr +++ b/tests/compile-fail/tracked_fn_incompatibles.stderr @@ -46,7 +46,7 @@ error[E0412]: cannot find type `tracked_fn_with_constructor` in this scope 6 | tracked_fn_with_constructor, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a struct with a similar name exists: `tracked_fn_with_one_input` ... -34 | #[salsa::tracked(jar = Jar)] +34 | #[salsa::tracked] | ---------------------------- similarly named struct `tracked_fn_with_one_input` defined here error[E0412]: cannot find type `tracked_fn_with_receiver_not_applied_to_impl_block` in this scope diff --git a/tests/compile-fail/tracked_method_incompatibles.rs b/tests/compile-fail/tracked_method_incompatibles.rs index a3d1354..9a112bf 100644 --- a/tests/compile-fail/tracked_method_incompatibles.rs +++ b/tests/compile-fail/tracked_method_incompatibles.rs @@ -1,7 +1,7 @@ #[salsa::jar(db = Db)] struct Jar(Tracked<'_>); -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] struct Tracked<'db> { field: u32, } diff --git a/tests/create-empty-database.rs b/tests/create-empty-database.rs deleted file mode 100644 index a417d88..0000000 --- a/tests/create-empty-database.rs +++ /dev/null @@ -1,36 +0,0 @@ -//! Tests that we can create a database of only 0-size jars without invoking UB - -use salsa::storage::HasJars; - -#[salsa::jar(db = Db)] -struct Jar(); - -trait Db: salsa::DbWithJar {} - -#[salsa::db(Jar)] -#[derive(Default)] -struct Database { - storage: salsa::Storage, -} - -impl salsa::Database for Database {} - -impl Db for Database {} - -#[test] -fn execute() { - let db = Database::default(); - let jars = db.storage.jars().0; - - ensure_init(jars); -} - -fn ensure_init(place: *const ::Jars) { - use std::mem::forget; - use std::ptr::addr_of; - - // SAFETY: Intentionally tries to access potentially uninitialized memory, - // so that miri can catch if we accidentally forget to initialize the memory. - #[allow(clippy::forget_non_drop)] - forget(unsafe { addr_of!((*place).0).read() }); -} diff --git a/tests/create-large-jar-database.rs b/tests/create-large-jar-database.rs deleted file mode 100644 index b444d6b..0000000 --- a/tests/create-large-jar-database.rs +++ /dev/null @@ -1,154 +0,0 @@ -//! Tests that we can create a database with very large jars without invoking UB - -use salsa::storage::HasJars; - -#[salsa::db(jar1::Jar1, jar2::Jar2, jar3::Jar3, jar4::Jar4)] -#[derive(Default)] -struct Database { - storage: salsa::Storage, -} - -impl salsa::Database for Database {} - -#[test] -fn execute() { - let db = Database::default(); - let jars = db.storage.jars().0; - - ensure_init(jars); -} - -fn ensure_init(place: *const ::Jars) { - use std::mem::forget; - use std::ptr::addr_of; - - // SAFETY: Intentionally tries to access potentially uninitialized memory, - // so that miri can catch if we accidentally forget to initialize the memory. - forget(unsafe { addr_of!((*place).0).read() }); - forget(unsafe { addr_of!((*place).1).read() }); - forget(unsafe { addr_of!((*place).2).read() }); - forget(unsafe { addr_of!((*place).3).read() }); -} - -macro_rules! make_jarX { - ($jarX:ident, $JarX:ident) => { - mod $jarX { - #[salsa::jar(db = Db)] - pub(crate) struct $JarX(T1<'_>); - - pub(crate) trait Db: salsa::DbWithJar<$JarX> {} - - impl Db for DB where DB: salsa::DbWithJar<$JarX> {} - - #[salsa::tracked(jar = $JarX)] - struct T1<'db> { - a0: String, - a1: String, - a2: String, - a3: String, - a4: String, - a5: String, - a6: String, - a7: String, - a8: String, - a9: String, - a10: String, - a11: String, - a12: String, - a13: String, - a14: String, - a15: String, - a16: String, - a17: String, - a18: String, - a19: String, - a20: String, - a21: String, - a22: String, - a23: String, - a24: String, - a25: String, - a26: String, - a27: String, - a28: String, - a29: String, - a30: String, - a31: String, - a32: String, - a33: String, - a34: String, - a35: String, - a36: String, - a37: String, - a38: String, - a39: String, - a40: String, - a41: String, - a42: String, - a43: String, - a44: String, - a45: String, - a46: String, - a47: String, - a48: String, - a49: String, - a50: String, - a51: String, - a52: String, - a53: String, - a54: String, - a55: String, - a56: String, - a57: String, - a58: String, - a59: String, - a60: String, - a61: String, - a62: String, - a63: String, - a64: String, - a65: String, - a66: String, - a67: String, - a68: String, - a69: String, - a70: String, - a71: String, - a72: String, - a73: String, - a74: String, - a75: String, - a76: String, - a77: String, - a78: String, - a79: String, - a80: String, - a81: String, - a82: String, - a83: String, - a84: String, - a85: String, - a86: String, - a87: String, - a88: String, - a89: String, - a90: String, - a91: String, - a92: String, - a93: String, - a94: String, - a95: String, - a96: String, - a97: String, - a98: String, - a99: String, - a100: String, - } - } - }; -} - -make_jarX!(jar1, Jar1); -make_jarX!(jar2, Jar2); -make_jarX!(jar3, Jar3); -make_jarX!(jar4, Jar4); diff --git a/tests/cycles.rs b/tests/cycles.rs index 7dc1289..16d28e2 100644 --- a/tests/cycles.rs +++ b/tests/cycles.rs @@ -56,53 +56,40 @@ struct Error { cycle: Vec, } -#[salsa::jar(db = Db)] -struct Jar( - MyInput, - memoized_a, - memoized_b, - volatile_a, - volatile_b, - ABC, - cycle_a, - cycle_b, - cycle_c, -); +use salsa::Database as Db; +use salsa::Setter; -trait Db: salsa::DbWithJar {} - -#[salsa::db(Jar)] +#[salsa::db] #[derive(Default)] struct Database { storage: salsa::Storage, } -impl Db for Database {} - +#[salsa::db] impl salsa::Database for Database {} impl RefUnwindSafe for Database {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput {} -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn memoized_a(db: &dyn Db, input: MyInput) { memoized_b(db, input) } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn memoized_b(db: &dyn Db, input: MyInput) { memoized_a(db, input) } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn volatile_a(db: &dyn Db, input: MyInput) { db.report_untracked_read(); volatile_b(db, input) } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn volatile_b(db: &dyn Db, input: MyInput) { db.report_untracked_read(); volatile_a(db, input) @@ -120,7 +107,7 @@ enum CycleQuery { AthenC, } -#[salsa::input(jar = Jar)] +#[salsa::input] struct ABC { a: CycleQuery, b: CycleQuery, @@ -142,29 +129,29 @@ impl CycleQuery { } } -#[salsa::tracked(jar = Jar, recovery_fn=recover_a)] +#[salsa::tracked(recovery_fn=recover_a)] fn cycle_a(db: &dyn Db, abc: ABC) -> Result<(), Error> { abc.a(db).invoke(db, abc) } fn recover_a(db: &dyn Db, cycle: &salsa::Cycle, abc: ABC) -> Result<(), Error> { Err(Error { - cycle: cycle.all_participants(db), + cycle: cycle.participant_keys().map(|k| format!("{k:?}")).collect(), }) } -#[salsa::tracked(jar = Jar, recovery_fn=recover_b)] +#[salsa::tracked(recovery_fn=recover_b)] fn cycle_b(db: &dyn Db, abc: ABC) -> Result<(), Error> { abc.b(db).invoke(db, abc) } fn recover_b(db: &dyn Db, cycle: &salsa::Cycle, abc: ABC) -> Result<(), Error> { Err(Error { - cycle: cycle.all_participants(db), + cycle: cycle.participant_keys().map(|k| format!("{k:?}")).collect(), }) } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn cycle_c(db: &dyn Db, abc: ABC) -> Result<(), Error> { abc.c(db).invoke(db, abc) } @@ -182,30 +169,32 @@ fn extract_cycle(f: impl FnOnce() + UnwindSafe) -> salsa::Cycle { #[test] fn cycle_memoized() { - let mut db = Database::default(); - let input = MyInput::new(&db); - let cycle = extract_cycle(|| memoized_a(&db, input)); - let expected = expect![[r#" - [ - "memoized_a(0)", - "memoized_b(0)", - ] - "#]]; - expected.assert_debug_eq(&cycle.all_participants(&db)); + Database::default().attach(|db| { + let input = MyInput::new(db); + let cycle = extract_cycle(|| memoized_a(db, input)); + let expected = expect![[r#" + [ + memoized_a(0), + memoized_b(0), + ] + "#]]; + expected.assert_debug_eq(&cycle.all_participants(db)); + }) } #[test] fn cycle_volatile() { - let mut db = Database::default(); - let input = MyInput::new(&db); - let cycle = extract_cycle(|| volatile_a(&db, input)); - let expected = expect![[r#" - [ - "volatile_a(0)", - "volatile_b(0)", - ] - "#]]; - expected.assert_debug_eq(&cycle.all_participants(&db)); + Database::default().attach(|db| { + let input = MyInput::new(db); + let cycle = extract_cycle(|| volatile_a(db, input)); + let expected = expect![[r#" + [ + volatile_a(0), + volatile_b(0), + ] + "#]]; + expected.assert_debug_eq(&cycle.all_participants(db)); + }); } #[test] @@ -214,9 +203,10 @@ fn expect_cycle() { // ^ | // +-----+ - let mut db = Database::default(); - let abc = ABC::new(&db, CycleQuery::B, CycleQuery::A, CycleQuery::None); - assert!(cycle_a(&db, abc).is_err()); + Database::default().attach(|db| { + let abc = ABC::new(db, CycleQuery::B, CycleQuery::A, CycleQuery::None); + assert!(cycle_a(db, abc).is_err()); + }) } #[test] @@ -224,17 +214,18 @@ fn inner_cycle() { // A --> B <-- C // ^ | // +-----+ - let mut db = Database::default(); - let abc = ABC::new(&db, CycleQuery::B, CycleQuery::A, CycleQuery::B); - let err = cycle_c(&db, abc); - assert!(err.is_err()); - let expected = expect![[r#" - [ - "cycle_a(0)", - "cycle_b(0)", - ] - "#]]; - expected.assert_debug_eq(&err.unwrap_err().cycle); + Database::default().attach(|db| { + let abc = ABC::new(db, CycleQuery::B, CycleQuery::A, CycleQuery::B); + let err = cycle_c(db, abc); + assert!(err.is_err()); + let expected = expect![[r#" + [ + "cycle_b(0)", + "cycle_a(0)", + ] + "#]]; + expected.assert_debug_eq(&err.unwrap_err().cycle); + }) } #[test] @@ -329,40 +320,40 @@ fn cycle_disappears_durability() { #[test] fn cycle_mixed_1() { - let mut db = Database::default(); + Database::default().attach(|db| { + // A --> B <-- C + // | ^ + // +-----+ + let abc = ABC::new(db, CycleQuery::B, CycleQuery::C, CycleQuery::B); - // A --> B <-- C - // | ^ - // +-----+ - let abc = ABC::new(&db, CycleQuery::B, CycleQuery::C, CycleQuery::B); - - let expected = expect![[r#" - [ - "cycle_b(0)", - "cycle_c(0)", - ] - "#]]; - expected.assert_debug_eq(&cycle_c(&db, abc).unwrap_err().cycle); + let expected = expect![[r#" + [ + "cycle_c(0)", + "cycle_b(0)", + ] + "#]]; + expected.assert_debug_eq(&cycle_c(db, abc).unwrap_err().cycle); + }) } #[test] fn cycle_mixed_2() { - let mut db = Database::default(); - - // Configuration: - // - // A --> B --> C - // ^ | - // +-----------+ - let abc = ABC::new(&db, CycleQuery::B, CycleQuery::C, CycleQuery::A); - let expected = expect![[r#" + Database::default().attach(|db| { + // Configuration: + // + // A --> B --> C + // ^ | + // +-----------+ + let abc = ABC::new(db, CycleQuery::B, CycleQuery::C, CycleQuery::A); + let expected = expect![[r#" [ "cycle_a(0)", "cycle_b(0)", "cycle_c(0)", ] "#]]; - expected.assert_debug_eq(&cycle_a(&db, abc).unwrap_err().cycle); + expected.assert_debug_eq(&cycle_a(db, abc).unwrap_err().cycle); + }) } #[test] @@ -388,8 +379,8 @@ fn cycle_deterministic_order() { "cycle_b(0)", ], [ - "cycle_a(0)", "cycle_b(0)", + "cycle_a(0)", ], ) "#]]; @@ -441,19 +432,19 @@ fn cycle_multiple() { #[test] fn cycle_recovery_set_but_not_participating() { - let mut db = Database::default(); + Database::default().attach(|db| { + // A --> C -+ + // ^ | + // +--+ + let abc = ABC::new(db, CycleQuery::C, CycleQuery::None, CycleQuery::C); - // A --> C -+ - // ^ | - // +--+ - let abc = ABC::new(&db, CycleQuery::C, CycleQuery::None, CycleQuery::C); - - // Here we expect C to panic and A not to recover: - let r = extract_cycle(|| drop(cycle_a(&db, abc))); - let expected = expect![[r#" - [ - "cycle_c(0)", - ] - "#]]; - expected.assert_debug_eq(&r.all_participants(&db)); + // Here we expect C to panic and A not to recover: + let r = extract_cycle(|| drop(cycle_a(db, abc))); + let expected = expect![[r#" + [ + cycle_c(0), + ] + "#]]; + expected.assert_debug_eq(&r.all_participants(db)); + }) } diff --git a/tests/expect_reuse_field_x_of_a_tracked_struct_changes_but_fn_depends_on_field_y.rs b/tests/expect_reuse_field_x_of_a_tracked_struct_changes_but_fn_depends_on_field_y.rs index dab6c0f..de0c409 100644 --- a/tests/expect_reuse_field_x_of_a_tracked_struct_changes_but_fn_depends_on_field_y.rs +++ b/tests/expect_reuse_field_x_of_a_tracked_struct_changes_but_fn_depends_on_field_y.rs @@ -19,30 +19,30 @@ struct Jar( trait Db: salsa::DbWithJar + HasLogger {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn final_result_depends_on_x(db: &dyn Db, input: MyInput) -> u32 { db.push_log(format!("final_result_depends_on_x({:?})", input)); intermediate_result(db, input).x(db) * 2 } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn final_result_depends_on_y(db: &dyn Db, input: MyInput) -> u32 { db.push_log(format!("final_result_depends_on_y({:?})", input)); intermediate_result(db, input).y(db) * 2 } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] struct MyTracked<'db> { x: u32, y: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn intermediate_result<'db>(db: &'db dyn Db, input: MyInput) -> MyTracked<'db> { MyTracked::new(db, (input.field(db) + 1) / 2, input.field(db) / 2) } diff --git a/tests/expect_reuse_field_x_of_an_input_changes_but_fn_depends_on_field_y.rs b/tests/expect_reuse_field_x_of_an_input_changes_but_fn_depends_on_field_y.rs index 7664344..a304f2b 100644 --- a/tests/expect_reuse_field_x_of_an_input_changes_but_fn_depends_on_field_y.rs +++ b/tests/expect_reuse_field_x_of_an_input_changes_but_fn_depends_on_field_y.rs @@ -13,19 +13,19 @@ struct Jar(MyInput, result_depends_on_x, result_depends_on_y); trait Db: salsa::DbWithJar + HasLogger {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { x: u32, y: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn result_depends_on_x(db: &dyn Db, input: MyInput) -> u32 { db.push_log(format!("result_depends_on_x({:?})", input)); input.x(db) + 1 } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn result_depends_on_y(db: &dyn Db, input: MyInput) -> u32 { db.push_log(format!("result_depends_on_y({:?})", input)); input.y(db) - 1 diff --git a/tests/input_with_ids.rs b/tests/input_with_ids.rs index 3656c8e..6844a27 100644 --- a/tests/input_with_ids.rs +++ b/tests/input_with_ids.rs @@ -11,7 +11,7 @@ trait Db: salsa::DbWithJar {} #[derive(Clone, Debug)] struct Field {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { #[id] id_one: u32, diff --git a/tests/lru.rs b/tests/lru.rs index 51fb625..f7545b7 100644 --- a/tests/lru.rs +++ b/tests/lru.rs @@ -36,7 +36,7 @@ impl Drop for HotPotato { } } -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: u32, } @@ -47,7 +47,7 @@ fn get_hot_potato(db: &dyn Db, input: MyInput) -> Arc { Arc::new(HotPotato::new(input.field(db))) } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn get_hot_potato2(db: &dyn Db, input: MyInput) -> u32 { db.push_log(format!("get_hot_potato2({:?})", input.field(db))); get_hot_potato(db, input).0 diff --git a/tests/mutate_in_place.rs b/tests/mutate_in_place.rs index 3232762..f0bb9b1 100644 --- a/tests/mutate_in_place.rs +++ b/tests/mutate_in_place.rs @@ -11,7 +11,7 @@ struct Jar(MyInput); trait Db: salsa::DbWithJar + HasLogger {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: String, } diff --git a/tests/panic-when-creating-tracked-struct-outside-of-tracked-fn.rs b/tests/panic-when-creating-tracked-struct-outside-of-tracked-fn.rs index 9263ef8..8b7b588 100644 --- a/tests/panic-when-creating-tracked-struct-outside-of-tracked-fn.rs +++ b/tests/panic-when-creating-tracked-struct-outside-of-tracked-fn.rs @@ -6,7 +6,7 @@ struct Jar(MyTracked<'_>); trait Db: salsa::DbWithJar {} -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] struct MyTracked<'db> { field: u32, } diff --git a/tests/parallel/parallel_cycle_all_recover.rs b/tests/parallel/parallel_cycle_all_recover.rs index 6bbdd4f..4a2775b 100644 --- a/tests/parallel/parallel_cycle_all_recover.rs +++ b/tests/parallel/parallel_cycle_all_recover.rs @@ -13,7 +13,7 @@ impl + Knobs> Db for T {} #[salsa::jar(db = Db)] pub(crate) struct Jar(MyInput, a1, a2, b1, b2); -#[salsa::input(jar = Jar)] +#[salsa::input] pub(crate) struct MyInput { field: i32, } diff --git a/tests/parallel/parallel_cycle_mid_recover.rs b/tests/parallel/parallel_cycle_mid_recover.rs index 34e16e6..4a75ce7 100644 --- a/tests/parallel/parallel_cycle_mid_recover.rs +++ b/tests/parallel/parallel_cycle_mid_recover.rs @@ -13,12 +13,12 @@ impl + Knobs> Db for T {} #[salsa::jar(db = Db)] pub(crate) struct Jar(MyInput, a1, a2, b1, b2, b3); -#[salsa::input(jar = Jar)] +#[salsa::input] pub(crate) struct MyInput { field: i32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] pub(crate) fn a1(db: &dyn Db, input: MyInput) -> i32 { // tell thread b we have started db.signal(1); @@ -28,7 +28,7 @@ pub(crate) fn a1(db: &dyn Db, input: MyInput) -> i32 { a2(db, input) } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] pub(crate) fn a2(db: &dyn Db, input: MyInput) -> i32 { // create the cycle b1(db, input) @@ -46,7 +46,7 @@ fn recover_b1(db: &dyn Db, _cycle: &salsa::Cycle, key: MyInput) -> i32 { key.field(db) * 20 + 2 } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] pub(crate) fn b2(db: &dyn Db, input: MyInput) -> i32 { // will encounter a cycle but recover b3(db, input); diff --git a/tests/parallel/parallel_cycle_none_recover.rs b/tests/parallel/parallel_cycle_none_recover.rs index 4fd82e6..a6716b1 100644 --- a/tests/parallel/parallel_cycle_none_recover.rs +++ b/tests/parallel/parallel_cycle_none_recover.rs @@ -14,12 +14,12 @@ impl + Knobs> Db for T {} #[salsa::jar(db = Db)] pub(crate) struct Jar(MyInput, a, b); -#[salsa::input(jar = Jar)] +#[salsa::input] pub(crate) struct MyInput { field: i32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] pub(crate) fn a(db: &dyn Db, input: MyInput) -> i32 { // Wait to create the cycle until both threads have entered db.signal(1); @@ -28,7 +28,7 @@ pub(crate) fn a(db: &dyn Db, input: MyInput) -> i32 { b(db, input) } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] pub(crate) fn b(db: &dyn Db, input: MyInput) -> i32 { // Wait to create the cycle until both threads have entered db.wait_for(1); diff --git a/tests/parallel/parallel_cycle_one_recover.rs b/tests/parallel/parallel_cycle_one_recover.rs index 35f90cf..055eff8 100644 --- a/tests/parallel/parallel_cycle_one_recover.rs +++ b/tests/parallel/parallel_cycle_one_recover.rs @@ -13,12 +13,12 @@ impl + Knobs> Db for T {} #[salsa::jar(db = Db)] pub(crate) struct Jar(MyInput, a1, a2, b1, b2); -#[salsa::input(jar = Jar)] +#[salsa::input] pub(crate) struct MyInput { field: i32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] pub(crate) fn a1(db: &dyn Db, input: MyInput) -> i32 { // Wait to create the cycle until both threads have entered db.signal(1); @@ -36,7 +36,7 @@ fn recover(db: &dyn Db, _cycle: &salsa::Cycle, key: MyInput) -> i32 { key.field(db) * 20 + 2 } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] pub(crate) fn b1(db: &dyn Db, input: MyInput) -> i32 { // Wait to create the cycle until both threads have entered db.wait_for(1); @@ -47,7 +47,7 @@ pub(crate) fn b1(db: &dyn Db, input: MyInput) -> i32 { b2(db, input) } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] pub(crate) fn b2(db: &dyn Db, input: MyInput) -> i32 { a1(db, input) } diff --git a/tests/specify-only-works-if-the-key-is-created-in-the-current-query.rs b/tests/specify-only-works-if-the-key-is-created-in-the-current-query.rs index e0c1c89..5b0ec7d 100644 --- a/tests/specify-only-works-if-the-key-is-created-in-the-current-query.rs +++ b/tests/specify-only-works-if-the-key-is-created-in-the-current-query.rs @@ -13,22 +13,22 @@ struct Jar( trait Db: salsa::DbWithJar {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] struct MyTracked<'db> { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn tracked_struct_created_in_another_query<'db>(db: &'db dyn Db, input: MyInput) -> MyTracked<'db> { MyTracked::new(db, input.field(db) * 2) } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn tracked_fn<'db>(db: &'db dyn Db, input: MyInput) -> MyTracked<'db> { let t = tracked_struct_created_in_another_query(db, input); if input.field(db) != 0 { diff --git a/tests/specify_tracked_fn_in_rev_1_but_not_2.rs b/tests/specify_tracked_fn_in_rev_1_but_not_2.rs index a96e650..57b566d 100644 --- a/tests/specify_tracked_fn_in_rev_1_but_not_2.rs +++ b/tests/specify_tracked_fn_in_rev_1_but_not_2.rs @@ -48,7 +48,7 @@ fn read_maybe_specified<'db>(db: &'db dyn Db, tracked: MyTracked<'db>) -> u32 { /// Create a tracked value and *maybe* specify a value for /// `maybe_specified` -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn create_tracked<'db>(db: &'db dyn Db, input: MyInput) -> MyTracked<'db> { db.push_log(format!("create_tracked({:?})", input)); let tracked = MyTracked::new(db, input); diff --git a/tests/tracked-struct-unchanged-in-new-rev.rs b/tests/tracked-struct-unchanged-in-new-rev.rs index 29bd973..40dbfe3 100644 --- a/tests/tracked-struct-unchanged-in-new-rev.rs +++ b/tests/tracked-struct-unchanged-in-new-rev.rs @@ -5,17 +5,17 @@ struct Jar(MyInput, MyTracked<'_>, tracked_fn); trait Db: salsa::DbWithJar {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] struct MyTracked<'db> { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn tracked_fn<'db>(db: &'db dyn Db, input: MyInput) -> MyTracked<'db> { MyTracked::new(db, input.field(db) / 2) } diff --git a/tests/tracked_fn_on_input.rs b/tests/tracked_fn_on_input.rs index 0e3494d..2d44794 100644 --- a/tests/tracked_fn_on_input.rs +++ b/tests/tracked_fn_on_input.rs @@ -7,12 +7,12 @@ struct Jar(MyInput, tracked_fn); trait Db: salsa::DbWithJar {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn tracked_fn(db: &dyn Db, input: MyInput) -> u32 { input.field(db) * 2 } diff --git a/tests/tracked_fn_on_tracked.rs b/tests/tracked_fn_on_tracked.rs index 02f213a..172f171 100644 --- a/tests/tracked_fn_on_tracked.rs +++ b/tests/tracked_fn_on_tracked.rs @@ -6,17 +6,17 @@ struct Jar(MyInput, MyTracked<'_>, tracked_fn); trait Db: salsa::DbWithJar {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] struct MyTracked<'db> { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn tracked_fn<'db>(db: &'db dyn Db, input: MyInput) -> MyTracked<'db> { MyTracked::new(db, input.field(db) * 2) } diff --git a/tests/tracked_fn_on_tracked_specify.rs b/tests/tracked_fn_on_tracked_specify.rs index 1b4dfbe..9744e20 100644 --- a/tests/tracked_fn_on_tracked_specify.rs +++ b/tests/tracked_fn_on_tracked_specify.rs @@ -7,17 +7,17 @@ struct Jar(MyInput, MyTracked<'_>, tracked_fn, tracked_fn_extra); trait Db: salsa::DbWithJar {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] struct MyTracked<'db> { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn tracked_fn<'db>(db: &'db dyn Db, input: MyInput) -> MyTracked<'db> { let t = MyTracked::new(db, input.field(db) * 2); if input.field(db) != 0 { diff --git a/tests/tracked_fn_read_own_specify.rs b/tests/tracked_fn_read_own_specify.rs index 5785464..71b439e 100644 --- a/tests/tracked_fn_read_own_specify.rs +++ b/tests/tracked_fn_read_own_specify.rs @@ -8,17 +8,17 @@ struct Jar(MyInput, MyTracked<'_>, tracked_fn, tracked_fn_extra); trait Db: salsa::DbWithJar + HasLogger {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] struct MyTracked<'db> { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] fn tracked_fn<'db>(db: &'db dyn Db, input: MyInput) -> u32 { db.push_log(format!("tracked_fn({:?})", input.debug(db))); let t = MyTracked::new(db, input.field(db) * 2); diff --git a/tests/tracked_struct_db1_lt.rs b/tests/tracked_struct_db1_lt.rs index b5214f1..97f3b3c 100644 --- a/tests/tracked_struct_db1_lt.rs +++ b/tests/tracked_struct_db1_lt.rs @@ -11,17 +11,17 @@ struct Jar(MyInput, MyTracked1<'_>, MyTracked2<'_>); trait Db: salsa::DbWithJar + HasLogger {} -#[salsa::input(jar = Jar)] +#[salsa::input] struct MyInput { field: u32, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] struct MyTracked1<'db1> { field: MyTracked2<'db1>, } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] struct MyTracked2<'db2> { field: u32, } diff --git a/tests/warnings/needless_borrow.rs b/tests/warnings/needless_borrow.rs index 787f69e..e6added 100644 --- a/tests/warnings/needless_borrow.rs +++ b/tests/warnings/needless_borrow.rs @@ -12,7 +12,7 @@ impl salsa::DebugWithDb for Token { } } -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] struct TokenTree<'db> { #[return_ref] tokens: Vec, diff --git a/tests/warnings/needless_lifetimes.rs b/tests/warnings/needless_lifetimes.rs index 3612d39..8cf91b6 100644 --- a/tests/warnings/needless_lifetimes.rs +++ b/tests/warnings/needless_lifetimes.rs @@ -6,10 +6,10 @@ pub struct Jar(SourceTree<'_>, SourceTree_all_items, use_tree); #[derive(Debug, PartialEq, Eq, Hash)] pub struct Item {} -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] pub struct SourceTree<'db> {} -#[salsa::tracked(jar = Jar)] +#[salsa::tracked] impl<'db> SourceTree<'db> { #[salsa::tracked(return_ref)] pub fn all_items(self, _db: &'db dyn Db) -> Vec { diff --git a/tests/warnings/unused_variable_db.rs b/tests/warnings/unused_variable_db.rs index 5396918..e3d227e 100644 --- a/tests/warnings/unused_variable_db.rs +++ b/tests/warnings/unused_variable_db.rs @@ -3,5 +3,5 @@ trait Db: salsa::DbWithJar {} #[salsa::jar(db = Db)] struct Jar(Keywords<'_>); -#[salsa::interned(jar = Jar)] +#[salsa::interned] struct Keywords<'db> {}