mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Merge pull request #19879 from Veykril/push-mqykxnqtktuw
fix: Fix IDE layer not resolving some macro calls
This commit is contained in:
commit
a420ef2b17
@ -422,7 +422,6 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
|
|||||||
let makro = &item_tree[loc.id.value];
|
let makro = &item_tree[loc.id.value];
|
||||||
MacroDefId {
|
MacroDefId {
|
||||||
krate: loc.container.krate,
|
krate: loc.container.krate,
|
||||||
block: loc.container.block.map(|block| salsa::plumbing::AsId::as_id(&block)),
|
|
||||||
kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()),
|
kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()),
|
||||||
local_inner: false,
|
local_inner: false,
|
||||||
allow_internal_unsafe: loc.allow_internal_unsafe,
|
allow_internal_unsafe: loc.allow_internal_unsafe,
|
||||||
@ -436,7 +435,6 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
|
|||||||
let makro = &item_tree[loc.id.value];
|
let makro = &item_tree[loc.id.value];
|
||||||
MacroDefId {
|
MacroDefId {
|
||||||
krate: loc.container.krate,
|
krate: loc.container.krate,
|
||||||
block: loc.container.block.map(|block| salsa::plumbing::AsId::as_id(&block)),
|
|
||||||
kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()),
|
kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()),
|
||||||
local_inner: loc.flags.contains(MacroRulesLocFlags::LOCAL_INNER),
|
local_inner: loc.flags.contains(MacroRulesLocFlags::LOCAL_INNER),
|
||||||
allow_internal_unsafe: loc
|
allow_internal_unsafe: loc
|
||||||
@ -452,7 +450,6 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
|
|||||||
let makro = &item_tree[loc.id.value];
|
let makro = &item_tree[loc.id.value];
|
||||||
MacroDefId {
|
MacroDefId {
|
||||||
krate: loc.container.krate,
|
krate: loc.container.krate,
|
||||||
block: None,
|
|
||||||
kind: MacroDefKind::ProcMacro(
|
kind: MacroDefKind::ProcMacro(
|
||||||
InFile::new(loc.id.file_id(), makro.ast_id),
|
InFile::new(loc.id.file_id(), makro.ast_id),
|
||||||
loc.expander,
|
loc.expander,
|
||||||
|
@ -75,7 +75,7 @@ impl TraitItems {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attribute_calls(&self) -> impl Iterator<Item = (AstId<ast::Item>, MacroCallId)> + '_ {
|
pub fn macro_calls(&self) -> impl Iterator<Item = (AstId<ast::Item>, MacroCallId)> + '_ {
|
||||||
self.macro_calls.iter().flat_map(|it| it.iter()).copied()
|
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))
|
(Arc::new(ImplItems { items, macro_calls }), DefDiagnostics::new(diagnostics))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attribute_calls(&self) -> impl Iterator<Item = (AstId<ast::Item>, MacroCallId)> + '_ {
|
pub fn macro_calls(&self) -> impl Iterator<Item = (AstId<ast::Item>, MacroCallId)> + '_ {
|
||||||
self.macro_calls.iter().flat_map(|it| it.iter()).copied()
|
self.macro_calls.iter().flat_map(|it| it.iter()).copied()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -696,15 +696,6 @@ impl<'db> Resolver<'db> {
|
|||||||
&def_map[local_id].scope
|
&def_map[local_id].scope
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn item_scopes(&self) -> impl Iterator<Item = &ItemScope> {
|
|
||||||
self.scopes()
|
|
||||||
.filter_map(move |scope| match scope {
|
|
||||||
Scope::BlockScope(m) => Some(&m.def_map[m.module_id].scope),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
.chain(std::iter::once(&self.module_scope.def_map[self.module_scope.module_id].scope))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn krate(&self) -> Crate {
|
pub fn krate(&self) -> Crate {
|
||||||
self.module_scope.def_map.krate()
|
self.module_scope.def_map.krate()
|
||||||
}
|
}
|
||||||
|
@ -258,8 +258,6 @@ pub struct MacroCallLoc {
|
|||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct MacroDefId {
|
pub struct MacroDefId {
|
||||||
pub krate: Crate,
|
pub krate: Crate,
|
||||||
// FIXME: In `hir-expand` we can't refer to `BlockId`.
|
|
||||||
pub block: Option<salsa::Id>,
|
|
||||||
pub edition: Edition,
|
pub edition: Edition,
|
||||||
pub kind: MacroDefKind,
|
pub kind: MacroDefKind,
|
||||||
pub local_inner: bool,
|
pub local_inner: bool,
|
||||||
|
@ -408,11 +408,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn expand_macro_call(&self, macro_call: &ast::MacroCall) -> Option<InFile<SyntaxNode>> {
|
pub fn expand_macro_call(&self, macro_call: &ast::MacroCall) -> Option<InFile<SyntaxNode>> {
|
||||||
let sa = self.analyze_no_infer(macro_call.syntax())?;
|
let file_id = self.to_def(macro_call)?;
|
||||||
|
|
||||||
let macro_call = InFile::new(sa.file_id, macro_call);
|
|
||||||
let file_id = sa.expansion(self.db, macro_call)?;
|
|
||||||
|
|
||||||
let node = self.parse_or_expand(file_id.into());
|
let node = self.parse_or_expand(file_id.into());
|
||||||
Some(InFile::new(file_id.into(), node))
|
Some(InFile::new(file_id.into(), node))
|
||||||
}
|
}
|
||||||
@ -434,10 +430,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
&self,
|
&self,
|
||||||
macro_call: &ast::MacroCall,
|
macro_call: &ast::MacroCall,
|
||||||
) -> Option<ExpandResult<SyntaxNode>> {
|
) -> Option<ExpandResult<SyntaxNode>> {
|
||||||
let sa = self.analyze_no_infer(macro_call.syntax())?;
|
let file_id = self.to_def(macro_call)?;
|
||||||
|
|
||||||
let macro_call = InFile::new(sa.file_id, macro_call);
|
|
||||||
let file_id = sa.expansion(self.db, macro_call)?;
|
|
||||||
let macro_call = self.db.lookup_intern_macro_call(file_id);
|
let macro_call = self.db.lookup_intern_macro_call(file_id);
|
||||||
|
|
||||||
let skip = matches!(
|
let skip = matches!(
|
||||||
@ -574,9 +567,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
speculative_args: &ast::TokenTree,
|
speculative_args: &ast::TokenTree,
|
||||||
token_to_map: SyntaxToken,
|
token_to_map: SyntaxToken,
|
||||||
) -> Option<(SyntaxNode, Vec<(SyntaxToken, u8)>)> {
|
) -> Option<(SyntaxNode, Vec<(SyntaxToken, u8)>)> {
|
||||||
let analyzer = self.analyze_no_infer(actual_macro_call.syntax())?;
|
let macro_file = self.to_def(actual_macro_call)?;
|
||||||
let macro_call = InFile::new(analyzer.file_id, actual_macro_call);
|
|
||||||
let macro_file = analyzer.expansion(self.db, macro_call)?;
|
|
||||||
hir_expand::db::expand_speculative(
|
hir_expand::db::expand_speculative(
|
||||||
self.db,
|
self.db,
|
||||||
macro_file,
|
macro_file,
|
||||||
@ -1097,16 +1088,7 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
let file_id = match m_cache.get(&mcall) {
|
let file_id = match m_cache.get(&mcall) {
|
||||||
Some(&it) => it,
|
Some(&it) => it,
|
||||||
None => {
|
None => {
|
||||||
let it = token
|
let it = ast::MacroCall::to_def(self, mcall.as_ref())?;
|
||||||
.parent()
|
|
||||||
.and_then(|parent| {
|
|
||||||
self.analyze_impl(
|
|
||||||
InFile::new(expansion, &parent),
|
|
||||||
None,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
})?
|
|
||||||
.expansion(self.db, mcall.as_ref())?;
|
|
||||||
m_cache.insert(mcall, it);
|
m_cache.insert(mcall, it);
|
||||||
it
|
it
|
||||||
}
|
}
|
||||||
@ -1551,9 +1533,6 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
.and_then(|call| macro_call_to_macro_id(ctx, call))
|
.and_then(|call| macro_call_to_macro_id(ctx, call))
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
})
|
})
|
||||||
.or_else(|| {
|
|
||||||
self.analyze(macro_call.value.syntax())?.resolve_macro_call(self.db, macro_call)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_proc_macro_call(&self, macro_call: InFile<&ast::MacroCall>) -> bool {
|
pub fn is_proc_macro_call(&self, macro_call: InFile<&ast::MacroCall>) -> bool {
|
||||||
@ -1562,14 +1541,8 @@ impl<'db> SemanticsImpl<'db> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_macro_call_arm(&self, macro_call: &ast::MacroCall) -> Option<u32> {
|
pub fn resolve_macro_call_arm(&self, macro_call: &ast::MacroCall) -> Option<u32> {
|
||||||
let sa = self.analyze(macro_call.syntax())?;
|
let file_id = self.to_def(macro_call)?;
|
||||||
self.db
|
self.db.parse_macro_expansion(file_id).value.1.matched_arm
|
||||||
.parse_macro_expansion(
|
|
||||||
sa.expansion(self.db, self.wrap_node_infile(macro_call.clone()).as_ref())?,
|
|
||||||
)
|
|
||||||
.value
|
|
||||||
.1
|
|
||||||
.matched_arm
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_unsafe_ops(&self, def: DefWithBody) -> FxHashSet<ExprOrPatSource> {
|
pub fn get_unsafe_ops(&self, def: DefWithBody) -> FxHashSet<ExprOrPatSource> {
|
||||||
|
@ -36,9 +36,14 @@ impl ChildBySource for TraitId {
|
|||||||
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
|
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
|
||||||
let data = db.trait_items(*self);
|
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)| {
|
|(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::<ast::MacroCall>() {
|
||||||
|
res[keys::MACRO_CALL].insert(ptr, call_id);
|
||||||
|
} else {
|
||||||
|
res[keys::ATTR_MACRO_CALL].insert(ptr, call_id);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
data.items.iter().for_each(|&(_, item)| {
|
data.items.iter().for_each(|&(_, item)| {
|
||||||
@ -50,10 +55,14 @@ impl ChildBySource for TraitId {
|
|||||||
impl ChildBySource for ImplId {
|
impl ChildBySource for ImplId {
|
||||||
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
|
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
|
||||||
let data = db.impl_items(*self);
|
let data = db.impl_items(*self);
|
||||||
// FIXME: Macro calls
|
data.macro_calls().filter(|(ast_id, _)| ast_id.file_id == file_id).for_each(
|
||||||
data.attribute_calls().filter(|(ast_id, _)| ast_id.file_id == file_id).for_each(
|
|
||||||
|(ast_id, call_id)| {
|
|(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::<ast::MacroCall>() {
|
||||||
|
res[keys::MACRO_CALL].insert(ptr, call_id);
|
||||||
|
} else {
|
||||||
|
res[keys::ATTR_MACRO_CALL].insert(ptr, call_id);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
data.items.iter().for_each(|&(_, item)| {
|
data.items.iter().for_each(|&(_, item)| {
|
||||||
|
@ -26,12 +26,12 @@ use hir_def::{
|
|||||||
},
|
},
|
||||||
hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat},
|
hir::{BindingId, Expr, ExprId, ExprOrPatId, Pat},
|
||||||
lang_item::LangItem,
|
lang_item::LangItem,
|
||||||
nameres::{MacroSubNs, block_def_map, crate_def_map},
|
nameres::MacroSubNs,
|
||||||
resolver::{HasResolver, Resolver, TypeNs, ValueNs, resolver_for_scope},
|
resolver::{HasResolver, Resolver, TypeNs, ValueNs, resolver_for_scope},
|
||||||
type_ref::{Mutability, TypeRefId},
|
type_ref::{Mutability, TypeRefId},
|
||||||
};
|
};
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
HirFileId, InFile, MacroCallId,
|
HirFileId, InFile,
|
||||||
mod_path::{ModPath, PathKind, path},
|
mod_path::{ModPath, PathKind, path},
|
||||||
name::{AsName, Name},
|
name::{AsName, Name},
|
||||||
};
|
};
|
||||||
@ -218,18 +218,6 @@ impl<'db> SourceAnalyzer<'db> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn expansion(
|
|
||||||
&self,
|
|
||||||
db: &dyn HirDatabase,
|
|
||||||
macro_call: InFile<&ast::MacroCall>,
|
|
||||||
) -> Option<MacroCallId> {
|
|
||||||
self.store_sm().and_then(|sm| sm.expansion(macro_call)).or_else(|| {
|
|
||||||
let ast_id_map = db.ast_id_map(macro_call.file_id);
|
|
||||||
let call_ast_id = macro_call.with_value(ast_id_map.ast_id(macro_call.value));
|
|
||||||
self.resolver.item_scopes().find_map(|scope| scope.macro_invoc(call_ast_id))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn trait_environment(&self, db: &'db dyn HirDatabase) -> Arc<TraitEnvironment> {
|
fn trait_environment(&self, db: &'db dyn HirDatabase) -> Arc<TraitEnvironment> {
|
||||||
self.body_().map(|(def, ..)| def).map_or_else(
|
self.body_().map(|(def, ..)| def).map_or_else(
|
||||||
|| TraitEnvironment::empty(self.resolver.krate()),
|
|| TraitEnvironment::empty(self.resolver.krate()),
|
||||||
@ -753,21 +741,6 @@ impl<'db> SourceAnalyzer<'db> {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn resolve_macro_call(
|
|
||||||
&self,
|
|
||||||
db: &dyn HirDatabase,
|
|
||||||
macro_call: InFile<&ast::MacroCall>,
|
|
||||||
) -> Option<Macro> {
|
|
||||||
self.expansion(db, macro_call).and_then(|it| {
|
|
||||||
let def = it.lookup(db).def;
|
|
||||||
let def_map = match def.block {
|
|
||||||
Some(block) => block_def_map(db, base_db::salsa::plumbing::FromId::from_id(block)),
|
|
||||||
None => crate_def_map(db, def.krate),
|
|
||||||
};
|
|
||||||
def_map.macro_def_to_macro_id.get(&def.kind.erased_ast_id()).map(|it| (*it).into())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn resolve_bind_pat_to_const(
|
pub(crate) fn resolve_bind_pat_to_const(
|
||||||
&self,
|
&self,
|
||||||
db: &'db dyn HirDatabase,
|
db: &'db dyn HirDatabase,
|
||||||
|
@ -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""#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1023,7 +1023,7 @@ impl flags::AnalysisStats {
|
|||||||
percentage(num_pats_partially_unknown, num_pats),
|
percentage(num_pats_partially_unknown, num_pats),
|
||||||
num_pat_type_mismatches
|
num_pat_type_mismatches
|
||||||
);
|
);
|
||||||
eprintln!(" panics: {}", panics);
|
eprintln!(" panics: {panics}");
|
||||||
eprintln!("{:<20} {}", "Inference:", inference_time);
|
eprintln!("{:<20} {}", "Inference:", inference_time);
|
||||||
report_metric("unknown type", num_exprs_unknown, "#");
|
report_metric("unknown type", num_exprs_unknown, "#");
|
||||||
report_metric("type mismatches", num_expr_type_mismatches, "#");
|
report_metric("type mismatches", num_expr_type_mismatches, "#");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user