diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index ed27f6122b..e53d126928 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -16,7 +16,6 @@ use itertools::Itertools; use rustc_hash::{FxHashMap, FxHashSet}; use smallvec::{smallvec, SmallVec}; use syntax::{ - algo::find_node_at_offset, ast::{self, GenericParamsOwner, LoopBodyOwner}, match_ast, AstNode, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextSize, }; @@ -241,10 +240,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { node: &SyntaxNode, offset: TextSize, ) -> Option { - if let Some(it) = find_node_at_offset(node, offset) { - return Some(it); - } - self.imp.descend_node_at_offset(node, offset).flatten().find_map(N::cast) } diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs index 8ec5e10c4d..079f847030 100644 --- a/crates/ide/src/expand_macro.rs +++ b/crates/ide/src/expand_macro.rs @@ -31,6 +31,7 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< SyntaxKind::IDENT => 1, _ => 0, })?; + let descended = sema.descend_into_macros(tok.clone()); if let Some(attr) = descended.ancestors().find_map(ast::Attr::cast) { if let Some((path, tt)) = attr.as_simple_call() { @@ -45,6 +46,9 @@ pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option< } } } + + // FIXME: Intermix attribute and bang! expansions + // currently we only recursively expand one of the two types let mut expanded = None; let mut name = None; for node in tok.ancestors() { diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 68b75f3ffc..f8ddcdd9a4 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -1661,6 +1661,28 @@ id! { ); } + #[test] + fn test_hover_through_attr() { + check( + r#" +//- proc_macros: identity +#[proc_macros::identity] +fn foo$0() {} +"#, + expect![[r#" + *foo* + + ```rust + test + ``` + + ```rust + fn foo() + ``` + "#]], + ); + } + #[test] fn test_hover_through_expr_in_macro() { check( diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 8c3ad0fced..c39d00b6e7 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs @@ -1507,4 +1507,23 @@ fn f() { "#]], ) } + + #[test] + fn attr_expanded() { + check( + r#" +//- proc_macros: identity + +#[proc_macros::identity] +fn func$0() { + func(); +} +"#, + expect![[r#" + func Function FileId(0) 26..51 29..33 + + FileId(0) 42..46 + "#]], + ) + } } diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index a4297a2fec..a495e6c543 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs @@ -1880,4 +1880,26 @@ fn main() { f$0() } "error: No identifier available to rename", ) } + + #[test] + fn attributed_item() { + check( + "function", + r#" +//- proc_macros: identity + +#[proc_macros::identity] +fn func$0() { + func(); +} +"#, + r#" + +#[proc_macros::identity] +fn function() { + function(); +} +"#, + ) + } } diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 6b74ec3430..376384670a 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs @@ -1737,6 +1737,88 @@ fn t1() {} ); } + #[test] + fn attributed_module() { + check( + r#" +//- proc_macros: identity +//- /lib.rs +$0 +#[proc_macros::identity] +mod module { + #[test] + fn t0() {} + #[test] + fn t1() {} +} +"#, + &[TestMod, Test, Test], + expect![[r#" + [ + Runnable { + use_name_in_title: true, + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 26..94, + focus_range: 30..36, + name: "module", + kind: Module, + description: "mod module", + }, + kind: TestMod { + path: "module", + }, + cfg: None, + }, + Runnable { + use_name_in_title: true, + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 43..65, + focus_range: 58..60, + name: "t0", + kind: Function, + }, + kind: Test { + test_id: Path( + "module::t0", + ), + attr: TestAttr { + ignore: false, + }, + }, + cfg: None, + }, + Runnable { + use_name_in_title: true, + nav: NavigationTarget { + file_id: FileId( + 0, + ), + full_range: 70..92, + focus_range: 85..87, + name: "t1", + kind: Function, + }, + kind: Test { + test_id: Path( + "module::t1", + ), + attr: TestAttr { + ignore: false, + }, + }, + cfg: None, + }, + ] + "#]], + ); + } + #[test] fn find_no_tests() { check_tests( diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index e43119aa3b..80533d1faa 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html @@ -51,14 +51,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd pub trait Copy {} } -pub mod ops { - #[lang = "fn_once"] +#[proc_macros::identity] +pub mod ops { + #[lang = "fn_once"] pub trait FnOnce<Args> {} - #[lang = "fn_mut"] + #[lang = "fn_mut"] pub trait FnMut<Args>: FnOnce<Args> {} - #[lang = "fn"] + #[lang = "fn"] pub trait Fn<Args>: FnMut<Args> {} } diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index 740127202f..6b08e916a9 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs @@ -10,6 +10,7 @@ use crate::{fixture, FileRange, HlTag, TextRange}; fn test_highlighting() { check_highlighting( r#" +//- proc_macros: identity //- /main.rs crate:main deps:foo use inner::{self as inner_mod}; mod inner {} @@ -23,6 +24,7 @@ pub mod marker { pub trait Copy {} } +#[proc_macros::identity] pub mod ops { #[lang = "fn_once"] pub trait FnOnce {}