@@ -91,6 +91,16 @@ macro_rules! setup_tracked_fn {
9191
9292 struct $Configuration;
9393
94+ $zalsa:: register_jar! {
95+ $zalsa:: ErasedJar :: erase:: <$fn_name>( )
96+ }
97+
98+ #[ allow( non_local_definitions) ]
99+ impl $zalsa:: HasJar for $fn_name {
100+ type Jar = $fn_name;
101+ const KIND : $zalsa:: JarKind = $zalsa:: JarKind :: TrackedFn ;
102+ }
103+
94104 static $FN_CACHE: $zalsa:: IngredientCache <$zalsa:: function:: IngredientImpl <$Configuration>> =
95105 $zalsa:: IngredientCache :: new( ) ;
96106
@@ -108,7 +118,7 @@ macro_rules! setup_tracked_fn {
108118 impl $zalsa:: SalsaStructInDb for $InternedData<' _> {
109119 type MemoIngredientMap = $zalsa:: MemoIngredientSingletonIndex ;
110120
111- fn lookup_or_create_ingredient_index ( aux: & $zalsa:: Zalsa ) -> $zalsa:: IngredientIndices {
121+ fn lookup_ingredient_index ( aux: & $zalsa:: Zalsa ) -> $zalsa:: IngredientIndices {
112122 $zalsa:: IngredientIndices :: empty( )
113123 }
114124
@@ -155,27 +165,19 @@ macro_rules! setup_tracked_fn {
155165 impl $Configuration {
156166 fn fn_ingredient( db: & dyn $Db) -> & $zalsa:: function:: IngredientImpl <$Configuration> {
157167 let zalsa = db. zalsa( ) ;
158- $FN_CACHE. get_or_create( zalsa, || {
159- let jar_entry = zalsa. lookup_jar_by_type:: <$Configuration>( ) ;
160-
161- // If the ingredient has already been inserted, we know that the downcaster
162- // has also been registered. This is a fast-path for multi-database use cases
163- // that bypass the ingredient cache and will always execute this closure.
164- if let Some ( index) = jar_entry. get( ) {
165- return index;
166- }
167-
168- <dyn $Db as $Db>:: zalsa_register_downcaster( db) ;
169- jar_entry. get_or_create( )
170- } )
168+ $FN_CACHE
169+ . get_or_create( zalsa, || zalsa. lookup_jar_by_type:: <$fn_name>( ) )
170+ . get_or_init( || <dyn $Db as $Db>:: zalsa_register_downcaster( db) )
171171 }
172172
173173 pub fn fn_ingredient_mut( db: & mut dyn $Db) -> & mut $zalsa:: function:: IngredientImpl <Self > {
174- <dyn $Db as $Db>:: zalsa_register_downcaster( db) ;
174+ let view = <dyn $Db as $Db>:: zalsa_register_downcaster( db) ;
175175 let zalsa_mut = db. zalsa_mut( ) ;
176- let index = zalsa_mut. lookup_jar_by_type:: <$Configuration> ( ) . get_or_create ( ) ;
176+ let index = zalsa_mut. lookup_jar_by_type:: <$fn_name> ( ) ;
177177 let ( ingredient, _) = zalsa_mut. lookup_ingredient_mut( index) ;
178- ingredient. assert_type_mut:: <$zalsa:: function:: IngredientImpl <Self >>( )
178+ let ingredient = ingredient. assert_type_mut:: <$zalsa:: function:: IngredientImpl <Self >>( ) ;
179+ ingredient. get_or_init( || view) ;
180+ ingredient
179181 }
180182
181183 $zalsa:: macro_if! { $needs_interner =>
@@ -184,8 +186,7 @@ macro_rules! setup_tracked_fn {
184186 ) -> & $zalsa:: interned:: IngredientImpl <$Configuration> {
185187 let zalsa = db. zalsa( ) ;
186188 $INTERN_CACHE. get_or_create( zalsa, || {
187- <dyn $Db as $Db>:: zalsa_register_downcaster( db) ;
188- zalsa. lookup_jar_by_type:: <$Configuration>( ) . get_or_create( ) . successor( 0 )
189+ zalsa. lookup_jar_by_type:: <$fn_name>( ) . successor( 0 )
189190 } )
190191 }
191192 }
@@ -248,42 +249,31 @@ macro_rules! setup_tracked_fn {
248249 }
249250 }
250251
251- impl $zalsa:: Jar for $Configuration {
252- fn create_dependencies( zalsa: & $zalsa:: Zalsa ) -> $zalsa:: IngredientIndices
253- where
254- Self : Sized
255- {
256- $zalsa:: macro_if! {
257- if $needs_interner {
258- $zalsa:: IngredientIndices :: empty( )
259- } else {
260- <$InternedData as $zalsa:: SalsaStructInDb >:: lookup_or_create_ingredient_index( zalsa)
261- }
262- }
263- }
264-
252+ #[ allow( non_local_definitions) ]
253+ impl $zalsa:: Jar for $fn_name {
265254 fn create_ingredients(
266- zalsa: & $zalsa:: Zalsa ,
255+ zalsa: & mut $zalsa:: Zalsa ,
267256 first_index: $zalsa:: IngredientIndex ,
268- struct_index: $zalsa:: IngredientIndices ,
269257 ) -> Vec <Box <dyn $zalsa:: Ingredient >> {
270258 let struct_index: $zalsa:: IngredientIndices = $zalsa:: macro_if! {
271259 if $needs_interner {
272260 first_index. successor( 0 ) . into( )
273261 } else {
274- struct_index
262+ // Note that struct ingredients are created before tracked functions,
263+ // so this cannot panic.
264+ <$InternedData as $zalsa:: SalsaStructInDb >:: lookup_ingredient_index( zalsa)
275265 }
276266 } ;
277267
278268 $zalsa:: macro_if! { $needs_interner =>
279- let intern_ingredient = <$zalsa:: interned:: IngredientImpl <$Configuration>>:: new(
269+ let mut intern_ingredient = <$zalsa:: interned:: IngredientImpl <$Configuration>>:: new(
280270 first_index. successor( 0 )
281271 ) ;
282272 }
283273
284274 let intern_ingredient_memo_types = $zalsa:: macro_if! {
285275 if $needs_interner {
286- Some ( $zalsa:: Ingredient :: memo_table_types ( & intern_ingredient) )
276+ Some ( $zalsa:: Ingredient :: memo_table_types_mut ( & mut intern_ingredient) )
287277 } else {
288278 None
289279 }
@@ -303,7 +293,6 @@ macro_rules! setup_tracked_fn {
303293 first_index,
304294 memo_ingredient_indices,
305295 $lru,
306- zalsa. views( ) . downcaster_for:: <dyn $Db>( ) ,
307296 ) ;
308297 $zalsa:: macro_if! {
309298 if $needs_interner {
@@ -386,6 +375,7 @@ macro_rules! setup_tracked_fn {
386375 $zalsa:: return_mode_expression!( ( $return_mode, __, __) , $output_ty, result, )
387376 } )
388377 }
378+
389379 // The struct needs be last in the macro expansion in order to make the tracked
390380 // function's ident be identified as a function, not a struct, during semantic highlighting.
391381 // for more details, see https://github.com/salsa-rs/salsa/pull/612.
0 commit comments