aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-03-24 10:17:12 +0000
committerGitHub <[email protected]>2021-03-24 10:17:12 +0000
commit2aa64831e578406f85e68adf27e519175e1e532d (patch)
treeac288ca7b8a25ea41d8b66ed2deeedb33d5c8df8
parent5f9ba2d589afaaec91ee79bfc7fa3aba636916f2 (diff)
parent903a2e98f93df87af19375e951c56e7c285989d4 (diff)
Merge #8183
8183: Fix missing command error with macros r=Veykril a=brandondong **Reproduction:** 1. Define a struct through a macro (can be via `macro_rules`, proc macro, or `include!()`). 2. !!MISSING: command!! annotation appears. Clicking on it results in an error message. No matter where the macro is called/defined, the annotation is always at the start of the file. ![image](https://user-images.githubusercontent.com/13722457/112268785-bce14500-8c34-11eb-9a23-bafd63ffd6ef.png) **Cause:** - For struct `A`, a `HasImpls` annotation is added just like for struct `B`. Unlike `B`, the file id for `A` is not the file we are adding annotations to but a macro file. - The resolving step of the code lens does not succeed. **Fix:** - Check that the files match before computing offsets and adding `HasImpls`/`HasReferences` annotations. Co-authored-by: Brandon <[email protected]>
-rw-r--r--crates/ide/src/annotations.rs46
1 files changed, 38 insertions, 8 deletions
diff --git a/crates/ide/src/annotations.rs b/crates/ide/src/annotations.rs
index 72492f826..64bc926f1 100644
--- a/crates/ide/src/annotations.rs
+++ b/crates/ide/src/annotations.rs
@@ -1,5 +1,5 @@
1use either::Either; 1use either::Either;
2use hir::{HasSource, Semantics}; 2use hir::{HasSource, InFile, Semantics};
3use ide_db::{ 3use ide_db::{
4 base_db::{FileId, FilePosition, FileRange}, 4 base_db::{FileId, FilePosition, FileRange},
5 helpers::visit_file_defs, 5 helpers::visit_file_defs,
@@ -80,19 +80,19 @@ pub(crate) fn annotations(
80 Either::Left(def) => { 80 Either::Left(def) => {
81 let node = match def { 81 let node = match def {
82 hir::ModuleDef::Const(konst) => { 82 hir::ModuleDef::Const(konst) => {
83 konst.source(db).and_then(|node| range_and_position_of(&node.value)) 83 konst.source(db).and_then(|node| range_and_position_of(&node, file_id))
84 } 84 }
85 hir::ModuleDef::Trait(trait_) => { 85 hir::ModuleDef::Trait(trait_) => {
86 trait_.source(db).and_then(|node| range_and_position_of(&node.value)) 86 trait_.source(db).and_then(|node| range_and_position_of(&node, file_id))
87 } 87 }
88 hir::ModuleDef::Adt(hir::Adt::Struct(strukt)) => { 88 hir::ModuleDef::Adt(hir::Adt::Struct(strukt)) => {
89 strukt.source(db).and_then(|node| range_and_position_of(&node.value)) 89 strukt.source(db).and_then(|node| range_and_position_of(&node, file_id))
90 } 90 }
91 hir::ModuleDef::Adt(hir::Adt::Enum(enum_)) => { 91 hir::ModuleDef::Adt(hir::Adt::Enum(enum_)) => {
92 enum_.source(db).and_then(|node| range_and_position_of(&node.value)) 92 enum_.source(db).and_then(|node| range_and_position_of(&node, file_id))
93 } 93 }
94 hir::ModuleDef::Adt(hir::Adt::Union(union)) => { 94 hir::ModuleDef::Adt(hir::Adt::Union(union)) => {
95 union.source(db).and_then(|node| range_and_position_of(&node.value)) 95 union.source(db).and_then(|node| range_and_position_of(&node, file_id))
96 } 96 }
97 _ => None, 97 _ => None,
98 }; 98 };
@@ -120,8 +120,19 @@ pub(crate) fn annotations(
120 }); 120 });
121 } 121 }
122 122
123 fn range_and_position_of(node: &dyn NameOwner) -> Option<(TextSize, TextRange)> { 123 fn range_and_position_of<T: NameOwner>(
124 Some((node.name()?.syntax().text_range().start(), node.syntax().text_range())) 124 node: &InFile<T>,
125 file_id: FileId,
126 ) -> Option<(TextSize, TextRange)> {
127 if node.file_id != file_id.into() {
128 // Node is outside the file we are adding annotations to (e.g. macros).
129 None
130 } else {
131 Some((
132 node.value.name()?.syntax().text_range().start(),
133 node.value.syntax().text_range(),
134 ))
135 }
125 } 136 }
126 } 137 }
127 Either::Right(_) => (), 138 Either::Right(_) => (),
@@ -967,4 +978,23 @@ struct Foo;
967 "#]], 978 "#]],
968 ); 979 );
969 } 980 }
981
982 #[test]
983 fn test_no_annotations_macro_struct_def() {
984 check(
985 r#"
986//- /lib.rs
987macro_rules! m {
988 () => {
989 struct A {}
990 };
991}
992
993m!();
994"#,
995 expect![[r#"
996 []
997 "#]],
998 );
999 }
970} 1000}