A generic framework for on-demand, incrementalized computation. Inspired by adapton, glimmer, and rustc's query system.
Find a file
bors[bot] 252d21e358
Merge #423
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>
2022-11-29 04:54:45 +00:00
.github/workflows Update test.yml 2022-08-24 18:45:53 +02:00
book Correct docs to refer to #[salsa::cycle] 2022-09-16 11:10:06 +00:00
components salsa 2022: fix input macro set_* being off by one if id field present 2022-11-04 23:39:35 +00:00
examples Remove ': salsa::Database' bound from two examples 2021-12-30 11:02:30 +00:00
examples-2022 Update on-demand input docs 2022-09-16 00:14:54 +01:00
salsa-2022-tests Merge #423 2022-11-29 04:54:45 +00:00
src Merge #381 2022-08-25 10:34:44 +00:00
tests Fix clippy issues 2022-08-24 18:45:53 +02:00
.dir-locals.el ask emacs to rustfmt on save 2018-09-28 11:26:57 -04:00
.gitignore Fix clippy issues 2022-08-24 18:45:53 +02:00
bors.toml Update book workflow 2021-09-28 22:03:05 +02:00
Cargo.toml Move calc and lazy-input examples to examples-2022 2022-09-16 00:14:44 +01:00
FAQ.md Update New Mexico state question 2020-06-26 15:48:29 +01:00
LICENSE-APACHE add readme, license, etc 2018-09-28 11:01:27 -04:00
LICENSE-MIT add readme, license, etc 2018-09-28 11:01:27 -04:00
README.md Fix Chinese book link 2022-09-24 01:00:36 +09:00
RELEASES.md highlight breaking changes 2019-08-15 08:08:00 -04:00
rustfmt.toml add empty/default rustfmt.toml 2022-08-22 19:19:22 +08:00

salsa

Test Book Released API docs Crates.io

A generic framework for on-demand, incrementalized computation.

Salsa Logo

Obligatory warning

Very much a WORK IN PROGRESS at this point. Ready for experimental use but expect frequent breaking changes.

Credits

This system is heavily inspired by adapton, glimmer, and rustc's query system. So credit goes to Eduard-Mihai Burtescu, Matthew Hammer, Yehuda Katz, and Michael Woerister.

Key idea

The key idea of salsa is that you define your program as a set of queries. Every query is used like function K -> V that maps from some key of type K to a value of type V. Queries come in two basic varieties:

  • Inputs: the base inputs to your system. You can change these whenever you like.
  • Functions: pure functions (no side effects) that transform your inputs into other values. The results of queries are memoized to avoid recomputing them a lot. When you make changes to the inputs, we'll figure out (fairly intelligently) when we can re-use these memoized values and when we have to recompute them.

Want to learn more?

To learn more about Salsa, try one of the following:

Getting in touch

The bulk of the discussion happens in the issues and pull requests, but we have a zulip chat as well.