11//! base_db defines basic database traits. The concrete DB is defined by ide.
2+
3+ pub use salsa;
4+ pub use salsa_macros;
5+
26// FIXME: Rename this crate, base db is non descriptive
37mod change;
48mod input;
59
6- use std:: hash:: BuildHasherDefault ;
10+ use std:: { cell :: RefCell , hash:: BuildHasherDefault , panic , sync :: Once } ;
711
812pub use crate :: {
913 change:: FileChange ,
@@ -17,7 +21,6 @@ pub use crate::{
1721use dashmap:: { DashMap , mapref:: entry:: Entry } ;
1822pub use query_group:: { self } ;
1923use rustc_hash:: { FxHashSet , FxHasher } ;
20- pub use salsa:: { self } ;
2124use salsa:: { Durability , Setter } ;
2225pub use semver:: { BuildMetadata , Prerelease , Version , VersionReq } ;
2326use span:: Edition ;
@@ -28,7 +31,7 @@ pub use vfs::{AnchoredPath, AnchoredPathBuf, FileId, VfsPath, file_set::FileSet}
2831#[ macro_export]
2932macro_rules! impl_intern_key {
3033 ( $id: ident, $loc: ident) => {
31- #[ salsa :: interned( no_lifetime) ]
34+ #[ salsa_macros :: interned( no_lifetime) ]
3235 pub struct $id {
3336 pub loc: $loc,
3437 }
@@ -60,7 +63,7 @@ impl Files {
6063 match self . files . get ( & file_id) {
6164 Some ( text) => * text,
6265 None => {
63- panic ! ( "Unable to fetch file text for `vfs::FileId`: {:?}; this is a bug" , file_id )
66+ panic ! ( "Unable to fetch file text for `vfs::FileId`: {file_id :?}; this is a bug" )
6467 }
6568 }
6669 }
@@ -101,8 +104,7 @@ impl Files {
101104 let source_root = match self . source_roots . get ( & source_root_id) {
102105 Some ( source_root) => source_root,
103106 None => panic ! (
104- "Unable to fetch `SourceRootInput` with `SourceRootId` ({:?}); this is a bug" ,
105- source_root_id
107+ "Unable to fetch `SourceRootInput` with `SourceRootId` ({source_root_id:?}); this is a bug"
106108 ) ,
107109 } ;
108110
@@ -132,8 +134,7 @@ impl Files {
132134 let file_source_root = match self . file_source_roots . get ( & id) {
133135 Some ( file_source_root) => file_source_root,
134136 None => panic ! (
135- "Unable to get `FileSourceRootInput` with `vfs::FileId` ({:?}); this is a bug" ,
136- id
137+ "Unable to get `FileSourceRootInput` with `vfs::FileId` ({id:?}); this is a bug" ,
137138 ) ,
138139 } ;
139140 * file_source_root
@@ -163,7 +164,7 @@ impl Files {
163164 }
164165}
165166
166- #[ salsa :: interned( no_lifetime, debug, constructor=from_span) ]
167+ #[ salsa_macros :: interned( no_lifetime, debug, constructor=from_span) ]
167168pub struct EditionedFileId {
168169 pub editioned_file_id : span:: EditionedFileId ,
169170}
@@ -198,18 +199,18 @@ impl EditionedFileId {
198199 }
199200}
200201
201- #[ salsa :: input( debug) ]
202+ #[ salsa_macros :: input( debug) ]
202203pub struct FileText {
203204 pub text : Arc < str > ,
204205 pub file_id : vfs:: FileId ,
205206}
206207
207- #[ salsa :: input( debug) ]
208+ #[ salsa_macros :: input( debug) ]
208209pub struct FileSourceRootInput {
209210 pub source_root_id : SourceRootId ,
210211}
211212
212- #[ salsa :: input( debug) ]
213+ #[ salsa_macros :: input( debug) ]
213214pub struct SourceRootInput {
214215 pub source_root : Arc < SourceRoot > ,
215216}
@@ -276,7 +277,7 @@ pub fn transitive_deps(db: &dyn SourceDatabase, crate_id: Crate) -> FxHashSet<Cr
276277 deps
277278}
278279
279- #[ salsa :: db]
280+ #[ salsa_macros :: db]
280281pub trait SourceDatabase : salsa:: Database {
281282 /// Text of the file.
282283 fn file_text ( & self , file_id : vfs:: FileId ) -> FileText ;
@@ -355,7 +356,7 @@ fn parse(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Parse<ast::SourceFil
355356}
356357
357358fn parse_errors ( db : & dyn RootQueryDb , file_id : EditionedFileId ) -> Option < & [ SyntaxError ] > {
358- #[ salsa :: tracked( return_ref) ]
359+ #[ salsa_macros :: tracked( return_ref) ]
359360 fn parse_errors ( db : & dyn RootQueryDb , file_id : EditionedFileId ) -> Option < Box < [ SyntaxError ] > > {
360361 let errors = db. parse ( file_id) . errors ( ) ;
361362 match & * errors {
@@ -384,3 +385,51 @@ fn relevant_crates(db: &dyn RootQueryDb, file_id: FileId) -> Arc<[Crate]> {
384385 let source_root = db. file_source_root ( file_id) ;
385386 db. source_root_crates ( source_root. source_root_id ( db) )
386387}
388+
389+ #[ must_use]
390+ pub struct DbPanicContext {
391+ // prevent arbitrary construction
392+ _priv : ( ) ,
393+ }
394+
395+ impl Drop for DbPanicContext {
396+ fn drop ( & mut self ) {
397+ Self :: with_ctx ( |ctx| assert ! ( ctx. pop( ) . is_some( ) ) ) ;
398+ }
399+ }
400+
401+ impl DbPanicContext {
402+ pub fn enter ( frame : String ) -> DbPanicContext {
403+ #[ expect( clippy:: print_stderr, reason = "already panicking anyway" ) ]
404+ fn set_hook ( ) {
405+ let default_hook = panic:: take_hook ( ) ;
406+ panic:: set_hook ( Box :: new ( move |panic_info| {
407+ DbPanicContext :: with_ctx ( |ctx| {
408+ if !ctx. is_empty ( ) {
409+ eprintln ! ( "Panic context:" ) ;
410+ for frame in ctx. iter ( ) {
411+ eprintln ! ( "> {frame}\n " ) ;
412+ }
413+ }
414+ } ) ;
415+ if let Some ( backtrace) = salsa:: Backtrace :: capture ( ) {
416+ eprintln ! ( "{backtrace}" ) ;
417+ }
418+ default_hook ( panic_info) ;
419+ } ) ) ;
420+ }
421+
422+ static SET_HOOK : Once = Once :: new ( ) ;
423+ SET_HOOK . call_once ( set_hook) ;
424+
425+ Self :: with_ctx ( |ctx| ctx. push ( frame) ) ;
426+ DbPanicContext { _priv : ( ) }
427+ }
428+
429+ fn with_ctx ( f : impl FnOnce ( & mut Vec < String > ) ) {
430+ thread_local ! {
431+ static CTX : RefCell <Vec <String >> = const { RefCell :: new( Vec :: new( ) ) } ;
432+ }
433+ CTX . with ( |ctx| f ( & mut ctx. borrow_mut ( ) ) ) ;
434+ }
435+ }
0 commit comments