mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 14:21:44 +00:00
Collect trait impls inside unnamed consts
This commit is contained in:
parent
f04f38d3d7
commit
7c1c0e6fea
3 changed files with 61 additions and 19 deletions
|
@ -107,6 +107,10 @@ impl ItemScope {
|
||||||
.map(|(_, v)| v)
|
.map(|(_, v)| v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unnamed_consts(&self) -> impl Iterator<Item = ConstId> + '_ {
|
||||||
|
self.unnamed_consts.iter().copied()
|
||||||
|
}
|
||||||
|
|
||||||
/// Iterate over all module scoped macros
|
/// Iterate over all module scoped macros
|
||||||
pub(crate) fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
|
pub(crate) fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
|
||||||
self.entries().filter_map(|(name, def)| def.take_macros().map(|macro_| (name, macro_)))
|
self.entries().filter_map(|(name, def)| def.take_macros().map(|macro_| (name, macro_)))
|
||||||
|
|
|
@ -8,8 +8,8 @@ use arrayvec::ArrayVec;
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use chalk_ir::{cast::Cast, Mutability, UniverseIndex};
|
use chalk_ir::{cast::Cast, Mutability, UniverseIndex};
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule,
|
lang_item::LangItemTarget, nameres::DefMap, AssocContainerId, AssocItemId, FunctionId,
|
||||||
ImplId, Lookup, ModuleId, TraitId,
|
GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId,
|
||||||
};
|
};
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
@ -100,7 +100,12 @@ impl TraitImpls {
|
||||||
let mut impls = Self { map: FxHashMap::default() };
|
let mut impls = Self { map: FxHashMap::default() };
|
||||||
|
|
||||||
let crate_def_map = db.crate_def_map(krate);
|
let crate_def_map = db.crate_def_map(krate);
|
||||||
for (_module_id, module_data) in crate_def_map.modules() {
|
collect_def_map(db, &crate_def_map, &mut impls);
|
||||||
|
|
||||||
|
return Arc::new(impls);
|
||||||
|
|
||||||
|
fn collect_def_map(db: &dyn HirDatabase, def_map: &DefMap, impls: &mut TraitImpls) {
|
||||||
|
for (_module_id, module_data) in def_map.modules() {
|
||||||
for impl_id in module_data.scope.impls() {
|
for impl_id in module_data.scope.impls() {
|
||||||
let target_trait = match db.impl_trait(impl_id) {
|
let target_trait = match db.impl_trait(impl_id) {
|
||||||
Some(tr) => tr.skip_binders().hir_trait_id(),
|
Some(tr) => tr.skip_binders().hir_trait_id(),
|
||||||
|
@ -116,9 +121,17 @@ impl TraitImpls {
|
||||||
.or_default()
|
.or_default()
|
||||||
.push(impl_id);
|
.push(impl_id);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Arc::new(impls)
|
// To better support custom derives, collect impls in all unnamed const items.
|
||||||
|
// const _: () = { ... };
|
||||||
|
for konst in module_data.scope.unnamed_consts() {
|
||||||
|
let body = db.body(konst.into());
|
||||||
|
for (_, block_def_map) in body.blocks(db.upcast()) {
|
||||||
|
collect_def_map(db, &block_def_map, impls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn trait_impls_in_deps_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
|
pub(crate) fn trait_impls_in_deps_query(db: &dyn HirDatabase, krate: CrateId) -> Arc<Self> {
|
||||||
|
@ -208,6 +221,9 @@ impl InherentImpls {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: We're not collecting inherent impls from unnamed consts here, we intentionally only
|
||||||
|
// support trait impls there.
|
||||||
|
|
||||||
Arc::new(Self { map })
|
Arc::new(Self { map })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1292,3 +1292,25 @@ mod b {
|
||||||
"#]],
|
"#]],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn impl_in_unnamed_const() {
|
||||||
|
check_types(
|
||||||
|
r#"
|
||||||
|
struct S;
|
||||||
|
|
||||||
|
trait Tr {
|
||||||
|
fn method(&self) -> u16;
|
||||||
|
}
|
||||||
|
|
||||||
|
const _: () = {
|
||||||
|
impl Tr for S {}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn f() {
|
||||||
|
S.method();
|
||||||
|
//^^^^^^^^^^ u16
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue