mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-28 18:43:01 +00:00
fix: Record macro calls in signatures in ChildBySource impls
This commit is contained in:
parent
634596e2d7
commit
bb5e6deff5
4 changed files with 77 additions and 19 deletions
|
|
@ -1948,18 +1948,12 @@ impl<'db> SemanticsImpl<'db> {
|
||||||
ChildContainer::TraitId(it) => {
|
ChildContainer::TraitId(it) => {
|
||||||
return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
|
return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
|
||||||
}
|
}
|
||||||
ChildContainer::TraitAliasId(it) => {
|
|
||||||
return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
|
|
||||||
}
|
|
||||||
ChildContainer::ImplId(it) => {
|
ChildContainer::ImplId(it) => {
|
||||||
return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
|
return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
|
||||||
}
|
}
|
||||||
ChildContainer::EnumId(it) => {
|
ChildContainer::EnumId(it) => {
|
||||||
return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
|
return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
|
||||||
}
|
}
|
||||||
ChildContainer::TypeAliasId(it) => {
|
|
||||||
return Some(SourceAnalyzer::new_generic_def(self.db, it.into(), node, offset));
|
|
||||||
}
|
|
||||||
ChildContainer::GenericDefId(it) => {
|
ChildContainer::GenericDefId(it) => {
|
||||||
return Some(SourceAnalyzer::new_generic_def(self.db, it, node, offset));
|
return Some(SourceAnalyzer::new_generic_def(self.db, it, node, offset));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ use hir_def::{
|
||||||
DynMap,
|
DynMap,
|
||||||
keys::{self, Key},
|
keys::{self, Key},
|
||||||
},
|
},
|
||||||
|
hir::generics::GenericParams,
|
||||||
item_scope::ItemScope,
|
item_scope::ItemScope,
|
||||||
item_tree::ItemTreeNode,
|
item_tree::ItemTreeNode,
|
||||||
nameres::DefMap,
|
nameres::DefMap,
|
||||||
|
|
@ -49,6 +50,12 @@ impl ChildBySource for TraitId {
|
||||||
data.items.iter().for_each(|&(_, item)| {
|
data.items.iter().for_each(|&(_, item)| {
|
||||||
add_assoc_item(db, res, file_id, item);
|
add_assoc_item(db, res, file_id, item);
|
||||||
});
|
});
|
||||||
|
let (_, source_map) = db.trait_signature_with_source_map(*self);
|
||||||
|
source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each(
|
||||||
|
|(ast, &exp_id)| {
|
||||||
|
res[keys::MACRO_CALL].insert(ast.value, exp_id);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,6 +75,12 @@ impl ChildBySource for ImplId {
|
||||||
data.items.iter().for_each(|&(_, item)| {
|
data.items.iter().for_each(|&(_, item)| {
|
||||||
add_assoc_item(db, res, file_id, item);
|
add_assoc_item(db, res, file_id, item);
|
||||||
});
|
});
|
||||||
|
let (_, source_map) = db.impl_signature_with_source_map(*self);
|
||||||
|
source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each(
|
||||||
|
|(ast, &exp_id)| {
|
||||||
|
res[keys::MACRO_CALL].insert(ast.value, exp_id);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -195,6 +208,12 @@ impl ChildBySource for EnumId {
|
||||||
res[keys::ENUM_VARIANT]
|
res[keys::ENUM_VARIANT]
|
||||||
.insert(ast_id_map.get(tree[variant.lookup(db).id.value].ast_id), variant);
|
.insert(ast_id_map.get(tree[variant.lookup(db).id.value].ast_id), variant);
|
||||||
});
|
});
|
||||||
|
let (_, source_map) = db.enum_signature_with_source_map(*self);
|
||||||
|
source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each(
|
||||||
|
|(ast, &exp_id)| {
|
||||||
|
res[keys::MACRO_CALL].insert(ast.value, exp_id);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,7 +244,8 @@ impl ChildBySource for GenericDefId {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let generic_params = db.generic_params(*self);
|
let (generic_params, _, source_map) =
|
||||||
|
GenericParams::generic_params_and_store_and_source_map(db, *self);
|
||||||
let mut toc_idx_iter = generic_params.iter_type_or_consts().map(|(idx, _)| idx);
|
let mut toc_idx_iter = generic_params.iter_type_or_consts().map(|(idx, _)| idx);
|
||||||
let lts_idx_iter = generic_params.iter_lt().map(|(idx, _)| idx);
|
let lts_idx_iter = generic_params.iter_lt().map(|(idx, _)| idx);
|
||||||
|
|
||||||
|
|
@ -253,6 +273,12 @@ impl ChildBySource for GenericDefId {
|
||||||
res[keys::LIFETIME_PARAM].insert(AstPtr::new(&ast_param), id);
|
res[keys::LIFETIME_PARAM].insert(AstPtr::new(&ast_param), id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
source_map.expansions().filter(|(ast, _)| ast.file_id == file_id).for_each(
|
||||||
|
|(ast, &exp_id)| {
|
||||||
|
res[keys::MACRO_CALL].insert(ast.value, exp_id);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -631,14 +631,14 @@ impl SourceToDefCtx<'_, '_> {
|
||||||
match &item {
|
match &item {
|
||||||
ast::Item::Module(it) => self.module_to_def(container.with_value(it))?.into(),
|
ast::Item::Module(it) => self.module_to_def(container.with_value(it))?.into(),
|
||||||
ast::Item::Trait(it) => self.trait_to_def(container.with_value(it))?.into(),
|
ast::Item::Trait(it) => self.trait_to_def(container.with_value(it))?.into(),
|
||||||
ast::Item::TraitAlias(it) => {
|
|
||||||
self.trait_alias_to_def(container.with_value(it))?.into()
|
|
||||||
}
|
|
||||||
ast::Item::Impl(it) => self.impl_to_def(container.with_value(it))?.into(),
|
ast::Item::Impl(it) => self.impl_to_def(container.with_value(it))?.into(),
|
||||||
ast::Item::Enum(it) => self.enum_to_def(container.with_value(it))?.into(),
|
ast::Item::Enum(it) => self.enum_to_def(container.with_value(it))?.into(),
|
||||||
ast::Item::TypeAlias(it) => {
|
ast::Item::TypeAlias(it) => ChildContainer::GenericDefId(
|
||||||
self.type_alias_to_def(container.with_value(it))?.into()
|
self.type_alias_to_def(container.with_value(it))?.into(),
|
||||||
}
|
),
|
||||||
|
ast::Item::TraitAlias(it) => ChildContainer::GenericDefId(
|
||||||
|
self.trait_alias_to_def(container.with_value(it))?.into(),
|
||||||
|
),
|
||||||
ast::Item::Struct(it) => {
|
ast::Item::Struct(it) => {
|
||||||
let def = self.struct_to_def(container.with_value(it))?;
|
let def = self.struct_to_def(container.with_value(it))?;
|
||||||
let is_in_body = it.field_list().is_some_and(|it| {
|
let is_in_body = it.field_list().is_some_and(|it| {
|
||||||
|
|
@ -738,11 +738,9 @@ pub(crate) enum ChildContainer {
|
||||||
DefWithBodyId(DefWithBodyId),
|
DefWithBodyId(DefWithBodyId),
|
||||||
ModuleId(ModuleId),
|
ModuleId(ModuleId),
|
||||||
TraitId(TraitId),
|
TraitId(TraitId),
|
||||||
TraitAliasId(TraitAliasId),
|
|
||||||
ImplId(ImplId),
|
ImplId(ImplId),
|
||||||
EnumId(EnumId),
|
EnumId(EnumId),
|
||||||
VariantId(VariantId),
|
VariantId(VariantId),
|
||||||
TypeAliasId(TypeAliasId),
|
|
||||||
/// XXX: this might be the same def as, for example an `EnumId`. However,
|
/// XXX: this might be the same def as, for example an `EnumId`. However,
|
||||||
/// here the children are generic parameters, and not, eg enum variants.
|
/// here the children are generic parameters, and not, eg enum variants.
|
||||||
GenericDefId(GenericDefId),
|
GenericDefId(GenericDefId),
|
||||||
|
|
@ -751,11 +749,9 @@ impl_from! {
|
||||||
DefWithBodyId,
|
DefWithBodyId,
|
||||||
ModuleId,
|
ModuleId,
|
||||||
TraitId,
|
TraitId,
|
||||||
TraitAliasId,
|
|
||||||
ImplId,
|
ImplId,
|
||||||
EnumId,
|
EnumId,
|
||||||
VariantId,
|
VariantId,
|
||||||
TypeAliasId,
|
|
||||||
GenericDefId
|
GenericDefId
|
||||||
for ChildContainer
|
for ChildContainer
|
||||||
}
|
}
|
||||||
|
|
@ -767,11 +763,9 @@ impl ChildContainer {
|
||||||
ChildContainer::DefWithBodyId(it) => it.child_by_source(db, file_id),
|
ChildContainer::DefWithBodyId(it) => it.child_by_source(db, file_id),
|
||||||
ChildContainer::ModuleId(it) => it.child_by_source(db, file_id),
|
ChildContainer::ModuleId(it) => it.child_by_source(db, file_id),
|
||||||
ChildContainer::TraitId(it) => it.child_by_source(db, file_id),
|
ChildContainer::TraitId(it) => it.child_by_source(db, file_id),
|
||||||
ChildContainer::TraitAliasId(_) => DynMap::default(),
|
|
||||||
ChildContainer::ImplId(it) => it.child_by_source(db, file_id),
|
ChildContainer::ImplId(it) => it.child_by_source(db, file_id),
|
||||||
ChildContainer::EnumId(it) => it.child_by_source(db, file_id),
|
ChildContainer::EnumId(it) => it.child_by_source(db, file_id),
|
||||||
ChildContainer::VariantId(it) => it.child_by_source(db, file_id),
|
ChildContainer::VariantId(it) => it.child_by_source(db, file_id),
|
||||||
ChildContainer::TypeAliasId(_) => DynMap::default(),
|
|
||||||
ChildContainer::GenericDefId(it) => it.child_by_source(db, file_id),
|
ChildContainer::GenericDefId(it) => it.child_by_source(db, file_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -800,4 +800,48 @@ foo();
|
||||||
foo();"#]],
|
foo();"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn works_in_sig() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
macro_rules! foo {
|
||||||
|
() => { u32 };
|
||||||
|
}
|
||||||
|
fn foo() -> foo$0!() {
|
||||||
|
42
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
foo!
|
||||||
|
u32"#]],
|
||||||
|
);
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
macro_rules! foo {
|
||||||
|
() => { u32 };
|
||||||
|
}
|
||||||
|
fn foo(_: foo$0!() ) {}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
foo!
|
||||||
|
u32"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn works_in_generics() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
trait Trait {}
|
||||||
|
macro_rules! foo {
|
||||||
|
() => { Trait };
|
||||||
|
}
|
||||||
|
impl<const C: foo$0!()> Trait for () {}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
foo!
|
||||||
|
Trait"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue