Under this design, *all* databases are a
`DatabaseImpl<U>`, where the `U` implements
`UserData` (you can use `()` if there is none).
Code would default to `&dyn salsa::Database` but
if you want to give access to the userdata, you
can define a custom database trait
`MyDatabase: salsa::Databse` so long as you
* annotate `MyDatabase` trait definition of
impls of `MyDatabase` with `#[salsa::db]`
* implement `MyDatabase` for `DatabaseImpl<U>`
where `U` is your userdata (this could be a
blanket impl, if you don't know the precise
userdata type).
The `tests/common/mod.rs` shows the pattern.
Before we could not observe the case where:
* thread A is blocked on B
* cycle detected in thread B
* some participants are on thread A and have to be marked
(In particular, I commented out some code that seemed necessary and
didn't see any tests fail)
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).
Switch to a procedural implementation of the `query_group!` macro,
residing in the `components/salsa_macros` subcrate.
Allow the user to override the invoked function via `salsa::invoke(...)`
and the name of the generated query type via `salsa::query_type(...)`.
In all tests, replace the `salsa::query_group! { ... }` invocations with
the new attribute-style `#[salsa::query_group]` macro, and change them
to the new naming scheme for query types (`...Query`).
Update README, examples, and documentation.
If a query observes an untracked read, it gets changed_at equal to the
current revision. When we re-validate the query later, if it doesn't
do an untracked read this time, it gets changed_at equal to the
maximum of the dependencies. Crucially, this new changed_at may
be **older** then the previous value of changed_at. That is, we break
the rule that `changed_at` monotonically increases.
This can lead to missed re-executions down the line (see the added
test).
closes#66