@@ -327,6 +327,7 @@ unsafe impl Sync for DbInterner<'_> {}
327327impl < ' db > DbInterner < ' db > {
328328 // FIXME(next-solver): remove this method
329329 pub fn conjure ( ) -> DbInterner < ' db > {
330+ // Here we can not reinit the cache since we do that when we attach the db.
330331 crate :: with_attached_db ( |db| DbInterner {
331332 db : unsafe { std:: mem:: transmute :: < & dyn HirDatabase , & ' db dyn HirDatabase > ( db) } ,
332333 krate : None ,
@@ -339,10 +340,13 @@ impl<'db> DbInterner<'db> {
339340 ///
340341 /// Elaboration is a special kind: it needs lang items (for `Sized`), therefore it needs `new_with()`.
341342 pub fn new_no_crate ( db : & ' db dyn HirDatabase ) -> Self {
343+ // We do not reinit the cache here, since anything accessing the cache needs an InferCtxt,
344+ // and we panic when trying to construct an InferCtxt for an Interner without a crate.
342345 DbInterner { db, krate : None , lang_items : None }
343346 }
344347
345348 pub fn new_with ( db : & ' db dyn HirDatabase , krate : Crate ) -> DbInterner < ' db > {
349+ tls_cache:: reinit_cache ( db) ;
346350 DbInterner {
347351 db,
348352 krate : Some ( krate) ,
@@ -1120,7 +1124,8 @@ impl<'db> Interner for DbInterner<'db> {
11201124 self ,
11211125 f : impl FnOnce ( & mut rustc_type_ir:: search_graph:: GlobalCache < Self > ) -> R ,
11221126 ) -> R {
1123- tls_cache:: with_cache ( self . db , f)
1127+ // We make sure to reinit the cache when constructing the Interner.
1128+ tls_cache:: borrow_assume_valid ( self . db , f)
11241129 }
11251130
11261131 fn canonical_param_env_cache_get_or_insert < R > (
@@ -2475,6 +2480,7 @@ mod tls_db {
24752480 }
24762481
24772482 let _guard = DbGuard :: new ( self , db) ;
2483+ super :: tls_cache:: reinit_cache ( db) ;
24782484 op ( )
24792485 }
24802486
@@ -2497,10 +2503,14 @@ mod tls_db {
24972503 #[ inline]
24982504 fn drop ( & mut self ) {
24992505 self . state . database . set ( self . prev ) ;
2506+ if let Some ( prev) = self . prev {
2507+ super :: tls_cache:: reinit_cache ( unsafe { prev. as_ref ( ) } ) ;
2508+ }
25002509 }
25012510 }
25022511
25032512 let _guard = DbGuard :: new ( self , db) ;
2513+ super :: tls_cache:: reinit_cache ( db) ;
25042514 op ( )
25052515 }
25062516
@@ -2555,22 +2565,38 @@ mod tls_cache {
25552565 static GLOBAL_CACHE : RefCell <Option <Cache >> = const { RefCell :: new( None ) } ;
25562566 }
25572567
2558- pub ( super ) fn with_cache < ' db , T > (
2559- db : & ' db dyn HirDatabase ,
2560- f : impl FnOnce ( & mut GlobalCache < DbInterner < ' db > > ) -> T ,
2561- ) -> T {
2568+ pub ( super ) fn reinit_cache ( db : & dyn HirDatabase ) {
25622569 GLOBAL_CACHE . with_borrow_mut ( |handle| {
25632570 let ( db_nonce, revision) = db. nonce_and_revision ( ) ;
2564- let handle = match handle {
2571+ match handle {
25652572 Some ( handle) => {
25662573 if handle. revision != revision || db_nonce != handle. db_nonce {
25672574 * handle = Cache { cache : GlobalCache :: default ( ) , revision, db_nonce } ;
25682575 }
2569- handle
25702576 }
2571- None => handle. insert ( Cache { cache : GlobalCache :: default ( ) , revision, db_nonce } ) ,
2577+ None => * handle = Some ( Cache { cache : GlobalCache :: default ( ) , revision, db_nonce } ) ,
2578+ }
2579+ } )
2580+ }
2581+
2582+ pub ( super ) fn borrow_assume_valid < ' db , T > (
2583+ db : & ' db dyn HirDatabase ,
2584+ f : impl FnOnce ( & mut GlobalCache < DbInterner < ' db > > ) -> T ,
2585+ ) -> T {
2586+ if cfg ! ( debug_assertions) {
2587+ let get_state = || {
2588+ GLOBAL_CACHE . with_borrow ( |handle| {
2589+ handle. as_ref ( ) . map ( |handle| ( handle. db_nonce , handle. revision ) )
2590+ } )
25722591 } ;
2592+ let old_state = get_state ( ) ;
2593+ reinit_cache ( db) ;
2594+ let new_state = get_state ( ) ;
2595+ assert_eq ! ( old_state, new_state, "you assumed the cache is valid!" ) ;
2596+ }
25732597
2598+ GLOBAL_CACHE . with_borrow_mut ( |handle| {
2599+ let handle = handle. as_mut ( ) . expect ( "you assumed the cache is valid!" ) ;
25742600 // SAFETY: No idea
25752601 f ( unsafe {
25762602 std:: mem:: transmute :: <
0 commit comments