@@ -108,13 +108,16 @@ where
108108 return None ;
109109 }
110110 ClaimResult :: Cycle { .. } => match C :: CYCLE_STRATEGY {
111- CycleRecoveryStrategy :: Panic => db. zalsa_local ( ) . with_query_stack ( |stack| {
112- panic ! (
113- "dependency graph cycle when validating {database_key_index:#?}, \
111+ // SAFETY: We do not access the query stack reentrantly.
112+ CycleRecoveryStrategy :: Panic => unsafe {
113+ db. zalsa_local ( ) . with_query_stack_unchecked ( |stack| {
114+ panic ! (
115+ "dependency graph cycle when validating {database_key_index:#?}, \
114116 set cycle_fn/cycle_initial to fixpoint iterate.\n \
115117 Query stack:\n {stack:#?}",
116- ) ;
117- } ) ,
118+ ) ;
119+ } )
120+ } ,
118121 CycleRecoveryStrategy :: FallbackImmediate => {
119122 return Some ( VerifyResult :: unchanged ( ) ) ;
120123 }
@@ -336,32 +339,38 @@ where
336339 return true ;
337340 }
338341
339- zalsa_local. with_query_stack ( |stack| {
340- cycle_heads. iter ( ) . all ( |cycle_head| {
341- stack
342- . iter ( )
343- . rev ( )
344- . find ( |query| query. database_key_index == cycle_head. database_key_index )
345- . map ( |query| query. iteration_count ( ) )
346- . or_else ( || {
347- // If this is a cycle head is owned by another thread that is blocked by this ingredient,
348- // check if it has the same iteration count.
349- let ingredient = zalsa
350- . lookup_ingredient ( cycle_head. database_key_index . ingredient_index ( ) ) ;
351- let wait_result =
352- ingredient. wait_for ( zalsa, cycle_head. database_key_index . key_index ( ) ) ;
353-
354- if !wait_result. is_cycle_with_other_thread ( ) {
355- return None ;
356- }
342+ // SAFETY: We do not access the query stack reentrantly.
343+ unsafe {
344+ zalsa_local. with_query_stack_unchecked ( |stack| {
345+ cycle_heads. iter ( ) . all ( |cycle_head| {
346+ stack
347+ . iter ( )
348+ . rev ( )
349+ . find ( |query| query. database_key_index == cycle_head. database_key_index )
350+ . map ( |query| query. iteration_count ( ) )
351+ . or_else ( || {
352+ // If this is a cycle head is owned by another thread that is blocked by this ingredient,
353+ // check if it has the same iteration count.
354+ let ingredient = zalsa. lookup_ingredient (
355+ cycle_head. database_key_index . ingredient_index ( ) ,
356+ ) ;
357+ let wait_result = ingredient
358+ . wait_for ( zalsa, cycle_head. database_key_index . key_index ( ) ) ;
359+
360+ if !wait_result. is_cycle_with_other_thread ( ) {
361+ return None ;
362+ }
357363
358- let provisional_status = ingredient
359- . provisional_status ( zalsa, cycle_head. database_key_index . key_index ( ) ) ?;
360- provisional_status. iteration ( )
361- } )
362- == Some ( cycle_head. iteration_count )
364+ let provisional_status = ingredient. provisional_status (
365+ zalsa,
366+ cycle_head. database_key_index . key_index ( ) ,
367+ ) ?;
368+ provisional_status. iteration ( )
369+ } )
370+ == Some ( cycle_head. iteration_count )
371+ } )
363372 } )
364- } )
373+ }
365374 }
366375
367376 /// VerifyResult::Unchanged if the memo's value and `changed_at` time is up-to-date in the
0 commit comments