@@ -4,7 +4,9 @@ pub mod adt;
4
4
5
5
use std:: sync:: Arc ;
6
6
7
- use hir_expand:: { name:: Name , AstId , ExpandResult , HirFileId , InFile , MacroCallId , MacroDefKind } ;
7
+ use hir_expand:: {
8
+ name:: Name , AstId , ExpandResult , HirFileId , InFile , MacroCallId , MacroCallKind , MacroDefKind ,
9
+ } ;
8
10
use intern:: Interned ;
9
11
use smallvec:: SmallVec ;
10
12
use syntax:: { ast, Parse } ;
@@ -13,7 +15,9 @@ use crate::{
13
15
attr:: Attrs ,
14
16
db:: DefDatabase ,
15
17
expander:: { Expander , Mark } ,
16
- item_tree:: { self , AssocItem , FnFlags , ItemTree , ItemTreeId , ModItem , Param , TreeId } ,
18
+ item_tree:: {
19
+ self , AssocItem , FnFlags , ItemTree , ItemTreeId , MacroCall , ModItem , Param , TreeId ,
20
+ } ,
17
21
macro_call_as_call_id, macro_id_to_def_id,
18
22
nameres:: {
19
23
attr_resolution:: ResolvedAttr ,
@@ -520,7 +524,7 @@ struct AssocItemCollector<'a> {
520
524
db : & ' a dyn DefDatabase ,
521
525
module_id : ModuleId ,
522
526
def_map : Arc < DefMap > ,
523
- inactive_diagnostics : Vec < DefDiagnostic > ,
527
+ diagnostics : Vec < DefDiagnostic > ,
524
528
container : ItemContainerId ,
525
529
expander : Expander ,
526
530
@@ -543,7 +547,7 @@ impl<'a> AssocItemCollector<'a> {
543
547
expander : Expander :: new ( db, file_id, module_id) ,
544
548
items : Vec :: new ( ) ,
545
549
attr_calls : Vec :: new ( ) ,
546
- inactive_diagnostics : Vec :: new ( ) ,
550
+ diagnostics : Vec :: new ( ) ,
547
551
}
548
552
}
549
553
@@ -557,19 +561,18 @@ impl<'a> AssocItemCollector<'a> {
557
561
(
558
562
self . items ,
559
563
if self . attr_calls . is_empty ( ) { None } else { Some ( Box :: new ( self . attr_calls ) ) } ,
560
- self . inactive_diagnostics ,
564
+ self . diagnostics ,
561
565
)
562
566
}
563
567
564
- // FIXME: proc-macro diagnostics
565
568
fn collect ( & mut self , item_tree : & ItemTree , tree_id : TreeId , assoc_items : & [ AssocItem ] ) {
566
569
let container = self . container ;
567
570
self . items . reserve ( assoc_items. len ( ) ) ;
568
571
569
572
' items: for & item in assoc_items {
570
573
let attrs = item_tree. attrs ( self . db , self . module_id . krate , ModItem :: from ( item) . into ( ) ) ;
571
574
if !attrs. is_cfg_enabled ( self . expander . cfg_options ( ) ) {
572
- self . inactive_diagnostics . push ( DefDiagnostic :: unconfigured_code (
575
+ self . diagnostics . push ( DefDiagnostic :: unconfigured_code (
573
576
self . module_id . local_id ,
574
577
InFile :: new ( self . expander . current_file_id ( ) , item. ast_id ( item_tree) . upcast ( ) ) ,
575
578
attrs. cfg ( ) . unwrap ( ) ,
@@ -583,91 +586,126 @@ impl<'a> AssocItemCollector<'a> {
583
586
AstId :: new ( self . expander . current_file_id ( ) , item. ast_id ( item_tree) . upcast ( ) ) ;
584
587
let ast_id_with_path = AstIdWithPath { path : ( * attr. path ) . clone ( ) , ast_id } ;
585
588
586
- if let Ok ( ResolvedAttr :: Macro ( call_id ) ) = self . def_map . resolve_attr_macro (
589
+ match self . def_map . resolve_attr_macro (
587
590
self . db ,
588
591
self . module_id . local_id ,
589
592
ast_id_with_path,
590
593
attr,
591
594
) {
592
- self . attr_calls . push ( ( ast_id, call_id) ) ;
593
- // If proc attribute macro expansion is disabled, skip expanding it here
594
- if !self . db . expand_proc_attr_macros ( ) {
595
- continue ' attrs;
596
- }
597
- let loc = self . db . lookup_intern_macro_call ( call_id) ;
598
- if let MacroDefKind :: ProcMacro ( exp, ..) = loc. def . kind {
599
- // If there's no expander for the proc macro (e.g. the
600
- // proc macro is ignored, or building the proc macro
601
- // crate failed), skip expansion like we would if it was
602
- // disabled. This is analogous to the handling in
603
- // `DefCollector::collect_macros`.
604
- if exp. is_dummy ( ) {
595
+ Ok ( ResolvedAttr :: Macro ( call_id) ) => {
596
+ self . attr_calls . push ( ( ast_id, call_id) ) ;
597
+ // If proc attribute macro expansion is disabled, skip expanding it here
598
+ if !self . db . expand_proc_attr_macros ( ) {
605
599
continue ' attrs;
606
600
}
607
- }
601
+ let loc = self . db . lookup_intern_macro_call ( call_id) ;
602
+ if let MacroDefKind :: ProcMacro ( exp, ..) = loc. def . kind {
603
+ // If there's no expander for the proc macro (e.g. the
604
+ // proc macro is ignored, or building the proc macro
605
+ // crate failed), skip expansion like we would if it was
606
+ // disabled. This is analogous to the handling in
607
+ // `DefCollector::collect_macros`.
608
+ if exp. is_dummy ( ) {
609
+ continue ' attrs;
610
+ }
611
+ }
608
612
609
- let res = self . expander . enter_expand_id :: < ast:: MacroItems > ( self . db , call_id) ;
610
- self . collect_macro_items ( res, & || loc. kind . clone ( ) ) ;
611
- continue ' items;
613
+ let res =
614
+ self . expander . enter_expand_id :: < ast:: MacroItems > ( self . db , call_id) ;
615
+ self . collect_macro_items ( res, & || loc. kind . clone ( ) ) ;
616
+ continue ' items;
617
+ }
618
+ Ok ( _) => ( ) ,
619
+ Err ( _) => {
620
+ self . diagnostics . push ( DefDiagnostic :: unresolved_macro_call (
621
+ self . module_id . local_id ,
622
+ MacroCallKind :: Attr {
623
+ ast_id,
624
+ attr_args : Arc :: new ( ( tt:: Subtree :: empty ( ) , Default :: default ( ) ) ) ,
625
+ invoc_attr_index : attr. id ,
626
+ is_derive : false ,
627
+ } ,
628
+ attr. path ( ) . clone ( ) ,
629
+ ) ) ;
630
+ }
612
631
}
613
632
}
614
633
615
- match item {
616
- AssocItem :: Function ( id ) => {
617
- let item = & item_tree [ id ] ;
634
+ self . collect_item ( item_tree , tree_id , container , item ) ;
635
+ }
636
+ }
618
637
619
- let def =
620
- FunctionLoc { container, id : ItemTreeId :: new ( tree_id, id) } . intern ( self . db ) ;
621
- self . items . push ( ( item. name . clone ( ) , def. into ( ) ) ) ;
622
- }
623
- AssocItem :: Const ( id) => {
624
- let item = & item_tree[ id] ;
625
-
626
- let name = match item. name . clone ( ) {
627
- Some ( name) => name,
628
- None => continue ,
629
- } ;
630
- let def =
631
- ConstLoc { container, id : ItemTreeId :: new ( tree_id, id) } . intern ( self . db ) ;
632
- self . items . push ( ( name, def. into ( ) ) ) ;
633
- }
634
- AssocItem :: TypeAlias ( id) => {
635
- let item = & item_tree[ id] ;
638
+ fn collect_item (
639
+ & mut self ,
640
+ item_tree : & ItemTree ,
641
+ tree_id : TreeId ,
642
+ container : ItemContainerId ,
643
+ item : AssocItem ,
644
+ ) {
645
+ match item {
646
+ AssocItem :: Function ( id) => {
647
+ let item = & item_tree[ id] ;
636
648
637
- let def = TypeAliasLoc { container, id : ItemTreeId :: new ( tree_id, id) }
638
- . intern ( self . db ) ;
639
- self . items . push ( ( item. name . clone ( ) , def. into ( ) ) ) ;
640
- }
641
- AssocItem :: MacroCall ( call) => {
642
- let file_id = self . expander . current_file_id ( ) ;
643
- let call = & item_tree[ call] ;
644
- let module = self . expander . module . local_id ;
645
-
646
- if let Ok ( Some ( call_id) ) = macro_call_as_call_id (
647
- self . db . upcast ( ) ,
648
- & AstIdWithPath :: new ( file_id, call. ast_id , Clone :: clone ( & call. path ) ) ,
649
- call. expand_to ,
650
- self . expander . module . krate ( ) ,
651
- |path| {
652
- self . def_map
653
- . resolve_path (
654
- self . db ,
655
- module,
656
- & path,
657
- crate :: item_scope:: BuiltinShadowMode :: Other ,
658
- )
659
- . 0
660
- . take_macros ( )
661
- . map ( |it| macro_id_to_def_id ( self . db , it) )
662
- } ,
663
- ) {
649
+ let def =
650
+ FunctionLoc { container, id : ItemTreeId :: new ( tree_id, id) } . intern ( self . db ) ;
651
+ self . items . push ( ( item. name . clone ( ) , def. into ( ) ) ) ;
652
+ }
653
+ AssocItem :: Const ( id) => {
654
+ let item = & item_tree[ id] ;
655
+ let Some ( name) = item. name . clone ( ) else { return } ;
656
+ let def = ConstLoc { container, id : ItemTreeId :: new ( tree_id, id) } . intern ( self . db ) ;
657
+ self . items . push ( ( name, def. into ( ) ) ) ;
658
+ }
659
+ AssocItem :: TypeAlias ( id) => {
660
+ let item = & item_tree[ id] ;
661
+
662
+ let def =
663
+ TypeAliasLoc { container, id : ItemTreeId :: new ( tree_id, id) } . intern ( self . db ) ;
664
+ self . items . push ( ( item. name . clone ( ) , def. into ( ) ) ) ;
665
+ }
666
+ AssocItem :: MacroCall ( call) => {
667
+ let file_id = self . expander . current_file_id ( ) ;
668
+ let MacroCall { ast_id, expand_to, ref path } = item_tree[ call] ;
669
+ let module = self . expander . module . local_id ;
670
+
671
+ let resolver = |path| {
672
+ self . def_map
673
+ . resolve_path (
674
+ self . db ,
675
+ module,
676
+ & path,
677
+ crate :: item_scope:: BuiltinShadowMode :: Other ,
678
+ )
679
+ . 0
680
+ . take_macros ( )
681
+ . map ( |it| macro_id_to_def_id ( self . db , it) )
682
+ } ;
683
+ match macro_call_as_call_id (
684
+ self . db . upcast ( ) ,
685
+ & AstIdWithPath :: new ( file_id, ast_id, Clone :: clone ( path) ) ,
686
+ expand_to,
687
+ self . expander . module . krate ( ) ,
688
+ resolver,
689
+ ) {
690
+ Ok ( Some ( call_id) ) => {
664
691
let res =
665
692
self . expander . enter_expand_id :: < ast:: MacroItems > ( self . db , call_id) ;
666
693
self . collect_macro_items ( res, & || hir_expand:: MacroCallKind :: FnLike {
667
- ast_id : InFile :: new ( file_id, call . ast_id ) ,
694
+ ast_id : InFile :: new ( file_id, ast_id) ,
668
695
expand_to : hir_expand:: ExpandTo :: Items ,
669
696
} ) ;
670
697
}
698
+ Ok ( None ) => ( ) ,
699
+ Err ( _) => {
700
+ self . diagnostics . push ( DefDiagnostic :: unresolved_macro_call (
701
+ self . module_id . local_id ,
702
+ MacroCallKind :: FnLike {
703
+ ast_id : InFile :: new ( file_id, ast_id) ,
704
+ expand_to,
705
+ } ,
706
+ Clone :: clone ( path) ,
707
+ ) ) ;
708
+ }
671
709
}
672
710
}
673
711
}
@@ -681,14 +719,25 @@ impl<'a> AssocItemCollector<'a> {
681
719
let Some ( ( mark, parse) ) = value else { return } ;
682
720
683
721
if let Some ( err) = err {
684
- self . inactive_diagnostics . push ( DefDiagnostic :: macro_error (
685
- self . module_id . local_id ,
686
- error_call_kind ( ) ,
687
- err. to_string ( ) ,
688
- ) ) ;
722
+ let diag = match err {
723
+ // why is this reported here?
724
+ hir_expand:: ExpandError :: UnresolvedProcMacro ( krate) => {
725
+ DefDiagnostic :: unresolved_proc_macro (
726
+ self . module_id . local_id ,
727
+ error_call_kind ( ) ,
728
+ krate,
729
+ )
730
+ }
731
+ _ => DefDiagnostic :: macro_error (
732
+ self . module_id . local_id ,
733
+ error_call_kind ( ) ,
734
+ err. to_string ( ) ,
735
+ ) ,
736
+ } ;
737
+ self . diagnostics . push ( diag) ;
689
738
}
690
739
if let errors @ [ _, ..] = parse. errors ( ) {
691
- self . inactive_diagnostics . push ( DefDiagnostic :: macro_expansion_parse_error (
740
+ self . diagnostics . push ( DefDiagnostic :: macro_expansion_parse_error (
692
741
self . module_id . local_id ,
693
742
error_call_kind ( ) ,
694
743
errors. into ( ) ,
0 commit comments