salsa 2022: fix input macro set_* being off by one if id field present

This commit is contained in:
Jake Heinz 2022-11-04 23:37:18 +00:00
parent 30b5e9760a
commit dd10b16964
2 changed files with 29 additions and 16 deletions

View file

@ -110,15 +110,16 @@ impl InputStruct {
.zip(&set_field_names)
.zip(&field_vises)
.zip(&field_tys)
.map(|(((field_index, set_field_name), field_vis), field_ty)| {
parse_quote! {
#field_vis fn #set_field_name<'db>(self, __db: &'db mut #db_dyn_ty) -> salsa::setter::Setter<'db, #ident, #field_ty>
{
let (__jar, __runtime) = <_ as salsa::storage::HasJar<#jar_ty>>::jar_mut(__db);
let __ingredients = <#jar_ty as salsa::storage::HasIngredientsFor< #ident >>::ingredient_mut(__jar);
salsa::setter::Setter::new(__runtime, self, &mut __ingredients.#field_index)
}
}
.filter_map(|(((field_index, &set_field_name), field_vis), field_ty)| {
let set_field_name = set_field_name?;
Some(parse_quote! {
#field_vis fn #set_field_name<'db>(self, __db: &'db mut #db_dyn_ty) -> salsa::setter::Setter<'db, #ident, #field_ty>
{
let (__jar, __runtime) = <_ as salsa::storage::HasJar<#jar_ty>>::jar_mut(__db);
let __ingredients = <#jar_ty as salsa::storage::HasIngredientsFor< #ident >>::ingredient_mut(__jar);
salsa::setter::Setter::new(__runtime, self, &mut __ingredients.#field_index)
}
})
})
.collect();
@ -291,12 +292,13 @@ impl InputStruct {
.collect()
}
/// Names of setters of all fields
/// setters are not created for fields with #[id] tag so they'll be safe to include in debug formatting
pub(crate) fn all_set_field_names(&self) -> Vec<&syn::Ident> {
/// Names of setters of all fields that should be generated. Returns an optional Ident for the field name
/// that is None when the field should not generate a setter.
///
/// Setters are not created for fields with #[id] tag so they'll be safe to include in debug formatting
pub(crate) fn all_set_field_names(&self) -> Vec<Option<&syn::Ident>> {
self.all_fields()
.filter(|&field| !field.has_id_attr)
.map(|ef| ef.set_name())
.map(|ef| (!ef.has_id_attr).then(|| ef.set_name()))
.collect()
}

View file

@ -8,13 +8,17 @@ struct Jar(MyInput);
trait Db: salsa::DbWithJar<Jar> {}
#[derive(Clone, Debug)]
struct Field {}
#[salsa::input(jar = Jar)]
struct MyInput {
field: u32,
#[id]
id_one: u32,
#[id]
id_two: u16,
field: Field,
}
#[salsa::db(Jar)]
@ -31,9 +35,16 @@ impl Db for Database {}
fn test_debug() {
let mut db = Database::default();
let input = MyInput::new(&mut db, 22, 50, 10);
let input = MyInput::new(&mut db, 50, 10, Field {});
let actual = format!("{:?}", input.debug(&db));
let expected = expect![[r#"MyInput { [salsa id]: 0, id_one: 50, id_two: 10 }"#]];
expected.assert_eq(&actual);
}
#[test]
fn test_set() {
let mut db = Database::default();
let input = MyInput::new(&mut db, 50, 10, Field {});
input.set_field(&mut db).to(Field {});
}