Don't add non-impl/trait containers to scope

This commit is contained in:
Aleksey Kladov 2019-12-29 14:46:24 +01:00
parent dc48f89581
commit 8f36f768e1
4 changed files with 96 additions and 25 deletions

View file

@ -644,7 +644,7 @@ impl HasResolver for ContainerId {
fn resolver(self, db: &impl DefDatabase) -> Resolver {
match self {
ContainerId::ModuleId(it) => it.resolver(db),
ContainerId::DefWithBodyId(it) => it.resolver(db),
ContainerId::DefWithBodyId(it) => it.module(db).resolver(db),
}
}
}

View file

@ -11,8 +11,8 @@ use std::fmt::Write;
use std::sync::Arc;
use hir_def::{
body::BodySourceMap, child_by_source::ChildBySource, db::DefDatabase, keys,
nameres::CrateDefMap, AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId,
body::BodySourceMap, child_by_source::ChildBySource, db::DefDatabase, item_scope::ItemScope,
keys, nameres::CrateDefMap, AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId,
};
use hir_expand::InFile;
use insta::assert_snapshot;
@ -163,11 +163,54 @@ fn visit_module(
module_id: LocalModuleId,
cb: &mut dyn FnMut(DefWithBodyId),
) {
for decl in crate_def_map[module_id].scope.declarations() {
visit_scope(db, crate_def_map, &crate_def_map[module_id].scope, cb);
for impl_id in crate_def_map[module_id].scope.impls() {
let impl_data = db.impl_data(impl_id);
for &item in impl_data.items.iter() {
match item {
AssocItemId::FunctionId(it) => {
let def = it.into();
cb(def);
let body = db.body(def);
visit_scope(db, crate_def_map, &body.item_scope, cb);
}
AssocItemId::ConstId(it) => {
let def = it.into();
cb(def);
let body = db.body(def);
visit_scope(db, crate_def_map, &body.item_scope, cb);
}
AssocItemId::TypeAliasId(_) => (),
}
}
}
fn visit_scope(
db: &TestDB,
crate_def_map: &CrateDefMap,
scope: &ItemScope,
cb: &mut dyn FnMut(DefWithBodyId),
) {
for decl in scope.declarations() {
match decl {
ModuleDefId::FunctionId(it) => cb(it.into()),
ModuleDefId::ConstId(it) => cb(it.into()),
ModuleDefId::StaticId(it) => cb(it.into()),
ModuleDefId::FunctionId(it) => {
let def = it.into();
cb(def);
let body = db.body(def);
visit_scope(db, crate_def_map, &body.item_scope, cb);
}
ModuleDefId::ConstId(it) => {
let def = it.into();
cb(def);
let body = db.body(def);
visit_scope(db, crate_def_map, &body.item_scope, cb);
}
ModuleDefId::StaticId(it) => {
let def = it.into();
cb(def);
let body = db.body(def);
visit_scope(db, crate_def_map, &body.item_scope, cb);
}
ModuleDefId::TraitId(it) => {
let trait_data = db.trait_data(it);
for &(_, item) in trait_data.items.iter() {
@ -182,15 +225,6 @@ fn visit_module(
_ => (),
}
}
for impl_id in crate_def_map[module_id].scope.impls() {
let impl_data = db.impl_data(impl_id);
for &item in impl_data.items.iter() {
match item {
AssocItemId::FunctionId(it) => cb(it.into()),
AssocItemId::ConstId(it) => cb(it.into()),
AssocItemId::TypeAliasId(_) => (),
}
}
}
}

View file

@ -1,7 +1,8 @@
use super::infer;
use insta::assert_snapshot;
use test_utils::covers;
use super::infer;
#[test]
fn bug_484() {
assert_snapshot!(
@ -331,3 +332,36 @@ pub fn main_loop() {
"###
);
}
#[test]
fn issue_2669() {
assert_snapshot!(
infer(
r#"trait A {}
trait Write {}
struct Response<T> {}
trait D {
fn foo();
}
impl<T:A> D for Response<T> {
fn foo() {
end();
fn end<W: Write>() {
let _x: T = loop {};
}
}
}"#
),
@r###"
[147; 262) '{ ... }': ()
[161; 164) 'end': fn end<{unknown}>() -> ()
[161; 166) 'end()': ()
[199; 252) '{ ... }': ()
[221; 223) '_x': !
[230; 237) 'loop {}': !
[235; 237) '{}': ()
"###
)
}

View file

@ -1518,6 +1518,7 @@ fn test() {
[167; 179) 'GLOBAL_CONST': u32
[189; 191) 'id': u32
[194; 210) 'Foo::A..._CONST': u32
[126; 128) '99': u32
"###
);
}
@ -1549,6 +1550,8 @@ fn test() {
[233; 246) 'GLOBAL_STATIC': u32
[256; 257) 'w': u32
[260; 277) 'GLOBAL...IC_MUT': u32
[118; 120) '99': u32
[161; 163) '99': u32
"###
);
}