@@ -10,6 +10,7 @@ use crate::{
1010 NavigationTarget , RunnableKind ,
1111 annotations:: fn_references:: find_all_methods,
1212 goto_implementation:: goto_implementation,
13+ navigation_target,
1314 references:: find_all_refs,
1415 runnables:: { Runnable , runnables} ,
1516} ;
@@ -148,15 +149,32 @@ pub(crate) fn annotations(
148149 node : InFile < T > ,
149150 source_file_id : FileId ,
150151 ) -> Option < ( TextRange , Option < TextRange > ) > {
151- if let Some ( InRealFile { file_id, value } ) = node. original_ast_node_rooted ( db) {
152- if file_id. file_id ( db) == source_file_id {
153- return Some ( (
154- value. syntax ( ) . text_range ( ) ,
155- value. name ( ) . map ( |name| name. syntax ( ) . text_range ( ) ) ,
156- ) ) ;
152+ if let Some ( name) = node. value . name ( ) . map ( |name| name. syntax ( ) . text_range ( ) ) {
153+ // if we have a name, try mapping that out of the macro expansion as we can put the
154+ // annotation on that name token
155+ // See `test_no_annotations_macro_struct_def` vs `test_annotations_macro_struct_def_call_site`
156+ let res = navigation_target:: orig_range_with_focus_r (
157+ db,
158+ node. file_id ,
159+ node. value . syntax ( ) . text_range ( ) ,
160+ Some ( name) ,
161+ ) ;
162+ if res. call_site . 0 . file_id == source_file_id {
163+ if let Some ( name_range) = res. call_site . 1 {
164+ return Some ( ( res. call_site . 0 . range , Some ( name_range) ) ) ;
165+ }
157166 }
167+ } ;
168+ // otherwise try upmapping the entire node out of attributes
169+ let InRealFile { file_id, value } = node. original_ast_node_rooted ( db) ?;
170+ if file_id. file_id ( db) == source_file_id {
171+ Some ( (
172+ value. syntax ( ) . text_range ( ) ,
173+ value. name ( ) . map ( |name| name. syntax ( ) . text_range ( ) ) ,
174+ ) )
175+ } else {
176+ None
158177 }
159- None
160178 }
161179 } ) ;
162180
@@ -913,6 +931,56 @@ m!();
913931 ) ;
914932 }
915933
934+ #[ test]
935+ fn test_annotations_macro_struct_def_call_site ( ) {
936+ check (
937+ r#"
938+ //- /lib.rs
939+ macro_rules! m {
940+ ($name:ident) => {
941+ struct $name {}
942+ };
943+ }
944+
945+ m! {
946+ Name
947+ };
948+ "# ,
949+ expect ! [ [ r#"
950+ [
951+ Annotation {
952+ range: 83..87,
953+ kind: HasImpls {
954+ pos: FilePositionWrapper {
955+ file_id: FileId(
956+ 0,
957+ ),
958+ offset: 83,
959+ },
960+ data: Some(
961+ [],
962+ ),
963+ },
964+ },
965+ Annotation {
966+ range: 83..87,
967+ kind: HasReferences {
968+ pos: FilePositionWrapper {
969+ file_id: FileId(
970+ 0,
971+ ),
972+ offset: 83,
973+ },
974+ data: Some(
975+ [],
976+ ),
977+ },
978+ },
979+ ]
980+ "# ] ] ,
981+ ) ;
982+ }
983+
916984 #[ test]
917985 fn test_annotations_appear_above_whole_item_when_configured_to_do_so ( ) {
918986 check_with_config (
0 commit comments