diff --git a/components/salsa-2022-macros/src/tracked_struct.rs b/components/salsa-2022-macros/src/tracked_struct.rs index 60043ddd..046981fc 100644 --- a/components/salsa-2022-macros/src/tracked_struct.rs +++ b/components/salsa-2022-macros/src/tracked_struct.rs @@ -135,11 +135,11 @@ impl TrackedStruct { parse_quote! { impl salsa::tracked_struct::Configuration for #config_ident { - type Fields = ( #(#field_tys,)* ); + type Fields<'db> = ( #(#field_tys,)* ); type Revisions = [salsa::Revision; #arity]; #[allow(clippy::unused_unit)] - fn id_fields(fields: &Self::Fields) -> impl std::hash::Hash { + fn id_fields(fields: &Self::Fields<'_>) -> impl std::hash::Hash { ( #( &fields.#id_field_indices ),* ) } @@ -151,11 +151,11 @@ impl TrackedStruct { [current_revision; #arity] } - unsafe fn update_fields( + unsafe fn update_fields<'db>( #current_revision: salsa::Revision, #revisions: &mut Self::Revisions, - #old_fields: *mut Self::Fields, - #new_fields: Self::Fields, + #old_fields: *mut Self::Fields<'db>, + #new_fields: Self::Fields<'db>, ) { use salsa::update::helper::Fallback as _; #update_fields diff --git a/components/salsa-2022/src/tracked_struct.rs b/components/salsa-2022/src/tracked_struct.rs index 5520b0b6..04dff1bc 100644 --- a/components/salsa-2022/src/tracked_struct.rs +++ b/components/salsa-2022/src/tracked_struct.rs @@ -24,7 +24,7 @@ mod tracked_field; /// to a struct. pub trait Configuration { /// A (possibly empty) tuple of the fields for this struct. - type Fields; + type Fields<'db>; /// A array of [`Revision`][] values, one per each of the value fields. /// When a struct is re-recreated in a new revision, the corresponding @@ -32,7 +32,7 @@ pub trait Configuration { /// values have changed (or if the field is marked as `#[no_eq]`). type Revisions; - fn id_fields(fields: &Self::Fields) -> impl Hash; + fn id_fields(fields: &Self::Fields<'_>) -> impl Hash; /// Access the revision of a given value field. /// `field_index` will be between 0 and the number of value fields. @@ -62,11 +62,11 @@ pub trait Configuration { /// Ensures that `old_fields` is fully updated and valid /// after it returns and that `revisions` has been updated /// for any field that changed. - unsafe fn update_fields( + unsafe fn update_fields<'db>( current_revision: Revision, revisions: &mut Self::Revisions, - old_fields: *mut Self::Fields, - new_fields: Self::Fields, + old_fields: *mut Self::Fields<'db>, + new_fields: Self::Fields<'db>, ); } // ANCHOR_END: Configuration @@ -140,7 +140,7 @@ where /// Fields of this tracked struct. They can change across revisions, /// but they do not change within a particular revision. - fields: C::Fields, + fields: C::Fields<'static>, /// The revision information for each field: when did this field last change. /// When tracked structs are re-created, this revision may be updated to the @@ -156,6 +156,14 @@ impl TrackedStructIngredient where C: Configuration, { + unsafe fn to_static<'db>(&'db self, fields: C::Fields<'db>) -> C::Fields<'static> { + unsafe { std::mem::transmute(fields) } + } + + unsafe fn to_self_ptr<'db>(&'db self, fields: *mut C::Fields<'static>) -> *mut C::Fields<'db> { + unsafe { std::mem::transmute(fields) } + } + pub fn new(index: IngredientIndex, debug_name: &'static str) -> Self { Self { interned: InternedIngredient::new(index, debug_name), @@ -199,7 +207,7 @@ where pub fn new_struct<'db>( &'db self, runtime: &'db Runtime, - fields: C::Fields, + fields: C::Fields<'db>, ) -> &'db TrackedStructValue { let data_hash = crate::hash::hash(&C::id_fields(&fields)); @@ -226,7 +234,7 @@ where struct_ingredient_index: self.struct_ingredient_index(), created_at: current_revision, durability: current_deps.durability, - fields, + fields: unsafe { self.to_static(fields) }, revisions: C::new_revisions(current_deps.changed_at), }, ) @@ -254,7 +262,7 @@ where C::update_fields( current_revision, &mut data.revisions, - std::ptr::addr_of_mut!(data.fields), + self.to_self_ptr(std::ptr::addr_of_mut!(data.fields)), fields, ); } diff --git a/components/salsa-2022/src/tracked_struct/tracked_field.rs b/components/salsa-2022/src/tracked_struct/tracked_field.rs index 39c8f03f..03451fe4 100644 --- a/components/salsa-2022/src/tracked_struct/tracked_field.rs +++ b/components/salsa-2022/src/tracked_struct/tracked_field.rs @@ -31,10 +31,14 @@ impl TrackedFieldIngredient where C: Configuration, { + unsafe fn to_self_ref<'db>(&'db self, fields: &'db C::Fields<'static>) -> &'db C::Fields<'db> { + unsafe { std::mem::transmute(fields) } + } + /// Access to this value field. /// Note that this function returns the entire tuple of value fields. /// The caller is responible for selecting the appropriate element. - pub fn field<'db>(&'db self, runtime: &'db Runtime, id: Id) -> &'db C::Fields { + pub fn field<'db>(&'db self, runtime: &'db Runtime, id: Id) -> &'db C::Fields<'db> { let data = self.struct_map.get(runtime, id); let changed_at = C::revision(&data.revisions, self.field_index); @@ -48,7 +52,7 @@ where changed_at, ); - &data.fields + unsafe { self.to_self_ref(&data.fields) } } }