@@ -4,7 +4,9 @@ pub mod adt;
44
55use std:: sync:: Arc ;
66
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+ } ;
810use intern:: Interned ;
911use smallvec:: SmallVec ;
1012use syntax:: { ast, Parse } ;
@@ -13,7 +15,9 @@ use crate::{
1315 attr:: Attrs ,
1416 db:: DefDatabase ,
1517 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+ } ,
1721 macro_call_as_call_id, macro_id_to_def_id,
1822 nameres:: {
1923 attr_resolution:: ResolvedAttr ,
@@ -520,7 +524,7 @@ struct AssocItemCollector<'a> {
520524 db : & ' a dyn DefDatabase ,
521525 module_id : ModuleId ,
522526 def_map : Arc < DefMap > ,
523- inactive_diagnostics : Vec < DefDiagnostic > ,
527+ diagnostics : Vec < DefDiagnostic > ,
524528 container : ItemContainerId ,
525529 expander : Expander ,
526530
@@ -543,7 +547,7 @@ impl<'a> AssocItemCollector<'a> {
543547 expander : Expander :: new ( db, file_id, module_id) ,
544548 items : Vec :: new ( ) ,
545549 attr_calls : Vec :: new ( ) ,
546- inactive_diagnostics : Vec :: new ( ) ,
550+ diagnostics : Vec :: new ( ) ,
547551 }
548552 }
549553
@@ -557,19 +561,18 @@ impl<'a> AssocItemCollector<'a> {
557561 (
558562 self . items ,
559563 if self . attr_calls . is_empty ( ) { None } else { Some ( Box :: new ( self . attr_calls ) ) } ,
560- self . inactive_diagnostics ,
564+ self . diagnostics ,
561565 )
562566 }
563567
564- // FIXME: proc-macro diagnostics
565568 fn collect ( & mut self , item_tree : & ItemTree , tree_id : TreeId , assoc_items : & [ AssocItem ] ) {
566569 let container = self . container ;
567570 self . items . reserve ( assoc_items. len ( ) ) ;
568571
569572 ' items: for & item in assoc_items {
570573 let attrs = item_tree. attrs ( self . db , self . module_id . krate , ModItem :: from ( item) . into ( ) ) ;
571574 if !attrs. is_cfg_enabled ( self . expander . cfg_options ( ) ) {
572- self . inactive_diagnostics . push ( DefDiagnostic :: unconfigured_code (
575+ self . diagnostics . push ( DefDiagnostic :: unconfigured_code (
573576 self . module_id . local_id ,
574577 InFile :: new ( self . expander . current_file_id ( ) , item. ast_id ( item_tree) . upcast ( ) ) ,
575578 attrs. cfg ( ) . unwrap ( ) ,
@@ -583,91 +586,126 @@ impl<'a> AssocItemCollector<'a> {
583586 AstId :: new ( self . expander . current_file_id ( ) , item. ast_id ( item_tree) . upcast ( ) ) ;
584587 let ast_id_with_path = AstIdWithPath { path : ( * attr. path ) . clone ( ) , ast_id } ;
585588
586- if let Ok ( ResolvedAttr :: Macro ( call_id ) ) = self . def_map . resolve_attr_macro (
589+ match self . def_map . resolve_attr_macro (
587590 self . db ,
588591 self . module_id . local_id ,
589592 ast_id_with_path,
590593 attr,
591594 ) {
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 ( ) {
605599 continue ' attrs;
606600 }
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+ }
608612
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+ }
612631 }
613632 }
614633
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+ }
618637
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] ;
636648
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) ) => {
664691 let res =
665692 self . expander . enter_expand_id :: < ast:: MacroItems > ( self . db , call_id) ;
666693 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) ,
668695 expand_to : hir_expand:: ExpandTo :: Items ,
669696 } ) ;
670697 }
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+ }
671709 }
672710 }
673711 }
@@ -681,14 +719,25 @@ impl<'a> AssocItemCollector<'a> {
681719 let Some ( ( mark, parse) ) = value else { return } ;
682720
683721 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) ;
689738 }
690739 if let errors @ [ _, ..] = parse. errors ( ) {
691- self . inactive_diagnostics . push ( DefDiagnostic :: macro_expansion_parse_error (
740+ self . diagnostics . push ( DefDiagnostic :: macro_expansion_parse_error (
692741 self . module_id . local_id ,
693742 error_call_kind ( ) ,
694743 errors. into ( ) ,
0 commit comments