1
1
//! base_db defines basic database traits. The concrete DB is defined by ide.
2
+
3
+ pub use salsa;
4
+ pub use salsa_macros;
5
+
2
6
// FIXME: Rename this crate, base db is non descriptive
3
7
mod change;
4
8
mod input;
5
9
6
- use std:: hash:: BuildHasherDefault ;
10
+ use std:: { cell :: RefCell , hash:: BuildHasherDefault , panic , sync :: Once } ;
7
11
8
12
pub use crate :: {
9
13
change:: FileChange ,
@@ -17,7 +21,6 @@ pub use crate::{
17
21
use dashmap:: { DashMap , mapref:: entry:: Entry } ;
18
22
pub use query_group:: { self } ;
19
23
use rustc_hash:: { FxHashSet , FxHasher } ;
20
- pub use salsa:: { self } ;
21
24
use salsa:: { Durability , Setter } ;
22
25
pub use semver:: { BuildMetadata , Prerelease , Version , VersionReq } ;
23
26
use span:: Edition ;
@@ -28,7 +31,7 @@ pub use vfs::{AnchoredPath, AnchoredPathBuf, FileId, VfsPath, file_set::FileSet}
28
31
#[ macro_export]
29
32
macro_rules! impl_intern_key {
30
33
( $id: ident, $loc: ident) => {
31
- #[ salsa :: interned( no_lifetime) ]
34
+ #[ salsa_macros :: interned( no_lifetime) ]
32
35
pub struct $id {
33
36
pub loc: $loc,
34
37
}
@@ -57,7 +60,12 @@ pub struct Files {
57
60
58
61
impl Files {
59
62
pub fn file_text ( & self , file_id : vfs:: FileId ) -> FileText {
60
- * self . files . get ( & file_id) . expect ( "Unable to fetch file; this is a bug" )
63
+ match self . files . get ( & file_id) {
64
+ Some ( text) => * text,
65
+ None => {
66
+ panic ! ( "Unable to fetch file text for `vfs::FileId`: {file_id:?}; this is a bug" )
67
+ }
68
+ }
61
69
}
62
70
63
71
pub fn set_file_text ( & self , db : & mut dyn SourceDatabase , file_id : vfs:: FileId , text : & str ) {
@@ -93,10 +101,12 @@ impl Files {
93
101
94
102
/// Source root of the file.
95
103
pub fn source_root ( & self , source_root_id : SourceRootId ) -> SourceRootInput {
96
- let source_root = self
97
- . source_roots
98
- . get ( & source_root_id)
99
- . expect ( "Unable to fetch source root id; this is a bug" ) ;
104
+ let source_root = match self . source_roots . get ( & source_root_id) {
105
+ Some ( source_root) => source_root,
106
+ None => panic ! (
107
+ "Unable to fetch `SourceRootInput` with `SourceRootId` ({source_root_id:?}); this is a bug"
108
+ ) ,
109
+ } ;
100
110
101
111
* source_root
102
112
}
@@ -121,10 +131,12 @@ impl Files {
121
131
}
122
132
123
133
pub fn file_source_root ( & self , id : vfs:: FileId ) -> FileSourceRootInput {
124
- let file_source_root = self
125
- . file_source_roots
126
- . get ( & id)
127
- . expect ( "Unable to fetch FileSourceRootInput; this is a bug" ) ;
134
+ let file_source_root = match self . file_source_roots . get ( & id) {
135
+ Some ( file_source_root) => file_source_root,
136
+ None => panic ! (
137
+ "Unable to get `FileSourceRootInput` with `vfs::FileId` ({id:?}); this is a bug" ,
138
+ ) ,
139
+ } ;
128
140
* file_source_root
129
141
}
130
142
@@ -152,7 +164,7 @@ impl Files {
152
164
}
153
165
}
154
166
155
- #[ salsa :: interned( no_lifetime, debug, constructor=from_span) ]
167
+ #[ salsa_macros :: interned( no_lifetime, debug, constructor=from_span) ]
156
168
pub struct EditionedFileId {
157
169
pub editioned_file_id : span:: EditionedFileId ,
158
170
}
@@ -187,18 +199,18 @@ impl EditionedFileId {
187
199
}
188
200
}
189
201
190
- #[ salsa :: input( debug) ]
202
+ #[ salsa_macros :: input( debug) ]
191
203
pub struct FileText {
192
204
pub text : Arc < str > ,
193
205
pub file_id : vfs:: FileId ,
194
206
}
195
207
196
- #[ salsa :: input( debug) ]
208
+ #[ salsa_macros :: input( debug) ]
197
209
pub struct FileSourceRootInput {
198
210
pub source_root_id : SourceRootId ,
199
211
}
200
212
201
- #[ salsa :: input( debug) ]
213
+ #[ salsa_macros :: input( debug) ]
202
214
pub struct SourceRootInput {
203
215
pub source_root : Arc < SourceRoot > ,
204
216
}
@@ -265,7 +277,7 @@ pub fn transitive_deps(db: &dyn SourceDatabase, crate_id: Crate) -> FxHashSet<Cr
265
277
deps
266
278
}
267
279
268
- #[ salsa :: db]
280
+ #[ salsa_macros :: db]
269
281
pub trait SourceDatabase : salsa:: Database {
270
282
/// Text of the file.
271
283
fn file_text ( & self , file_id : vfs:: FileId ) -> FileText ;
@@ -344,7 +356,7 @@ fn parse(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Parse<ast::SourceFil
344
356
}
345
357
346
358
fn parse_errors ( db : & dyn RootQueryDb , file_id : EditionedFileId ) -> Option < & [ SyntaxError ] > {
347
- #[ salsa :: tracked( return_ref) ]
359
+ #[ salsa_macros :: tracked( return_ref) ]
348
360
fn parse_errors ( db : & dyn RootQueryDb , file_id : EditionedFileId ) -> Option < Box < [ SyntaxError ] > > {
349
361
let errors = db. parse ( file_id) . errors ( ) ;
350
362
match & * errors {
@@ -373,3 +385,49 @@ fn relevant_crates(db: &dyn RootQueryDb, file_id: FileId) -> Arc<[Crate]> {
373
385
let source_root = db. file_source_root ( file_id) ;
374
386
db. source_root_crates ( source_root. source_root_id ( db) )
375
387
}
388
+
389
+ #[ must_use]
390
+ #[ non_exhaustive]
391
+ pub struct DbPanicContext ;
392
+
393
+ impl Drop for DbPanicContext {
394
+ fn drop ( & mut self ) {
395
+ Self :: with_ctx ( |ctx| assert ! ( ctx. pop( ) . is_some( ) ) ) ;
396
+ }
397
+ }
398
+
399
+ impl DbPanicContext {
400
+ pub fn enter ( frame : String ) -> DbPanicContext {
401
+ #[ expect( clippy:: print_stderr, reason = "already panicking anyway" ) ]
402
+ fn set_hook ( ) {
403
+ let default_hook = panic:: take_hook ( ) ;
404
+ panic:: set_hook ( Box :: new ( move |panic_info| {
405
+ default_hook ( panic_info) ;
406
+ if let Some ( backtrace) = salsa:: Backtrace :: capture ( ) {
407
+ eprintln ! ( "{backtrace:#}" ) ;
408
+ }
409
+ DbPanicContext :: with_ctx ( |ctx| {
410
+ if !ctx. is_empty ( ) {
411
+ eprintln ! ( "additional context:" ) ;
412
+ for ( idx, frame) in ctx. iter ( ) . enumerate ( ) {
413
+ eprintln ! ( "{idx:>4}: {frame}\n " ) ;
414
+ }
415
+ }
416
+ } ) ;
417
+ } ) ) ;
418
+ }
419
+
420
+ static SET_HOOK : Once = Once :: new ( ) ;
421
+ SET_HOOK . call_once ( set_hook) ;
422
+
423
+ Self :: with_ctx ( |ctx| ctx. push ( frame) ) ;
424
+ DbPanicContext
425
+ }
426
+
427
+ fn with_ctx ( f : impl FnOnce ( & mut Vec < String > ) ) {
428
+ thread_local ! {
429
+ static CTX : RefCell <Vec <String >> = const { RefCell :: new( Vec :: new( ) ) } ;
430
+ }
431
+ CTX . with ( |ctx| f ( & mut ctx. borrow_mut ( ) ) ) ;
432
+ }
433
+ }
0 commit comments