@@ -288,38 +288,107 @@ pub enum ModuleSource {
288
288
289
289
mod diagnostics {
290
290
use hir_expand:: diagnostics:: DiagnosticSink ;
291
+ use hir_expand:: hygiene:: Hygiene ;
292
+ use hir_expand:: InFile ;
291
293
use syntax:: { ast, AstPtr } ;
292
294
293
- use crate :: { db:: DefDatabase , diagnostics:: UnresolvedModule , nameres:: LocalModuleId , AstId } ;
295
+ use crate :: path:: ModPath ;
296
+ use crate :: { db:: DefDatabase , diagnostics:: * , nameres:: LocalModuleId , AstId } ;
294
297
295
298
#[ derive( Debug , PartialEq , Eq ) ]
296
- pub ( super ) enum DefDiagnostic {
297
- UnresolvedModule {
298
- module : LocalModuleId ,
299
- declaration : AstId < ast:: Module > ,
300
- candidate : String ,
301
- } ,
299
+ enum DiagnosticKind {
300
+ UnresolvedModule { declaration : AstId < ast:: Module > , candidate : String } ,
301
+
302
+ UnresolvedExternCrate { ast : AstId < ast:: ExternCrate > } ,
303
+
304
+ UnresolvedImport { ast : AstId < ast:: Use > , index : usize } ,
305
+ }
306
+
307
+ #[ derive( Debug , PartialEq , Eq ) ]
308
+ pub ( super ) struct DefDiagnostic {
309
+ in_module : LocalModuleId ,
310
+ kind : DiagnosticKind ,
302
311
}
303
312
304
313
impl DefDiagnostic {
314
+ pub ( super ) fn unresolved_module (
315
+ container : LocalModuleId ,
316
+ declaration : AstId < ast:: Module > ,
317
+ candidate : String ,
318
+ ) -> Self {
319
+ Self {
320
+ in_module : container,
321
+ kind : DiagnosticKind :: UnresolvedModule { declaration, candidate } ,
322
+ }
323
+ }
324
+
325
+ pub ( super ) fn unresolved_extern_crate (
326
+ container : LocalModuleId ,
327
+ declaration : AstId < ast:: ExternCrate > ,
328
+ ) -> Self {
329
+ Self {
330
+ in_module : container,
331
+ kind : DiagnosticKind :: UnresolvedExternCrate { ast : declaration } ,
332
+ }
333
+ }
334
+
335
+ pub ( super ) fn unresolved_import (
336
+ container : LocalModuleId ,
337
+ ast : AstId < ast:: Use > ,
338
+ index : usize ,
339
+ ) -> Self {
340
+ Self { in_module : container, kind : DiagnosticKind :: UnresolvedImport { ast, index } }
341
+ }
342
+
305
343
pub ( super ) fn add_to (
306
344
& self ,
307
345
db : & dyn DefDatabase ,
308
346
target_module : LocalModuleId ,
309
347
sink : & mut DiagnosticSink ,
310
348
) {
311
- match self {
312
- DefDiagnostic :: UnresolvedModule { module, declaration, candidate } => {
313
- if * module != target_module {
314
- return ;
315
- }
349
+ if self . in_module != target_module {
350
+ return ;
351
+ }
352
+
353
+ match & self . kind {
354
+ DiagnosticKind :: UnresolvedModule { declaration, candidate } => {
316
355
let decl = declaration. to_node ( db. upcast ( ) ) ;
317
356
sink. push ( UnresolvedModule {
318
357
file : declaration. file_id ,
319
358
decl : AstPtr :: new ( & decl) ,
320
359
candidate : candidate. clone ( ) ,
321
360
} )
322
361
}
362
+
363
+ DiagnosticKind :: UnresolvedExternCrate { ast } => {
364
+ let item = ast. to_node ( db. upcast ( ) ) ;
365
+ sink. push ( UnresolvedExternCrate {
366
+ file : ast. file_id ,
367
+ item : AstPtr :: new ( & item) ,
368
+ } ) ;
369
+ }
370
+
371
+ DiagnosticKind :: UnresolvedImport { ast, index } => {
372
+ let use_item = ast. to_node ( db. upcast ( ) ) ;
373
+ let hygiene = Hygiene :: new ( db. upcast ( ) , ast. file_id ) ;
374
+ let mut cur = 0 ;
375
+ let mut tree = None ;
376
+ ModPath :: expand_use_item (
377
+ InFile :: new ( ast. file_id , use_item) ,
378
+ & hygiene,
379
+ |_mod_path, use_tree, _is_glob, _alias| {
380
+ if cur == * index {
381
+ tree = Some ( use_tree. clone ( ) ) ;
382
+ }
383
+
384
+ cur += 1 ;
385
+ } ,
386
+ ) ;
387
+
388
+ if let Some ( tree) = tree {
389
+ sink. push ( UnresolvedImport { file : ast. file_id , node : AstPtr :: new ( & tree) } ) ;
390
+ }
391
+ }
323
392
}
324
393
}
325
394
}
0 commit comments