@@ -74,7 +74,7 @@ use rustc_hash::FxHashSet;
7474use stdx:: { format_to, impl_from} ;
7575use syntax:: {
7676 ast:: { self , HasAttrs as _, HasDocComments , HasName } ,
77- AstNode , AstPtr , SmolStr , SyntaxKind , SyntaxNodePtr ,
77+ AstNode , AstPtr , SmolStr , SyntaxNodePtr , T ,
7878} ;
7979use tt:: { Ident , Leaf , Literal , TokenTree } ;
8080
@@ -628,43 +628,37 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
628628
629629 DefDiagnosticKind :: UnresolvedProcMacro { ast } => {
630630 let mut precise_location = None ;
631- let ( node, name ) = match ast {
631+ let ( node, macro_name ) = match ast {
632632 MacroCallKind :: FnLike { ast_id, .. } => {
633633 let node = ast_id. to_node ( db. upcast ( ) ) ;
634634 ( ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & node) ) ) , None )
635635 }
636- MacroCallKind :: Derive { ast_id, derive_name , .. } => {
636+ MacroCallKind :: Derive { ast_id, derive_attr_index , derive_index } => {
637637 let node = ast_id. to_node ( db. upcast ( ) ) ;
638638
639639 // Compute the precise location of the macro name's token in the derive
640640 // list.
641- // FIXME: This does not handle paths to the macro, but neither does the
642- // rest of r-a.
643- let derive_attrs =
644- node. attrs ( ) . filter_map ( |attr| match attr. as_simple_call ( ) {
645- Some ( ( name, args) ) if name == "derive" => Some ( args) ,
646- _ => None ,
647- } ) ;
648- ' outer: for attr in derive_attrs {
649- let tokens =
650- attr. syntax ( ) . children_with_tokens ( ) . filter_map ( |elem| match elem {
651- syntax:: NodeOrToken :: Node ( _) => None ,
641+ let token = ( || {
642+ let derive_attr = node. attrs ( ) . nth ( * derive_attr_index as usize ) ?;
643+ derive_attr
644+ . syntax ( )
645+ . children_with_tokens ( )
646+ . filter_map ( |elem| match elem {
652647 syntax:: NodeOrToken :: Token ( tok) => Some ( tok) ,
653- } ) ;
654- for token in tokens {
655- if token. kind ( ) == SyntaxKind :: IDENT && token. text ( ) == & * * derive_name {
656- precise_location = Some ( token. text_range ( ) ) ;
657- break ' outer;
658- }
659- }
660- }
661-
648+ _ => None ,
649+ } )
650+ . group_by ( |t| t. kind ( ) == T ! [ , ] )
651+ . into_iter ( )
652+ . nth ( * derive_index as usize )
653+ . and_then ( |( _, mut g) | g. find ( |t| t. kind ( ) == T ! [ ident] ) )
654+ } ) ( ) ;
655+ precise_location = token. as_ref ( ) . map ( |tok| tok. text_range ( ) ) ;
662656 (
663657 ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & node) ) ) ,
664- Some ( derive_name . clone ( ) ) ,
658+ token . as_ref ( ) . map ( ToString :: to_string ) ,
665659 )
666660 }
667- MacroCallKind :: Attr { ast_id, invoc_attr_index, attr_name , .. } => {
661+ MacroCallKind :: Attr { ast_id, invoc_attr_index, .. } => {
668662 let node = ast_id. to_node ( db. upcast ( ) ) ;
669663 let attr = node
670664 . doc_comments_and_attrs ( )
@@ -673,14 +667,15 @@ fn emit_def_diagnostic(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, diag:
673667 . unwrap_or_else ( || panic ! ( "cannot find attribute #{}" , invoc_attr_index) ) ;
674668 (
675669 ast_id. with_value ( SyntaxNodePtr :: from ( AstPtr :: new ( & attr) ) ) ,
676- Some ( attr_name. clone ( ) ) ,
670+ attr. path ( )
671+ . and_then ( |path| path. segment ( ) )
672+ . and_then ( |seg| seg. name_ref ( ) )
673+ . as_ref ( )
674+ . map ( ToString :: to_string) ,
677675 )
678676 }
679677 } ;
680- acc. push (
681- UnresolvedProcMacro { node, precise_location, macro_name : name. map ( Into :: into) }
682- . into ( ) ,
683- ) ;
678+ acc. push ( UnresolvedProcMacro { node, precise_location, macro_name } . into ( ) ) ;
684679 }
685680
686681 DefDiagnosticKind :: UnresolvedMacroCall { ast, path } => {
0 commit comments