Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/query-group-macro/tests/cycle.rs')
-rw-r--r--crates/query-group-macro/tests/cycle.rs265
1 files changed, 0 insertions, 265 deletions
diff --git a/crates/query-group-macro/tests/cycle.rs b/crates/query-group-macro/tests/cycle.rs
deleted file mode 100644
index 8d195cbd8d..0000000000
--- a/crates/query-group-macro/tests/cycle.rs
+++ /dev/null
@@ -1,265 +0,0 @@
-use std::panic::UnwindSafe;
-
-use expect_test::expect;
-use query_group_macro::query_group;
-use salsa::Setter;
-
-/// The queries A, B, and C in `Database` can be configured
-/// to invoke one another in arbitrary ways using this
-/// enum.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-enum CycleQuery {
- None,
- A,
- B,
- C,
- AthenC,
-}
-
-#[salsa::input]
-struct ABC {
- a: CycleQuery,
- b: CycleQuery,
- c: CycleQuery,
-}
-
-impl CycleQuery {
- fn invoke(self, db: &dyn CycleDatabase, abc: ABC) -> Result<(), Error> {
- match self {
- CycleQuery::A => db.cycle_a(abc),
- CycleQuery::B => db.cycle_b(abc),
- CycleQuery::C => db.cycle_c(abc),
- CycleQuery::AthenC => {
- let _ = db.cycle_a(abc);
- db.cycle_c(abc)
- }
- CycleQuery::None => Ok(()),
- }
- }
-}
-
-#[salsa::input]
-struct MyInput {}
-
-#[salsa::tracked]
-fn memoized_a(db: &dyn CycleDatabase, input: MyInput) {
- memoized_b(db, input)
-}
-
-#[salsa::tracked]
-fn memoized_b(db: &dyn CycleDatabase, input: MyInput) {
- memoized_a(db, input)
-}
-
-#[salsa::tracked]
-fn volatile_a(db: &dyn CycleDatabase, input: MyInput) {
- db.report_untracked_read();
- volatile_b(db, input)
-}
-
-#[salsa::tracked]
-fn volatile_b(db: &dyn CycleDatabase, input: MyInput) {
- db.report_untracked_read();
- volatile_a(db, input)
-}
-
-#[track_caller]
-fn extract_cycle(f: impl FnOnce() + UnwindSafe) -> salsa::Cycle {
- let v = std::panic::catch_unwind(f);
- if let Err(d) = &v {
- if let Some(cycle) = d.downcast_ref::<salsa::Cycle>() {
- return cycle.clone();
- }
- }
- panic!("unexpected value: {:?}", v)
-}
-
-#[derive(PartialEq, Eq, Hash, Clone, Debug)]
-struct Error {
- cycle: Vec<String>,
-}
-
-#[query_group]
-trait CycleDatabase: salsa::Database {
- #[salsa::cycle(recover_a)]
- fn cycle_a(&self, abc: ABC) -> Result<(), Error>;
-
- #[salsa::cycle(recover_b)]
- fn cycle_b(&self, abc: ABC) -> Result<(), Error>;
-
- fn cycle_c(&self, abc: ABC) -> Result<(), Error>;
-}
-
-fn cycle_a(db: &dyn CycleDatabase, abc: ABC) -> Result<(), Error> {
- abc.a(db).invoke(db, abc)
-}
-
-fn recover_a(_db: &dyn CycleDatabase, cycle: &salsa::Cycle, _abc: ABC) -> Result<(), Error> {
- Err(Error { cycle: cycle.participant_keys().map(|k| format!("{k:?}")).collect() })
-}
-
-fn cycle_b(db: &dyn CycleDatabase, abc: ABC) -> Result<(), Error> {
- abc.b(db).invoke(db, abc)
-}
-
-fn recover_b(_db: &dyn CycleDatabase, cycle: &salsa::Cycle, _abc: ABC) -> Result<(), Error> {
- Err(Error { cycle: cycle.participant_keys().map(|k| format!("{k:?}")).collect() })
-}
-
-fn cycle_c(db: &dyn CycleDatabase, abc: ABC) -> Result<(), Error> {
- abc.c(db).invoke(db, abc)
-}
-
-#[test]
-fn cycle_memoized() {
- let db = salsa::DatabaseImpl::new();
-
- let input = MyInput::new(&db);
- let cycle = extract_cycle(|| memoized_a(&db, input));
- let expected = expect![[r#"
- [
- DatabaseKeyIndex(
- IngredientIndex(
- 1,
- ),
- Id(0),
- ),
- DatabaseKeyIndex(
- IngredientIndex(
- 2,
- ),
- Id(0),
- ),
- ]
- "#]];
- expected.assert_debug_eq(&cycle.all_participants(&db));
-}
-
-#[test]
-fn inner_cycle() {
- // A --> B <-- C
- // ^ |
- // +-----+
- let db = salsa::DatabaseImpl::new();
-
- let abc = ABC::new(&db, CycleQuery::B, CycleQuery::A, CycleQuery::B);
- let err = db.cycle_c(abc);
- assert!(err.is_err());
- let expected = expect![[r#"
- [
- "cycle_a_shim(Id(0))",
- "cycle_b_shim(Id(0))",
- ]
- "#]];
- expected.assert_debug_eq(&err.unwrap_err().cycle);
-}
-
-#[test]
-fn cycle_revalidate() {
- // A --> B
- // ^ |
- // +-----+
- let mut db = salsa::DatabaseImpl::new();
- let abc = ABC::new(&db, CycleQuery::B, CycleQuery::A, CycleQuery::None);
- assert!(db.cycle_a(abc).is_err());
- abc.set_b(&mut db).to(CycleQuery::A); // same value as default
- assert!(db.cycle_a(abc).is_err());
-}
-
-#[test]
-fn cycle_recovery_unchanged_twice() {
- // A --> B
- // ^ |
- // +-----+
- let mut db = salsa::DatabaseImpl::new();
- let abc = ABC::new(&db, CycleQuery::B, CycleQuery::A, CycleQuery::None);
- assert!(db.cycle_a(abc).is_err());
-
- abc.set_c(&mut db).to(CycleQuery::A); // force new revision
- assert!(db.cycle_a(abc).is_err());
-}
-
-#[test]
-fn cycle_appears() {
- let mut db = salsa::DatabaseImpl::new();
- // A --> B
- let abc = ABC::new(&db, CycleQuery::B, CycleQuery::None, CycleQuery::None);
- assert!(db.cycle_a(abc).is_ok());
-
- // A --> B
- // ^ |
- // +-----+
- abc.set_b(&mut db).to(CycleQuery::A);
- assert!(db.cycle_a(abc).is_err());
-}
-
-#[test]
-fn cycle_disappears() {
- let mut db = salsa::DatabaseImpl::new();
-
- // A --> B
- // ^ |
- // +-----+
- let abc = ABC::new(&db, CycleQuery::B, CycleQuery::A, CycleQuery::None);
- assert!(db.cycle_a(abc).is_err());
-
- // A --> B
- abc.set_b(&mut db).to(CycleQuery::None);
- assert!(db.cycle_a(abc).is_ok());
-}
-
-#[test]
-fn cycle_multiple() {
- // No matter whether we start from A or B, we get the same set of participants:
- let db = salsa::DatabaseImpl::new();
-
- // Configuration:
- //
- // A --> B <-- C
- // ^ | ^
- // +-----+ |
- // | |
- // +-----+
- //
- // Here, conceptually, B encounters a cycle with A and then
- // recovers.
- let abc = ABC::new(&db, CycleQuery::B, CycleQuery::AthenC, CycleQuery::A);
-
- let c = db.cycle_c(abc);
- let b = db.cycle_b(abc);
- let a = db.cycle_a(abc);
- let expected = expect![[r#"
- (
- [
- "cycle_a_shim(Id(0))",
- "cycle_b_shim(Id(0))",
- ],
- [
- "cycle_a_shim(Id(0))",
- "cycle_b_shim(Id(0))",
- ],
- [
- "cycle_a_shim(Id(0))",
- "cycle_b_shim(Id(0))",
- ],
- )
- "#]];
- expected.assert_debug_eq(&(c.unwrap_err().cycle, b.unwrap_err().cycle, a.unwrap_err().cycle));
-}
-
-#[test]
-fn cycle_mixed_1() {
- let db = salsa::DatabaseImpl::new();
- // A --> B <-- C
- // | ^
- // +-----+
- let abc = ABC::new(&db, CycleQuery::B, CycleQuery::C, CycleQuery::B);
-
- let expected = expect![[r#"
- [
- "cycle_b_shim(Id(0))",
- "cycle_c_shim(Id(0))",
- ]
- "#]];
- expected.assert_debug_eq(&db.cycle_c(abc).unwrap_err().cycle);
-}