salsa/tests/incremental/memoized_dep_inputs.rs
Niko Matsakis fad97eeb6a remove the DB parameter
This had two unexpected consequences, one unfortunate, one "medium":

* All `salsa::Database` must be `'static`. This falls out from
`Q::DynDb` not having access to any lifetimes, but also the defaulting
rules for `dyn QueryGroup` that make it `dyn QueryGroup + 'static`. We
don't really support generic databases anyway yet so this isn't a big
deal, and we can add workarounds later (ideally via GATs).

* It is now statically impossible to invoke `snapshot` from a query,
and so we don't need to test that it panics. This is because the
signature of `snapshot` returns a `Snapshot<Self>` and that is not
accessible to a `dyn QueryGroup` type. Similarly, invoking
`Runtime::snapshot` directly is not possible becaues it is
crate-private. So I removed the test. This seems ok, but eventually I
would like to expose ways for queries to do parallel
execution (matklad and I had talked about a "speculation" primitive
for enabling that).

* This commit is 99% boilerplate I did with search-and-replace. I also
rolled in a few other changes I might have preferred to factor out,
most notably removing the `GetQueryTable` plumbing trait in favor of
free-methods, but it was awkward to factor them out and get all the
generics right (so much simpler in this version).
2020-07-04 14:17:11 +00:00

61 lines
1.8 KiB
Rust

use crate::implementation::{TestContext, TestContextImpl};
#[salsa::query_group(MemoizedDepInputs)]
pub(crate) trait MemoizedDepInputsContext: TestContext {
fn dep_memoized2(&self) -> usize;
fn dep_memoized1(&self) -> usize;
#[salsa::dependencies]
fn dep_derived1(&self) -> usize;
#[salsa::input]
fn dep_input1(&self) -> usize;
#[salsa::input]
fn dep_input2(&self) -> usize;
}
fn dep_memoized2(db: &dyn MemoizedDepInputsContext) -> usize {
db.log().add("Memoized2 invoked");
db.dep_memoized1()
}
fn dep_memoized1(db: &dyn MemoizedDepInputsContext) -> usize {
db.log().add("Memoized1 invoked");
db.dep_derived1() * 2
}
fn dep_derived1(db: &dyn MemoizedDepInputsContext) -> usize {
db.log().add("Derived1 invoked");
db.dep_input1() / 2
}
#[test]
fn revalidate() {
let db = &mut TestContextImpl::default();
db.set_dep_input1(0);
// Initial run starts from Memoized2:
let v = db.dep_memoized2();
assert_eq!(v, 0);
db.assert_log(&["Memoized2 invoked", "Memoized1 invoked", "Derived1 invoked"]);
// After that, we first try to validate Memoized1 but wind up
// running Memoized2. Note that we don't try to validate
// Derived1, so it is invoked by Memoized1.
db.set_dep_input1(44);
let v = db.dep_memoized2();
assert_eq!(v, 44);
db.assert_log(&["Memoized1 invoked", "Derived1 invoked", "Memoized2 invoked"]);
// Here validation of Memoized1 succeeds so Memoized2 never runs.
db.set_dep_input1(45);
let v = db.dep_memoized2();
assert_eq!(v, 44);
db.assert_log(&["Memoized1 invoked", "Derived1 invoked"]);
// Here, a change to input2 doesn't affect us, so nothing runs.
db.set_dep_input2(45);
let v = db.dep_memoized2();
assert_eq!(v, 44);
db.assert_log(&[]);
}