diff --git a/crates/hir-def/src/nameres/assoc.rs b/crates/hir-def/src/nameres/assoc.rs index d45709b8b9..86225d33b4 100644 --- a/crates/hir-def/src/nameres/assoc.rs +++ b/crates/hir-def/src/nameres/assoc.rs @@ -75,7 +75,7 @@ impl TraitItems { }) } - pub fn attribute_calls(&self) -> impl Iterator, MacroCallId)> + '_ { + pub fn macro_calls(&self) -> impl Iterator, MacroCallId)> + '_ { self.macro_calls.iter().flat_map(|it| it.iter()).copied() } } @@ -109,7 +109,7 @@ impl ImplItems { (Arc::new(ImplItems { items, macro_calls }), DefDiagnostics::new(diagnostics)) } - pub fn attribute_calls(&self) -> impl Iterator, MacroCallId)> + '_ { + pub fn macro_calls(&self) -> impl Iterator, MacroCallId)> + '_ { self.macro_calls.iter().flat_map(|it| it.iter()).copied() } } diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 117d9c4920..5823f6260b 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -408,11 +408,7 @@ impl<'db> SemanticsImpl<'db> { } pub fn expand_macro_call(&self, macro_call: &ast::MacroCall) -> Option> { - let sa = self.analyze_no_infer(macro_call.syntax())?; - - let macro_call = InFile::new(sa.file_id, macro_call); - let file_id = sa.expansion(self.db, macro_call)?; - + let file_id = self.to_def(macro_call)?; let node = self.parse_or_expand(file_id.into()); Some(InFile::new(file_id.into(), node)) } @@ -434,10 +430,7 @@ impl<'db> SemanticsImpl<'db> { &self, macro_call: &ast::MacroCall, ) -> Option> { - let sa = self.analyze_no_infer(macro_call.syntax())?; - - let macro_call = InFile::new(sa.file_id, macro_call); - let file_id = sa.expansion(self.db, macro_call)?; + let file_id = self.to_def(macro_call)?; let macro_call = self.db.lookup_intern_macro_call(file_id); let skip = matches!( @@ -1097,16 +1090,7 @@ impl<'db> SemanticsImpl<'db> { let file_id = match m_cache.get(&mcall) { Some(&it) => it, None => { - let it = token - .parent() - .and_then(|parent| { - self.analyze_impl( - InFile::new(expansion, &parent), - None, - false, - ) - })? - .expansion(self.db, mcall.as_ref())?; + let it = ast::MacroCall::to_def(self, mcall.as_ref())?; m_cache.insert(mcall, it); it } @@ -1562,14 +1546,8 @@ impl<'db> SemanticsImpl<'db> { } pub fn resolve_macro_call_arm(&self, macro_call: &ast::MacroCall) -> Option { - let sa = self.analyze(macro_call.syntax())?; - self.db - .parse_macro_expansion( - sa.expansion(self.db, self.wrap_node_infile(macro_call.clone()).as_ref())?, - ) - .value - .1 - .matched_arm + let file_id = self.to_def(macro_call)?; + self.db.parse_macro_expansion(file_id).value.1.matched_arm } pub fn get_unsafe_ops(&self, def: DefWithBody) -> FxHashSet { diff --git a/crates/hir/src/semantics/child_by_source.rs b/crates/hir/src/semantics/child_by_source.rs index 9393d08ad3..6accf9b2e9 100644 --- a/crates/hir/src/semantics/child_by_source.rs +++ b/crates/hir/src/semantics/child_by_source.rs @@ -36,9 +36,14 @@ impl ChildBySource for TraitId { fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) { let data = db.trait_items(*self); - data.attribute_calls().filter(|(ast_id, _)| ast_id.file_id == file_id).for_each( + data.macro_calls().filter(|(ast_id, _)| ast_id.file_id == file_id).for_each( |(ast_id, call_id)| { - res[keys::ATTR_MACRO_CALL].insert(ast_id.to_ptr(db), call_id); + let ptr = ast_id.to_ptr(db); + if let Some(ptr) = ptr.cast::() { + res[keys::MACRO_CALL].insert(ptr, call_id); + } else { + res[keys::ATTR_MACRO_CALL].insert(ptr, call_id); + } }, ); data.items.iter().for_each(|&(_, item)| { @@ -50,10 +55,14 @@ impl ChildBySource for TraitId { impl ChildBySource for ImplId { fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) { let data = db.impl_items(*self); - // FIXME: Macro calls - data.attribute_calls().filter(|(ast_id, _)| ast_id.file_id == file_id).for_each( + data.macro_calls().filter(|(ast_id, _)| ast_id.file_id == file_id).for_each( |(ast_id, call_id)| { - res[keys::ATTR_MACRO_CALL].insert(ast_id.to_ptr(db), call_id); + let ptr = ast_id.to_ptr(db); + if let Some(ptr) = ptr.cast::() { + res[keys::MACRO_CALL].insert(ptr, call_id); + } else { + res[keys::ATTR_MACRO_CALL].insert(ptr, call_id); + } }, ); data.items.iter().for_each(|&(_, item)| { diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs index 9beed2cac1..f8f9378b9e 100644 --- a/crates/ide/src/expand_macro.rs +++ b/crates/ide/src/expand_macro.rs @@ -719,4 +719,44 @@ __log!(written:%; "Test"$0); "#]], ); } + + #[test] + fn assoc_call() { + check( + r#" +macro_rules! mac { + () => { fn assoc() {} } +} +impl () { + mac$0!(); +} + "#, + expect![[r#" + mac! + fn assoc(){}"#]], + ); + } + + #[test] + fn eager() { + check( + r#" +//- minicore: concat +macro_rules! my_concat { + ($head:expr, $($tail:tt)*) => { concat!($head, $($tail)*) }; +} + + +fn test() { + _ = my_concat!( + conc$0at!("<", ">"), + "hi", + ); +} + "#, + expect![[r#" + my_concat! + "<>hi""#]], + ); + } } diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 671e838421..12b393b80c 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -1023,7 +1023,7 @@ impl flags::AnalysisStats { percentage(num_pats_partially_unknown, num_pats), num_pat_type_mismatches ); - eprintln!(" panics: {}", panics); + eprintln!(" panics: {panics}"); eprintln!("{:<20} {}", "Inference:", inference_time); report_metric("unknown type", num_exprs_unknown, "#"); report_metric("type mismatches", num_expr_type_mismatches, "#");