diff --git a/crates/ide/src/annotations.rs b/crates/ide/src/annotations.rs index 72492f8266..64bc926f1c 100644 --- a/crates/ide/src/annotations.rs +++ b/crates/ide/src/annotations.rs @@ -1,5 +1,5 @@ use either::Either; -use hir::{HasSource, Semantics}; +use hir::{HasSource, InFile, Semantics}; use ide_db::{ base_db::{FileId, FilePosition, FileRange}, helpers::visit_file_defs, @@ -80,19 +80,19 @@ pub(crate) fn annotations( Either::Left(def) => { let node = match def { hir::ModuleDef::Const(konst) => { - konst.source(db).and_then(|node| range_and_position_of(&node.value)) + konst.source(db).and_then(|node| range_and_position_of(&node, file_id)) } hir::ModuleDef::Trait(trait_) => { - trait_.source(db).and_then(|node| range_and_position_of(&node.value)) + trait_.source(db).and_then(|node| range_and_position_of(&node, file_id)) } hir::ModuleDef::Adt(hir::Adt::Struct(strukt)) => { - strukt.source(db).and_then(|node| range_and_position_of(&node.value)) + strukt.source(db).and_then(|node| range_and_position_of(&node, file_id)) } hir::ModuleDef::Adt(hir::Adt::Enum(enum_)) => { - enum_.source(db).and_then(|node| range_and_position_of(&node.value)) + enum_.source(db).and_then(|node| range_and_position_of(&node, file_id)) } hir::ModuleDef::Adt(hir::Adt::Union(union)) => { - union.source(db).and_then(|node| range_and_position_of(&node.value)) + union.source(db).and_then(|node| range_and_position_of(&node, file_id)) } _ => None, }; @@ -120,8 +120,19 @@ pub(crate) fn annotations( }); } - fn range_and_position_of(node: &dyn NameOwner) -> Option<(TextSize, TextRange)> { - Some((node.name()?.syntax().text_range().start(), node.syntax().text_range())) + fn range_and_position_of( + node: &InFile, + file_id: FileId, + ) -> Option<(TextSize, TextRange)> { + if node.file_id != file_id.into() { + // Node is outside the file we are adding annotations to (e.g. macros). + None + } else { + Some(( + node.value.name()?.syntax().text_range().start(), + node.value.syntax().text_range(), + )) + } } } Either::Right(_) => (), @@ -961,6 +972,25 @@ mod tests { struct Foo; //- /lib.rs // this file comes last since `check` checks the first file only +"#, + expect![[r#" + [] + "#]], + ); + } + + #[test] + fn test_no_annotations_macro_struct_def() { + check( + r#" +//- /lib.rs +macro_rules! m { + () => { + struct A {} + }; +} + +m!(); "#, expect![[r#" []