@@ -41,7 +41,7 @@ use hir_def::{
41
41
body:: { BodyDiagnostic , SyntheticSyntax } ,
42
42
expr:: { BindingAnnotation , LabelId , Pat , PatId } ,
43
43
lang_item:: LangItemTarget ,
44
- nameres,
44
+ nameres:: { self , diagnostics :: DefDiagnostic } ,
45
45
per_ns:: PerNs ,
46
46
resolver:: { HasResolver , Resolver } ,
47
47
AttrDefId , ConstId , ConstParamId , EnumId , FunctionId , GenericDefId , HasModule , LifetimeParamId ,
@@ -523,191 +523,7 @@ impl Module {
523
523
// FIXME: This is accidentally quadratic.
524
524
continue ;
525
525
}
526
- match & diag. kind {
527
- DefDiagnosticKind :: UnresolvedModule { ast : declaration, candidate } => {
528
- let decl = declaration. to_node ( db. upcast ( ) ) ;
529
- acc. push (
530
- UnresolvedModule {
531
- decl : InFile :: new ( declaration. file_id , AstPtr :: new ( & decl) ) ,
532
- candidate : candidate. clone ( ) ,
533
- }
534
- . into ( ) ,
535
- )
536
- }
537
- DefDiagnosticKind :: UnresolvedExternCrate { ast } => {
538
- let item = ast. to_node ( db. upcast ( ) ) ;
539
- acc. push (
540
- UnresolvedExternCrate {
541
- decl : InFile :: new ( ast. file_id , AstPtr :: new ( & item) ) ,
542
- }
543
- . into ( ) ,
544
- ) ;
545
- }
546
-
547
- DefDiagnosticKind :: UnresolvedImport { id, index } => {
548
- let file_id = id. file_id ( ) ;
549
- let item_tree = id. item_tree ( db. upcast ( ) ) ;
550
- let import = & item_tree[ id. value ] ;
551
-
552
- let use_tree = import. use_tree_to_ast ( db. upcast ( ) , file_id, * index) ;
553
- acc. push (
554
- UnresolvedImport { decl : InFile :: new ( file_id, AstPtr :: new ( & use_tree) ) }
555
- . into ( ) ,
556
- ) ;
557
- }
558
-
559
- DefDiagnosticKind :: UnconfiguredCode { ast, cfg, opts } => {
560
- let item = ast. to_node ( db. upcast ( ) ) ;
561
- acc. push (
562
- InactiveCode {
563
- node : ast. with_value ( AstPtr :: new ( & item) . into ( ) ) ,
564
- cfg : cfg. clone ( ) ,
565
- opts : opts. clone ( ) ,
566
- }
567
- . into ( ) ,
568
- ) ;
569
- }
570
-
571
- DefDiagnosticKind :: UnresolvedProcMacro { ast } => {
572
- let mut precise_location = None ;
573
- let ( node, name) = match ast {
574
- MacroCallKind :: FnLike { ast_id, .. } => {
575
- let node = ast_id. to_node ( db. upcast ( ) ) ;
576
- ( ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & node) ) ) , None )
577
- }
578
- MacroCallKind :: Derive { ast_id, derive_name, .. } => {
579
- let node = ast_id. to_node ( db. upcast ( ) ) ;
580
-
581
- // Compute the precise location of the macro name's token in the derive
582
- // list.
583
- // FIXME: This does not handle paths to the macro, but neither does the
584
- // rest of r-a.
585
- let derive_attrs =
586
- node. attrs ( ) . filter_map ( |attr| match attr. as_simple_call ( ) {
587
- Some ( ( name, args) ) if name == "derive" => Some ( args) ,
588
- _ => None ,
589
- } ) ;
590
- ' outer: for attr in derive_attrs {
591
- let tokens =
592
- attr. syntax ( ) . children_with_tokens ( ) . filter_map ( |elem| {
593
- match elem {
594
- syntax:: NodeOrToken :: Node ( _) => None ,
595
- syntax:: NodeOrToken :: Token ( tok) => Some ( tok) ,
596
- }
597
- } ) ;
598
- for token in tokens {
599
- if token. kind ( ) == SyntaxKind :: IDENT
600
- && token. text ( ) == & * * derive_name
601
- {
602
- precise_location = Some ( token. text_range ( ) ) ;
603
- break ' outer;
604
- }
605
- }
606
- }
607
-
608
- (
609
- ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & node) ) ) ,
610
- Some ( derive_name. clone ( ) ) ,
611
- )
612
- }
613
- MacroCallKind :: Attr { ast_id, invoc_attr_index, attr_name, .. } => {
614
- let node = ast_id. to_node ( db. upcast ( ) ) ;
615
- let attr = node
616
- . doc_comments_and_attrs ( )
617
- . nth ( ( * invoc_attr_index) as usize )
618
- . and_then ( Either :: right)
619
- . unwrap_or_else ( || {
620
- panic ! ( "cannot find attribute #{}" , invoc_attr_index)
621
- } ) ;
622
- (
623
- ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & attr) ) ) ,
624
- Some ( attr_name. clone ( ) ) ,
625
- )
626
- }
627
- } ;
628
- acc. push (
629
- UnresolvedProcMacro {
630
- node,
631
- precise_location,
632
- macro_name : name. map ( Into :: into) ,
633
- }
634
- . into ( ) ,
635
- ) ;
636
- }
637
-
638
- DefDiagnosticKind :: UnresolvedMacroCall { ast, path } => {
639
- let node = ast. to_node ( db. upcast ( ) ) ;
640
- acc. push (
641
- UnresolvedMacroCall {
642
- macro_call : InFile :: new ( ast. file_id , AstPtr :: new ( & node) ) ,
643
- path : path. clone ( ) ,
644
- }
645
- . into ( ) ,
646
- ) ;
647
- }
648
-
649
- DefDiagnosticKind :: MacroError { ast, message } => {
650
- let node = match ast {
651
- MacroCallKind :: FnLike { ast_id, .. } => {
652
- let node = ast_id. to_node ( db. upcast ( ) ) ;
653
- ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & node) ) )
654
- }
655
- MacroCallKind :: Derive { ast_id, .. } => {
656
- // FIXME: point to the attribute instead, this creates very large diagnostics
657
- let node = ast_id. to_node ( db. upcast ( ) ) ;
658
- ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & node) ) )
659
- }
660
- MacroCallKind :: Attr { ast_id, .. } => {
661
- // FIXME: point to the attribute instead, this creates very large diagnostics
662
- let node = ast_id. to_node ( db. upcast ( ) ) ;
663
- ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & node) ) )
664
- }
665
- } ;
666
- acc. push ( MacroError { node, message : message. clone ( ) } . into ( ) ) ;
667
- }
668
-
669
- DefDiagnosticKind :: UnimplementedBuiltinMacro { ast } => {
670
- let node = ast. to_node ( db. upcast ( ) ) ;
671
- // Must have a name, otherwise we wouldn't emit it.
672
- let name = node. name ( ) . expect ( "unimplemented builtin macro with no name" ) ;
673
- acc. push (
674
- UnimplementedBuiltinMacro {
675
- node : ast. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & name) ) ) ,
676
- }
677
- . into ( ) ,
678
- ) ;
679
- }
680
- DefDiagnosticKind :: InvalidDeriveTarget { ast, id } => {
681
- let node = ast. to_node ( db. upcast ( ) ) ;
682
- let derive = node. attrs ( ) . nth ( * id as usize ) ;
683
- match derive {
684
- Some ( derive) => {
685
- acc. push (
686
- InvalidDeriveTarget {
687
- node : ast. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & derive) ) ) ,
688
- }
689
- . into ( ) ,
690
- ) ;
691
- }
692
- None => stdx:: never!( "derive diagnostic on item without derive attribute" ) ,
693
- }
694
- }
695
- DefDiagnosticKind :: MalformedDerive { ast, id } => {
696
- let node = ast. to_node ( db. upcast ( ) ) ;
697
- let derive = node. attrs ( ) . nth ( * id as usize ) ;
698
- match derive {
699
- Some ( derive) => {
700
- acc. push (
701
- MalformedDerive {
702
- node : ast. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & derive) ) ) ,
703
- }
704
- . into ( ) ,
705
- ) ;
706
- }
707
- None => stdx:: never!( "derive diagnostic on item without derive attribute" ) ,
708
- }
709
- }
710
- }
526
+ emit_def_diagnostic ( db, acc, diag) ;
711
527
}
712
528
for decl in self . declarations ( db) {
713
529
match decl {
@@ -767,6 +583,180 @@ impl Module {
767
583
}
768
584
}
769
585
586
+ fn emit_def_diagnostic ( db : & dyn HirDatabase , acc : & mut Vec < AnyDiagnostic > , diag : & DefDiagnostic ) {
587
+ match & diag. kind {
588
+ DefDiagnosticKind :: UnresolvedModule { ast : declaration, candidate } => {
589
+ let decl = declaration. to_node ( db. upcast ( ) ) ;
590
+ acc. push (
591
+ UnresolvedModule {
592
+ decl : InFile :: new ( declaration. file_id , AstPtr :: new ( & decl) ) ,
593
+ candidate : candidate. clone ( ) ,
594
+ }
595
+ . into ( ) ,
596
+ )
597
+ }
598
+ DefDiagnosticKind :: UnresolvedExternCrate { ast } => {
599
+ let item = ast. to_node ( db. upcast ( ) ) ;
600
+ acc. push (
601
+ UnresolvedExternCrate { decl : InFile :: new ( ast. file_id , AstPtr :: new ( & item) ) } . into ( ) ,
602
+ ) ;
603
+ }
604
+
605
+ DefDiagnosticKind :: UnresolvedImport { id, index } => {
606
+ let file_id = id. file_id ( ) ;
607
+ let item_tree = id. item_tree ( db. upcast ( ) ) ;
608
+ let import = & item_tree[ id. value ] ;
609
+
610
+ let use_tree = import. use_tree_to_ast ( db. upcast ( ) , file_id, * index) ;
611
+ acc. push (
612
+ UnresolvedImport { decl : InFile :: new ( file_id, AstPtr :: new ( & use_tree) ) } . into ( ) ,
613
+ ) ;
614
+ }
615
+
616
+ DefDiagnosticKind :: UnconfiguredCode { ast, cfg, opts } => {
617
+ let item = ast. to_node ( db. upcast ( ) ) ;
618
+ acc. push (
619
+ InactiveCode {
620
+ node : ast. with_value ( AstPtr :: new ( & item) . into ( ) ) ,
621
+ cfg : cfg. clone ( ) ,
622
+ opts : opts. clone ( ) ,
623
+ }
624
+ . into ( ) ,
625
+ ) ;
626
+ }
627
+
628
+ DefDiagnosticKind :: UnresolvedProcMacro { ast } => {
629
+ let mut precise_location = None ;
630
+ let ( node, name) = match ast {
631
+ MacroCallKind :: FnLike { ast_id, .. } => {
632
+ let node = ast_id. to_node ( db. upcast ( ) ) ;
633
+ ( ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & node) ) ) , None )
634
+ }
635
+ MacroCallKind :: Derive { ast_id, derive_name, .. } => {
636
+ let node = ast_id. to_node ( db. upcast ( ) ) ;
637
+
638
+ // Compute the precise location of the macro name's token in the derive
639
+ // list.
640
+ // FIXME: This does not handle paths to the macro, but neither does the
641
+ // rest of r-a.
642
+ let derive_attrs =
643
+ node. attrs ( ) . filter_map ( |attr| match attr. as_simple_call ( ) {
644
+ Some ( ( name, args) ) if name == "derive" => Some ( args) ,
645
+ _ => None ,
646
+ } ) ;
647
+ ' outer: for attr in derive_attrs {
648
+ let tokens =
649
+ attr. syntax ( ) . children_with_tokens ( ) . filter_map ( |elem| match elem {
650
+ syntax:: NodeOrToken :: Node ( _) => None ,
651
+ syntax:: NodeOrToken :: Token ( tok) => Some ( tok) ,
652
+ } ) ;
653
+ for token in tokens {
654
+ if token. kind ( ) == SyntaxKind :: IDENT && token. text ( ) == & * * derive_name {
655
+ precise_location = Some ( token. text_range ( ) ) ;
656
+ break ' outer;
657
+ }
658
+ }
659
+ }
660
+
661
+ (
662
+ ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & node) ) ) ,
663
+ Some ( derive_name. clone ( ) ) ,
664
+ )
665
+ }
666
+ MacroCallKind :: Attr { ast_id, invoc_attr_index, attr_name, .. } => {
667
+ let node = ast_id. to_node ( db. upcast ( ) ) ;
668
+ let attr = node
669
+ . doc_comments_and_attrs ( )
670
+ . nth ( ( * invoc_attr_index) as usize )
671
+ . and_then ( Either :: right)
672
+ . unwrap_or_else ( || panic ! ( "cannot find attribute #{}" , invoc_attr_index) ) ;
673
+ (
674
+ ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & attr) ) ) ,
675
+ Some ( attr_name. clone ( ) ) ,
676
+ )
677
+ }
678
+ } ;
679
+ acc. push (
680
+ UnresolvedProcMacro { node, precise_location, macro_name : name. map ( Into :: into) }
681
+ . into ( ) ,
682
+ ) ;
683
+ }
684
+
685
+ DefDiagnosticKind :: UnresolvedMacroCall { ast, path } => {
686
+ let node = ast. to_node ( db. upcast ( ) ) ;
687
+ acc. push (
688
+ UnresolvedMacroCall {
689
+ macro_call : InFile :: new ( ast. file_id , AstPtr :: new ( & node) ) ,
690
+ path : path. clone ( ) ,
691
+ }
692
+ . into ( ) ,
693
+ ) ;
694
+ }
695
+
696
+ DefDiagnosticKind :: MacroError { ast, message } => {
697
+ let node = match ast {
698
+ MacroCallKind :: FnLike { ast_id, .. } => {
699
+ let node = ast_id. to_node ( db. upcast ( ) ) ;
700
+ ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & node) ) )
701
+ }
702
+ MacroCallKind :: Derive { ast_id, .. } => {
703
+ // FIXME: point to the attribute instead, this creates very large diagnostics
704
+ let node = ast_id. to_node ( db. upcast ( ) ) ;
705
+ ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & node) ) )
706
+ }
707
+ MacroCallKind :: Attr { ast_id, .. } => {
708
+ // FIXME: point to the attribute instead, this creates very large diagnostics
709
+ let node = ast_id. to_node ( db. upcast ( ) ) ;
710
+ ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & node) ) )
711
+ }
712
+ } ;
713
+ acc. push ( MacroError { node, message : message. clone ( ) } . into ( ) ) ;
714
+ }
715
+
716
+ DefDiagnosticKind :: UnimplementedBuiltinMacro { ast } => {
717
+ let node = ast. to_node ( db. upcast ( ) ) ;
718
+ // Must have a name, otherwise we wouldn't emit it.
719
+ let name = node. name ( ) . expect ( "unimplemented builtin macro with no name" ) ;
720
+ acc. push (
721
+ UnimplementedBuiltinMacro {
722
+ node : ast. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & name) ) ) ,
723
+ }
724
+ . into ( ) ,
725
+ ) ;
726
+ }
727
+ DefDiagnosticKind :: InvalidDeriveTarget { ast, id } => {
728
+ let node = ast. to_node ( db. upcast ( ) ) ;
729
+ let derive = node. attrs ( ) . nth ( * id as usize ) ;
730
+ match derive {
731
+ Some ( derive) => {
732
+ acc. push (
733
+ InvalidDeriveTarget {
734
+ node : ast. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & derive) ) ) ,
735
+ }
736
+ . into ( ) ,
737
+ ) ;
738
+ }
739
+ None => stdx:: never!( "derive diagnostic on item without derive attribute" ) ,
740
+ }
741
+ }
742
+ DefDiagnosticKind :: MalformedDerive { ast, id } => {
743
+ let node = ast. to_node ( db. upcast ( ) ) ;
744
+ let derive = node. attrs ( ) . nth ( * id as usize ) ;
745
+ match derive {
746
+ Some ( derive) => {
747
+ acc. push (
748
+ MalformedDerive {
749
+ node : ast. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & derive) ) ) ,
750
+ }
751
+ . into ( ) ,
752
+ ) ;
753
+ }
754
+ None => stdx:: never!( "derive diagnostic on item without derive attribute" ) ,
755
+ }
756
+ }
757
+ }
758
+ }
759
+
770
760
impl HasVisibility for Module {
771
761
fn visibility ( & self , db : & dyn HirDatabase ) -> Visibility {
772
762
let def_map = self . id . def_map ( db. upcast ( ) ) ;
@@ -1107,7 +1097,14 @@ impl DefWithBody {
1107
1097
pub fn diagnostics ( self , db : & dyn HirDatabase , acc : & mut Vec < AnyDiagnostic > ) {
1108
1098
let krate = self . module ( db) . id . krate ( ) ;
1109
1099
1110
- let source_map = db. body_with_source_map ( self . into ( ) ) . 1 ;
1100
+ let ( body, source_map) = db. body_with_source_map ( self . into ( ) ) ;
1101
+
1102
+ for ( _, def_map) in body. blocks ( db. upcast ( ) ) {
1103
+ for diag in def_map. diagnostics ( ) {
1104
+ emit_def_diagnostic ( db, acc, diag) ;
1105
+ }
1106
+ }
1107
+
1111
1108
for diag in source_map. diagnostics ( ) {
1112
1109
match diag {
1113
1110
BodyDiagnostic :: InactiveCode { node, cfg, opts } => acc. push (
0 commit comments