Requires unsafe, since Rust currently doesn't have built-in
support for guaranteed in-place initialization. Unfortunately,
this unsafety propagates to making `Jar` unsafe to implement
in order to guarantee that the jar is initialized, but since
the preferred way to implement it is via `salsa::jar`, this
won't impact most users.
440: Change the constructor of `salsa::Id` to const fn r=XFFXFF a=Y-Nak
This change is motivated to allow interned structs to have default const instances and prefill them in db initialization.
A specific example is managing symbols as a salsa interned struct in a compiler implementation. By declaring keywords as `const` symbols, we can handle keywords without going through their internal representation as rustc does (ref: [rustc_span::symbol](https://github.com/rust-lang/rust/blob/master/compiler/rustc_span/src/symbol.rs)).
Conceptually, it'd look like the one below.
```rust
#[salsa::interned]
pub struct Symbol {
data: String,
}
const SELF_SYM: Symbol = Symbol(salsa::Id::from_u32(1))
...
/// This function is called in db initialization.
fn prefill(db: &dyn HirDb) {
Symbol::new(db, "self".to_string());
...
}
```
Co-authored-by: Yoshitomo Nakanishi <yurayura.rounin.3@gmail.com>
435: Allow `clippy::needless_lifetimes` on tracked method getters r=XFFXFF a=DropDemBits
The tracked method generation adds an extra `__db` lifetime to the signature, but clippy complains that this lifetime can be elided in some cases, so add an allow to silence this warning.
Unfortunately clippy doesn't lint inside of the warning tests, so those tests don't do anything to check that no clippy warnings are generated.
Co-authored-by: DropDemBits <r3usrlnd@gmail.com>
436: Update trybuild tests r=XFFXFF a=DropDemBits
Rust 1.68 changed how the help suggestion text renders, and shows a diff for the suggested change.
Co-authored-by: DropDemBits <r3usrlnd@gmail.com>
428: salsa-2022: fix hanging cancellations due to cvar not being notified r=nikomatsakis a=manapointer
This PR fixes an issue with the `cvar` condvar field of `Shared<DB>` not being notified when `Arc<Shared<DB>>`s were getting dropped.
Previously, the condvar was being notified here:
```rust
impl<DB> Drop for Shared<DB>
where
DB: HasJars,
{
fn drop(&mut self) {
self.cvar.notify_all();
}
}
```
However, because this is implemented on `Shared<DB>`, the `drop` code only ran after all `Arc<Shared<DB>>`s (including that of the actual database and not just its snapshots) had dropped first, even though the intention was for the `drop` code to run when each individual `Arc<Shared<DB>>` was dropped so that the condvar would be notified each time.
To fix this, I've modified the `Shared<DB>` struct to instead hold `Arc`s to both the jars and the condvar, and `Storage` now holds `Shared<DB>` directly rather than `Arc<Shared<DB>>`. When `Shared<DB>` is dropped, it first drops its `Arc` for the jars, and then notifies the condvar.
## Note
On my local branch I have a test case for this functionality, although it relied on timing using `std:🧵:sleep`. I figured this was less than ideal, so I decided not to include it in this PR - I'd love to get feedback on a better way to test this!
Co-authored-by: manapointer <manapointer@gmail.com>
Co-authored-by: Niko Matsakis <niko@alum.mit.edu>
423: salsa 2022: fix input macro set_* being off by one if id field present r=XFFXFF a=jhgg
This PR fixes an issue with code generation for `#[salsa::input]` struct's `set_` methods.
Consider the following code:
```rust
#[salsa::input(jar = Jar)]
struct BuggedInput {
#[id]
id: u32,
other: String,
}
```
This will expand to:
```rust
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
struct BuggedInput(salsa::Id);
impl BuggedInput {
// snip...
fn set_other<'db>(
self,
__db: &'db mut <Jar as salsa:🫙:Jar<'_>>::DynDb,
) -> salsa::setter::Setter<'db, BuggedInput, u32> {
// ^^^ wrong type (should be `String`)
let (__jar, __runtime) = <_ as salsa::storage::HasJar<Jar>>::jar_mut(__db);
let __ingredients =
<Jar as salsa::storage::HasIngredientsFor<BuggedInput>>::ingredient_mut(__jar);
salsa::setter::Setter::new(__runtime, self, &mut __ingredients.0)
// ^ wrong index (should be `1`)
}
}
```
Here we can see that the generated `set_other` impl is improperly setting the `id` field. This bug is caused because the filtering of the id fields in `InputStruct::all_set_field_names` causes a mismatch in `InputStruct::input_inherent_impl` when zipped with the field indices and types.
This PR changes `all_set_field_names` to return an `Option<&syn::Ident>` where the None is provided when a setter should not be generated, thus not causing index mismatches because no filtering occurs. Instead, we filter inside of `input_inherent_impl` after all the zips have been applied to the iterator.
After this PR, the code generated is now correct:
```rust
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Debug)]
struct BuggedInput(salsa::Id);
impl BuggedInput {
// snip...
fn set_other<'db>(
self,
__db: &'db mut <Jar as salsa:🫙:Jar<'_>>::DynDb,
) -> salsa::setter::Setter<'db, BuggedInput, String> {
let (__jar, __runtime) = <_ as salsa::storage::HasJar<Jar>>::jar_mut(__db);
let __ingredients =
<Jar as salsa::storage::HasIngredientsFor<BuggedInput>>::ingredient_mut(__jar);
salsa::setter::Setter::new(__runtime, self, &mut __ingredients.1)
}
}
```
Co-authored-by: Jake Heinz <jh@discordapp.com>
412: Fix race condition in interned data r=nikomatsakis a=Skepfyr
In some scenarios the `InternedIngredient` could return two different ids for the same data if called in parallel.
Co-authored-by: Jack Rickard <jack.rickard@outlook.com>