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 { fn resolver(self, db: &impl DefDatabase) -> Resolver {
match self { match self {
ContainerId::ModuleId(it) => it.resolver(db), 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 std::sync::Arc;
use hir_def::{ use hir_def::{
body::BodySourceMap, child_by_source::ChildBySource, db::DefDatabase, keys, body::BodySourceMap, child_by_source::ChildBySource, db::DefDatabase, item_scope::ItemScope,
nameres::CrateDefMap, AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId, keys, nameres::CrateDefMap, AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId,
}; };
use hir_expand::InFile; use hir_expand::InFile;
use insta::assert_snapshot; use insta::assert_snapshot;
@ -163,35 +163,69 @@ fn visit_module(
module_id: LocalModuleId, module_id: LocalModuleId,
cb: &mut dyn FnMut(DefWithBodyId), 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);
match decl {
ModuleDefId::FunctionId(it) => cb(it.into()),
ModuleDefId::ConstId(it) => cb(it.into()),
ModuleDefId::StaticId(it) => cb(it.into()),
ModuleDefId::TraitId(it) => {
let trait_data = db.trait_data(it);
for &(_, item) in trait_data.items.iter() {
match item {
AssocItemId::FunctionId(it) => cb(it.into()),
AssocItemId::ConstId(it) => cb(it.into()),
AssocItemId::TypeAliasId(_) => (),
}
}
}
ModuleDefId::ModuleId(it) => visit_module(db, crate_def_map, it.local_id, cb),
_ => (),
}
}
for impl_id in crate_def_map[module_id].scope.impls() { for impl_id in crate_def_map[module_id].scope.impls() {
let impl_data = db.impl_data(impl_id); let impl_data = db.impl_data(impl_id);
for &item in impl_data.items.iter() { for &item in impl_data.items.iter() {
match item { match item {
AssocItemId::FunctionId(it) => cb(it.into()), AssocItemId::FunctionId(it) => {
AssocItemId::ConstId(it) => cb(it.into()), 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(_) => (), 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) => {
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() {
match item {
AssocItemId::FunctionId(it) => cb(it.into()),
AssocItemId::ConstId(it) => cb(it.into()),
AssocItemId::TypeAliasId(_) => (),
}
}
}
ModuleDefId::ModuleId(it) => visit_module(db, crate_def_map, it.local_id, cb),
_ => (),
}
}
}
} }
fn ellipsize(mut text: String, max_len: usize) -> String { fn ellipsize(mut text: String, max_len: usize) -> String {

View file

@ -1,7 +1,8 @@
use super::infer;
use insta::assert_snapshot; use insta::assert_snapshot;
use test_utils::covers; use test_utils::covers;
use super::infer;
#[test] #[test]
fn bug_484() { fn bug_484() {
assert_snapshot!( 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 [167; 179) 'GLOBAL_CONST': u32
[189; 191) 'id': u32 [189; 191) 'id': u32
[194; 210) 'Foo::A..._CONST': u32 [194; 210) 'Foo::A..._CONST': u32
[126; 128) '99': u32
"### "###
); );
} }
@ -1549,6 +1550,8 @@ fn test() {
[233; 246) 'GLOBAL_STATIC': u32 [233; 246) 'GLOBAL_STATIC': u32
[256; 257) 'w': u32 [256; 257) 'w': u32
[260; 277) 'GLOBAL...IC_MUT': u32 [260; 277) 'GLOBAL...IC_MUT': u32
[118; 120) '99': u32
[161; 163) '99': u32
"### "###
); );
} }