diff --git a/components/salsa-2022-macros/src/input.rs b/components/salsa-2022-macros/src/input.rs index 0027821e..4c019c9f 100644 --- a/components/salsa-2022-macros/src/input.rs +++ b/components/salsa-2022-macros/src/input.rs @@ -51,8 +51,6 @@ impl crate::options::AllowedOptions for InputStruct { impl InputStruct { fn generate_input(&self) -> syn::Result { - self.validate_input()?; - let id_struct = self.id_struct(); let inherent_impl = self.input_inherent_impl(); let ingredients_for_impl = self.input_ingredients(); @@ -70,12 +68,6 @@ impl InputStruct { }) } - fn validate_input(&self) -> syn::Result<()> { - // check for dissalowed fields - self.disallow_id_fields("input")?; - Ok(()) - } - /// Generate an inherent impl with methods on the entity type. fn input_inherent_impl(&self) -> syn::ItemImpl { let ident = self.id_ident(); @@ -112,8 +104,16 @@ impl InputStruct { ) .collect(); + // setters let set_field_names = self.all_set_field_names(); - let field_setters: Vec = field_indices.iter().zip(&set_field_names).zip(&field_vises).zip(&field_tys).map(|(((field_index, set_field_name), field_vis), field_ty)| { + let field_immuts = self.all_fields_immuts(); + let field_setters: Vec = field_indices.iter() + .zip(&set_field_names) + .zip(&field_vises) + .zip(&field_tys) + .zip(&field_immuts) + .filter(|(_, &is_immut )| !is_immut) + .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> { @@ -289,6 +289,10 @@ impl InputStruct { .collect() } + fn all_fields_immuts(&self) -> Vec { + self.all_fields().map(|f| f.has_id_attr).collect() + } + /// Implementation of `SalsaStructInDb`. fn salsa_struct_in_db_impl(&self) -> syn::ItemImpl { let ident = self.id_ident(); diff --git a/components/salsa-2022-macros/src/salsa_struct.rs b/components/salsa-2022-macros/src/salsa_struct.rs index 5e1c0019..515d9147 100644 --- a/components/salsa-2022-macros/src/salsa_struct.rs +++ b/components/salsa-2022-macros/src/salsa_struct.rs @@ -99,8 +99,7 @@ impl SalsaStruct { pub(crate) fn is_identity_field(&self, field: &SalsaField) -> bool { match self.kind { - SalsaStructKind::Input => false, - SalsaStructKind::Tracked => field.has_id_attr, + SalsaStructKind::Input | SalsaStructKind::Tracked => field.has_id_attr, SalsaStructKind::Interned => true, } } diff --git a/salsa-2022-tests/tests/input_with_ids.rs b/salsa-2022-tests/tests/input_with_ids.rs new file mode 100644 index 00000000..0d3032a0 --- /dev/null +++ b/salsa-2022-tests/tests/input_with_ids.rs @@ -0,0 +1,39 @@ +#![allow(warnings)] + +use expect_test::expect; +use salsa::DebugWithDb; + +#[salsa::jar(db = Db)] +struct Jar(MyInput); + +trait Db: salsa::DbWithJar {} + +#[salsa::input(jar = Jar)] +struct MyInput { + field: u32, + #[id] + id_one: u32, + #[id] + id_two: u16, +} + +#[salsa::db(Jar)] +#[derive(Default)] +struct Database { + storage: salsa::Storage, +} + +impl salsa::Database for Database {} + +impl Db for Database {} + +#[test] +fn test_debug() { + let mut db = Database::default(); + + let input = MyInput::new(&mut db, 22, 50, 10); + + let actual = format!("{:?}", input.debug(&db)); + let expected = expect![[r#"MyInput { [salsa id]: 0, id_one: 50, id_two: 10 }"#]]; + expected.assert_eq(&actual); +}