aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r--crates/hir_def/src/attr.rs1
-rw-r--r--crates/hir_def/src/body.rs2
-rw-r--r--crates/hir_def/src/body/tests.rs41
-rw-r--r--crates/hir_def/src/db.rs7
-rw-r--r--crates/hir_def/src/find_path.rs18
-rw-r--r--crates/hir_def/src/import_map.rs2
-rw-r--r--crates/hir_def/src/item_tree.rs31
-rw-r--r--crates/hir_def/src/item_tree/lower.rs45
-rw-r--r--crates/hir_def/src/lang_item.rs2
-rw-r--r--crates/hir_def/src/nameres.rs140
-rw-r--r--crates/hir_def/src/nameres/collector.rs58
-rw-r--r--crates/hir_def/src/nameres/path_resolution.rs37
-rw-r--r--crates/hir_def/src/nameres/tests.rs20
-rw-r--r--crates/hir_def/src/nameres/tests/block.rs97
-rw-r--r--crates/hir_def/src/resolver.rs23
-rw-r--r--crates/hir_def/src/test_db.rs6
16 files changed, 435 insertions, 95 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index 1b09ff816..c72649c41 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -207,6 +207,7 @@ impl Attrs {
207 mod_data.definition_source(db).as_ref().map(|src| match src { 207 mod_data.definition_source(db).as_ref().map(|src| match src {
208 ModuleSource::SourceFile(file) => file as &dyn AttrsOwner, 208 ModuleSource::SourceFile(file) => file as &dyn AttrsOwner,
209 ModuleSource::Module(module) => module as &dyn AttrsOwner, 209 ModuleSource::Module(module) => module as &dyn AttrsOwner,
210 ModuleSource::BlockExpr(block) => block as &dyn AttrsOwner,
210 }), 211 }),
211 ), 212 ),
212 } 213 }
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs
index 3b2dd0f6e..2c2c999dd 100644
--- a/crates/hir_def/src/body.rs
+++ b/crates/hir_def/src/body.rs
@@ -122,7 +122,7 @@ impl Expander {
122 122
123 let mut err = None; 123 let mut err = None;
124 let call_id = 124 let call_id =
125 macro_call.as_call_id_with_errors(db, self.crate_def_map.krate, resolver, &mut |e| { 125 macro_call.as_call_id_with_errors(db, self.crate_def_map.krate(), resolver, &mut |e| {
126 err.get_or_insert(e); 126 err.get_or_insert(e);
127 }); 127 });
128 let call_id = match call_id { 128 let call_id = match call_id {
diff --git a/crates/hir_def/src/body/tests.rs b/crates/hir_def/src/body/tests.rs
index de77d5fc9..2e5d0a01e 100644
--- a/crates/hir_def/src/body/tests.rs
+++ b/crates/hir_def/src/body/tests.rs
@@ -6,18 +6,24 @@ use crate::{test_db::TestDB, ModuleDefId};
6use super::*; 6use super::*;
7 7
8fn lower(ra_fixture: &str) -> Arc<Body> { 8fn lower(ra_fixture: &str) -> Arc<Body> {
9 let (db, file_id) = crate::test_db::TestDB::with_single_file(ra_fixture); 9 let db = crate::test_db::TestDB::with_files(ra_fixture);
10 10
11 let krate = db.crate_graph().iter().next().unwrap(); 11 let krate = db.crate_graph().iter().next().unwrap();
12 let def_map = db.crate_def_map(krate); 12 let def_map = db.crate_def_map(krate);
13 let module = def_map.modules_for_file(file_id).next().unwrap(); 13 let mut fn_def = None;
14 let module = &def_map[module]; 14 'outer: for (_, module) in def_map.modules() {
15 let fn_def = match module.scope.declarations().next().unwrap() { 15 for decl in module.scope.declarations() {
16 ModuleDefId::FunctionId(it) => it, 16 match decl {
17 _ => panic!(), 17 ModuleDefId::FunctionId(it) => {
18 }; 18 fn_def = Some(it);
19 break 'outer;
20 }
21 _ => {}
22 }
23 }
24 }
19 25
20 db.body(fn_def.into()) 26 db.body(fn_def.unwrap().into())
21} 27}
22 28
23fn check_diagnostics(ra_fixture: &str) { 29fn check_diagnostics(ra_fixture: &str) {
@@ -42,6 +48,25 @@ fn main() { n_nuple!(1,2,3); }
42} 48}
43 49
44#[test] 50#[test]
51fn macro_resolve() {
52 // Regression test for a path resolution bug introduced with inner item handling.
53 lower(
54 r"
55macro_rules! vec {
56 () => { () };
57 ($elem:expr; $n:expr) => { () };
58 ($($x:expr),+ $(,)?) => { () };
59}
60mod m {
61 fn outer() {
62 let _ = vec![FileSet::default(); self.len()];
63 }
64}
65 ",
66 );
67}
68
69#[test]
45fn cfg_diagnostics() { 70fn cfg_diagnostics() {
46 check_diagnostics( 71 check_diagnostics(
47 r" 72 r"
diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs
index 91c8d45cd..a87c80b8a 100644
--- a/crates/hir_def/src/db.rs
+++ b/crates/hir_def/src/db.rs
@@ -2,9 +2,9 @@
2use std::sync::Arc; 2use std::sync::Arc;
3 3
4use base_db::{salsa, CrateId, SourceDatabase, Upcast}; 4use base_db::{salsa, CrateId, SourceDatabase, Upcast};
5use hir_expand::{db::AstDatabase, HirFileId}; 5use hir_expand::{db::AstDatabase, AstId, HirFileId};
6use la_arena::ArenaMap; 6use la_arena::ArenaMap;
7use syntax::SmolStr; 7use syntax::{ast, SmolStr};
8 8
9use crate::{ 9use crate::{
10 adt::{EnumData, StructData}, 10 adt::{EnumData, StructData},
@@ -55,6 +55,9 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
55 #[salsa::invoke(DefMap::crate_def_map_query)] 55 #[salsa::invoke(DefMap::crate_def_map_query)]
56 fn crate_def_map_query(&self, krate: CrateId) -> Arc<DefMap>; 56 fn crate_def_map_query(&self, krate: CrateId) -> Arc<DefMap>;
57 57
58 #[salsa::invoke(DefMap::block_def_map_query)]
59 fn block_def_map(&self, krate: CrateId, block: AstId<ast::BlockExpr>) -> Arc<DefMap>;
60
58 #[salsa::invoke(StructData::struct_data_query)] 61 #[salsa::invoke(StructData::struct_data_query)]
59 fn struct_data(&self, id: StructId) -> Arc<StructData>; 62 fn struct_data(&self, id: StructId) -> Arc<StructData>;
60 #[salsa::invoke(StructData::union_data_query)] 63 #[salsa::invoke(StructData::union_data_query)]
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs
index 422a6eeb4..db2d125ae 100644
--- a/crates/hir_def/src/find_path.rs
+++ b/crates/hir_def/src/find_path.rs
@@ -51,7 +51,7 @@ fn check_self_super(def_map: &DefMap, item: ItemInNs, from: ModuleId) -> Option<
51 if item == ItemInNs::Types(from.into()) { 51 if item == ItemInNs::Types(from.into()) {
52 // - if the item is the module we're in, use `self` 52 // - if the item is the module we're in, use `self`
53 Some(ModPath::from_segments(PathKind::Super(0), Vec::new())) 53 Some(ModPath::from_segments(PathKind::Super(0), Vec::new()))
54 } else if let Some(parent_id) = def_map.modules[from.local_id].parent { 54 } else if let Some(parent_id) = def_map[from.local_id].parent {
55 // - if the item is the parent module, use `super` (this is not used recursively, since `super::super` is ugly) 55 // - if the item is the parent module, use `super` (this is not used recursively, since `super::super` is ugly)
56 if item 56 if item
57 == ItemInNs::Types(ModuleDefId::ModuleId(ModuleId { 57 == ItemInNs::Types(ModuleDefId::ModuleId(ModuleId {
@@ -111,7 +111,7 @@ fn find_path_inner(
111 111
112 // - if the item is already in scope, return the name under which it is 112 // - if the item is already in scope, return the name under which it is
113 let def_map = db.crate_def_map(from.krate); 113 let def_map = db.crate_def_map(from.krate);
114 let from_scope: &crate::item_scope::ItemScope = &def_map.modules[from.local_id].scope; 114 let from_scope: &crate::item_scope::ItemScope = &def_map[from.local_id].scope;
115 let scope_name = 115 let scope_name =
116 if let Some((name, _)) = from_scope.name_of(item) { Some(name.clone()) } else { None }; 116 if let Some((name, _)) = from_scope.name_of(item) { Some(name.clone()) } else { None };
117 if prefixed.is_none() && scope_name.is_some() { 117 if prefixed.is_none() && scope_name.is_some() {
@@ -123,7 +123,7 @@ fn find_path_inner(
123 if item 123 if item
124 == ItemInNs::Types(ModuleDefId::ModuleId(ModuleId { 124 == ItemInNs::Types(ModuleDefId::ModuleId(ModuleId {
125 krate: from.krate, 125 krate: from.krate,
126 local_id: def_map.root, 126 local_id: def_map.root(),
127 })) 127 }))
128 { 128 {
129 return Some(ModPath::from_segments(PathKind::Crate, Vec::new())); 129 return Some(ModPath::from_segments(PathKind::Crate, Vec::new()));
@@ -136,7 +136,7 @@ fn find_path_inner(
136 } 136 }
137 137
138 // - if the item is the crate root of a dependency crate, return the name from the extern prelude 138 // - if the item is the crate root of a dependency crate, return the name from the extern prelude
139 for (name, def_id) in &def_map.extern_prelude { 139 for (name, def_id) in def_map.extern_prelude() {
140 if item == ItemInNs::Types(*def_id) { 140 if item == ItemInNs::Types(*def_id) {
141 let name = scope_name.unwrap_or_else(|| name.clone()); 141 let name = scope_name.unwrap_or_else(|| name.clone());
142 return Some(ModPath::from_segments(PathKind::Plain, vec![name])); 142 return Some(ModPath::from_segments(PathKind::Plain, vec![name]));
@@ -144,10 +144,10 @@ fn find_path_inner(
144 } 144 }
145 145
146 // - if the item is in the prelude, return the name from there 146 // - if the item is in the prelude, return the name from there
147 if let Some(prelude_module) = def_map.prelude { 147 if let Some(prelude_module) = def_map.prelude() {
148 let prelude_def_map = db.crate_def_map(prelude_module.krate); 148 let prelude_def_map = db.crate_def_map(prelude_module.krate);
149 let prelude_scope: &crate::item_scope::ItemScope = 149 let prelude_scope: &crate::item_scope::ItemScope =
150 &prelude_def_map.modules[prelude_module.local_id].scope; 150 &prelude_def_map[prelude_module.local_id].scope;
151 if let Some((name, vis)) = prelude_scope.name_of(item) { 151 if let Some((name, vis)) = prelude_scope.name_of(item) {
152 if vis.is_visible_from(db, from) { 152 if vis.is_visible_from(db, from) {
153 return Some(ModPath::from_segments(PathKind::Plain, vec![name.clone()])); 153 return Some(ModPath::from_segments(PathKind::Plain, vec![name.clone()]));
@@ -175,7 +175,7 @@ fn find_path_inner(
175 175
176 // - otherwise, look for modules containing (reexporting) it and import it from one of those 176 // - otherwise, look for modules containing (reexporting) it and import it from one of those
177 177
178 let crate_root = ModuleId { local_id: def_map.root, krate: from.krate }; 178 let crate_root = ModuleId { local_id: def_map.root(), krate: from.krate };
179 let crate_attrs = db.attrs(crate_root.into()); 179 let crate_attrs = db.attrs(crate_root.into());
180 let prefer_no_std = crate_attrs.by_key("no_std").exists(); 180 let prefer_no_std = crate_attrs.by_key("no_std").exists();
181 let mut best_path = None; 181 let mut best_path = None;
@@ -287,7 +287,7 @@ fn find_local_import_locations(
287 287
288 // Compute the initial worklist. We start with all direct child modules of `from` as well as all 288 // Compute the initial worklist. We start with all direct child modules of `from` as well as all
289 // of its (recursive) parent modules. 289 // of its (recursive) parent modules.
290 let data = &def_map.modules[from.local_id]; 290 let data = &def_map[from.local_id];
291 let mut worklist = data 291 let mut worklist = data
292 .children 292 .children
293 .values() 293 .values()
@@ -296,7 +296,7 @@ fn find_local_import_locations(
296 let mut parent = data.parent; 296 let mut parent = data.parent;
297 while let Some(p) = parent { 297 while let Some(p) = parent {
298 worklist.push(ModuleId { krate: from.krate, local_id: p }); 298 worklist.push(ModuleId { krate: from.krate, local_id: p });
299 parent = def_map.modules[p].parent; 299 parent = def_map[p].parent;
300 } 300 }
301 301
302 let mut seen: FxHashSet<_> = FxHashSet::default(); 302 let mut seen: FxHashSet<_> = FxHashSet::default();
diff --git a/crates/hir_def/src/import_map.rs b/crates/hir_def/src/import_map.rs
index fac0de90c..0251d016b 100644
--- a/crates/hir_def/src/import_map.rs
+++ b/crates/hir_def/src/import_map.rs
@@ -75,7 +75,7 @@ impl ImportMap {
75 75
76 // We look only into modules that are public(ly reexported), starting with the crate root. 76 // We look only into modules that are public(ly reexported), starting with the crate root.
77 let empty = ImportPath { segments: vec![] }; 77 let empty = ImportPath { segments: vec![] };
78 let root = ModuleId { krate, local_id: def_map.root }; 78 let root = ModuleId { krate, local_id: def_map.root() };
79 let mut worklist = vec![(root, empty)]; 79 let mut worklist = vec![(root, empty)];
80 while let Some((module, mod_path)) = worklist.pop() { 80 while let Some((module, mod_path)) = worklist.pop() {
81 let ext_def_map; 81 let ext_def_map;
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index ff62928df..b8d7608e7 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -21,6 +21,7 @@ use hir_expand::{
21 HirFileId, InFile, 21 HirFileId, InFile,
22}; 22};
23use la_arena::{Arena, Idx, RawIdx}; 23use la_arena::{Arena, Idx, RawIdx};
24use profile::Count;
24use rustc_hash::FxHashMap; 25use rustc_hash::FxHashMap;
25use smallvec::SmallVec; 26use smallvec::SmallVec;
26use syntax::{ast, match_ast}; 27use syntax::{ast, match_ast};
@@ -67,15 +68,16 @@ impl GenericParamsId {
67/// The item tree of a source file. 68/// The item tree of a source file.
68#[derive(Debug, Eq, PartialEq)] 69#[derive(Debug, Eq, PartialEq)]
69pub struct ItemTree { 70pub struct ItemTree {
71 _c: Count<Self>,
72
70 top_level: SmallVec<[ModItem; 1]>, 73 top_level: SmallVec<[ModItem; 1]>,
71 attrs: FxHashMap<AttrOwner, RawAttrs>, 74 attrs: FxHashMap<AttrOwner, RawAttrs>,
72 inner_items: FxHashMap<FileAstId<ast::Item>, SmallVec<[ModItem; 1]>>,
73 75
74 data: Option<Box<ItemTreeData>>, 76 data: Option<Box<ItemTreeData>>,
75} 77}
76 78
77impl ItemTree { 79impl ItemTree {
78 pub fn item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> { 80 pub(crate) fn item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> {
79 let _p = profile::span("item_tree_query").detail(|| format!("{:?}", file_id)); 81 let _p = profile::span("item_tree_query").detail(|| format!("{:?}", file_id));
80 let syntax = if let Some(node) = db.parse_or_expand(file_id) { 82 let syntax = if let Some(node) = db.parse_or_expand(file_id) {
81 node 83 node
@@ -118,9 +120,9 @@ impl ItemTree {
118 120
119 fn empty() -> Self { 121 fn empty() -> Self {
120 Self { 122 Self {
123 _c: Count::new(),
121 top_level: Default::default(), 124 top_level: Default::default(),
122 attrs: Default::default(), 125 attrs: Default::default(),
123 inner_items: Default::default(),
124 data: Default::default(), 126 data: Default::default(),
125 } 127 }
126 } 128 }
@@ -147,6 +149,7 @@ impl ItemTree {
147 macro_defs, 149 macro_defs,
148 vis, 150 vis,
149 generics, 151 generics,
152 inner_items,
150 } = &mut **data; 153 } = &mut **data;
151 154
152 imports.shrink_to_fit(); 155 imports.shrink_to_fit();
@@ -169,6 +172,8 @@ impl ItemTree {
169 172
170 vis.arena.shrink_to_fit(); 173 vis.arena.shrink_to_fit();
171 generics.arena.shrink_to_fit(); 174 generics.arena.shrink_to_fit();
175
176 inner_items.shrink_to_fit();
172 } 177 }
173 } 178 }
174 179
@@ -191,16 +196,18 @@ impl ItemTree {
191 self.raw_attrs(of).clone().filter(db, krate) 196 self.raw_attrs(of).clone().filter(db, krate)
192 } 197 }
193 198
194 /// Returns the lowered inner items that `ast` corresponds to. 199 pub fn all_inner_items(&self) -> impl Iterator<Item = ModItem> + '_ {
195 /// 200 match &self.data {
196 /// Most AST items are lowered to a single `ModItem`, but some (eg. `use` items) may be lowered 201 Some(data) => Some(data.inner_items.values().flatten().copied()).into_iter().flatten(),
197 /// to multiple items in the `ItemTree`. 202 None => None.into_iter().flatten(),
198 pub fn inner_items(&self, ast: FileAstId<ast::Item>) -> &[ModItem] { 203 }
199 &self.inner_items[&ast]
200 } 204 }
201 205
202 pub fn all_inner_items(&self) -> impl Iterator<Item = ModItem> + '_ { 206 pub fn inner_items_of_block(&self, block: FileAstId<ast::BlockExpr>) -> &[ModItem] {
203 self.inner_items.values().flatten().copied() 207 match &self.data {
208 Some(data) => data.inner_items.get(&block).map(|it| &**it).unwrap_or(&[]),
209 None => &[],
210 }
204 } 211 }
205 212
206 pub fn source<S: ItemTreeNode>(&self, db: &dyn DefDatabase, of: ItemTreeId<S>) -> S::Source { 213 pub fn source<S: ItemTreeNode>(&self, db: &dyn DefDatabase, of: ItemTreeId<S>) -> S::Source {
@@ -297,6 +304,8 @@ struct ItemTreeData {
297 304
298 vis: ItemVisibilities, 305 vis: ItemVisibilities,
299 generics: GenericParamsStorage, 306 generics: GenericParamsStorage,
307
308 inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>,
300} 309}
301 310
302#[derive(Debug, Eq, PartialEq, Hash)] 311#[derive(Debug, Eq, PartialEq, Hash)]
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index 5e71ca42c..ce470fc3b 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -6,7 +6,7 @@ use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, name::known, HirFileId}
6use smallvec::SmallVec; 6use smallvec::SmallVec;
7use syntax::{ 7use syntax::{
8 ast::{self, ModuleItemOwner}, 8 ast::{self, ModuleItemOwner},
9 SyntaxNode, 9 SyntaxNode, WalkEvent,
10}; 10};
11 11
12use crate::{ 12use crate::{
@@ -37,7 +37,6 @@ pub(super) struct Ctx {
37 file: HirFileId, 37 file: HirFileId,
38 source_ast_id_map: Arc<AstIdMap>, 38 source_ast_id_map: Arc<AstIdMap>,
39 body_ctx: crate::body::LowerCtx, 39 body_ctx: crate::body::LowerCtx,
40 inner_items: Vec<ModItem>,
41 forced_visibility: Option<RawVisibilityId>, 40 forced_visibility: Option<RawVisibilityId>,
42} 41}
43 42
@@ -49,7 +48,6 @@ impl Ctx {
49 file, 48 file,
50 source_ast_id_map: db.ast_id_map(file), 49 source_ast_id_map: db.ast_id_map(file),
51 body_ctx: crate::body::LowerCtx::new(db, file), 50 body_ctx: crate::body::LowerCtx::new(db, file),
52 inner_items: Vec::new(),
53 forced_visibility: None, 51 forced_visibility: None,
54 } 52 }
55 } 53 }
@@ -73,8 +71,6 @@ impl Ctx {
73 } 71 }
74 72
75 fn lower_mod_item(&mut self, item: &ast::Item, inner: bool) -> Option<ModItems> { 73 fn lower_mod_item(&mut self, item: &ast::Item, inner: bool) -> Option<ModItems> {
76 assert!(inner || self.inner_items.is_empty());
77
78 // Collect inner items for 1-to-1-lowered items. 74 // Collect inner items for 1-to-1-lowered items.
79 match item { 75 match item {
80 ast::Item::Struct(_) 76 ast::Item::Struct(_)
@@ -150,14 +146,37 @@ impl Ctx {
150 146
151 fn collect_inner_items(&mut self, container: &SyntaxNode) { 147 fn collect_inner_items(&mut self, container: &SyntaxNode) {
152 let forced_vis = self.forced_visibility.take(); 148 let forced_vis = self.forced_visibility.take();
153 let mut inner_items = mem::take(&mut self.tree.inner_items); 149
154 inner_items.extend(container.descendants().skip(1).filter_map(ast::Item::cast).filter_map( 150 let mut block_stack = Vec::new();
155 |item| { 151 for event in container.preorder().skip(1) {
156 let ast_id = self.source_ast_id_map.ast_id(&item); 152 match event {
157 Some((ast_id, self.lower_mod_item(&item, true)?.0)) 153 WalkEvent::Enter(node) => {
158 }, 154 match_ast! {
159 )); 155 match node {
160 self.tree.inner_items = inner_items; 156 ast::BlockExpr(block) => {
157 block_stack.push(self.source_ast_id_map.ast_id(&block));
158 },
159 ast::Item(item) => {
160 let mod_items = self.lower_mod_item(&item, true);
161 let current_block = block_stack.last();
162 if let (Some(mod_items), Some(block)) = (mod_items, current_block) {
163 if !mod_items.0.is_empty() {
164 self.data().inner_items.entry(*block).or_default().extend(mod_items.0.iter().copied());
165 }
166 }
167 },
168 _ => {}
169 }
170 }
171 }
172 WalkEvent::Leave(node) => {
173 if ast::BlockExpr::cast(node).is_some() {
174 block_stack.pop();
175 }
176 }
177 }
178 }
179
161 self.forced_visibility = forced_vis; 180 self.forced_visibility = forced_vis;
162 } 181 }
163 182
diff --git a/crates/hir_def/src/lang_item.rs b/crates/hir_def/src/lang_item.rs
index 30188b740..9e90f745c 100644
--- a/crates/hir_def/src/lang_item.rs
+++ b/crates/hir_def/src/lang_item.rs
@@ -84,7 +84,7 @@ impl LangItems {
84 84
85 let crate_def_map = db.crate_def_map(krate); 85 let crate_def_map = db.crate_def_map(krate);
86 86
87 for (_, module_data) in crate_def_map.modules.iter() { 87 for (_, module_data) in crate_def_map.modules() {
88 for impl_def in module_data.scope.impls() { 88 for impl_def in module_data.scope.impls() {
89 lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDefId) 89 lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDefId)
90 } 90 }
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index 769a557ad..bd3ea9b8b 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -59,9 +59,10 @@ use std::sync::Arc;
59use base_db::{CrateId, Edition, FileId}; 59use base_db::{CrateId, Edition, FileId};
60use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile}; 60use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile};
61use la_arena::Arena; 61use la_arena::Arena;
62use profile::Count;
62use rustc_hash::FxHashMap; 63use rustc_hash::FxHashMap;
63use stdx::format_to; 64use stdx::format_to;
64use syntax::ast; 65use syntax::{ast, AstNode};
65 66
66use crate::{ 67use crate::{
67 db::DefDatabase, 68 db::DefDatabase,
@@ -75,14 +76,16 @@ use crate::{
75/// Contains all top-level defs from a macro-expanded crate 76/// Contains all top-level defs from a macro-expanded crate
76#[derive(Debug, PartialEq, Eq)] 77#[derive(Debug, PartialEq, Eq)]
77pub struct DefMap { 78pub struct DefMap {
78 pub root: LocalModuleId, 79 _c: Count<Self>,
79 pub modules: Arena<ModuleData>, 80 parent: Option<Arc<DefMap>>,
80 pub(crate) krate: CrateId, 81 root: LocalModuleId,
82 modules: Arena<ModuleData>,
83 krate: CrateId,
81 /// The prelude module for this crate. This either comes from an import 84 /// The prelude module for this crate. This either comes from an import
82 /// marked with the `prelude_import` attribute, or (in the normal case) from 85 /// marked with the `prelude_import` attribute, or (in the normal case) from
83 /// a dependency (`std` or `core`). 86 /// a dependency (`std` or `core`).
84 pub(crate) prelude: Option<ModuleId>, 87 prelude: Option<ModuleId>,
85 pub(crate) extern_prelude: FxHashMap<Name, ModuleDefId>, 88 extern_prelude: FxHashMap<Name, ModuleDefId>,
86 89
87 edition: Edition, 90 edition: Edition,
88 diagnostics: Vec<DefDiagnostic>, 91 diagnostics: Vec<DefDiagnostic>,
@@ -109,6 +112,10 @@ pub enum ModuleOrigin {
109 Inline { 112 Inline {
110 definition: AstId<ast::Module>, 113 definition: AstId<ast::Module>,
111 }, 114 },
115 /// Pseudo-module introduced by a block scope (contains only inner items).
116 BlockExpr {
117 block: AstId<ast::BlockExpr>,
118 },
112} 119}
113 120
114impl Default for ModuleOrigin { 121impl Default for ModuleOrigin {
@@ -122,7 +129,7 @@ impl ModuleOrigin {
122 match self { 129 match self {
123 ModuleOrigin::File { declaration: module, .. } 130 ModuleOrigin::File { declaration: module, .. }
124 | ModuleOrigin::Inline { definition: module, .. } => Some(*module), 131 | ModuleOrigin::Inline { definition: module, .. } => Some(*module),
125 ModuleOrigin::CrateRoot { .. } => None, 132 ModuleOrigin::CrateRoot { .. } | ModuleOrigin::BlockExpr { .. } => None,
126 } 133 }
127 } 134 }
128 135
@@ -137,7 +144,7 @@ impl ModuleOrigin {
137 144
138 pub fn is_inline(&self) -> bool { 145 pub fn is_inline(&self) -> bool {
139 match self { 146 match self {
140 ModuleOrigin::Inline { .. } => true, 147 ModuleOrigin::Inline { .. } | ModuleOrigin::BlockExpr { .. } => true,
141 ModuleOrigin::CrateRoot { .. } | ModuleOrigin::File { .. } => false, 148 ModuleOrigin::CrateRoot { .. } | ModuleOrigin::File { .. } => false,
142 } 149 }
143 } 150 }
@@ -155,6 +162,9 @@ impl ModuleOrigin {
155 definition.file_id, 162 definition.file_id,
156 ModuleSource::Module(definition.to_node(db.upcast())), 163 ModuleSource::Module(definition.to_node(db.upcast())),
157 ), 164 ),
165 ModuleOrigin::BlockExpr { block } => {
166 InFile::new(block.file_id, ModuleSource::BlockExpr(block.to_node(db.upcast())))
167 }
158 } 168 }
159 } 169 }
160} 170}
@@ -174,24 +184,51 @@ impl DefMap {
174 let _p = profile::span("crate_def_map_query").detail(|| { 184 let _p = profile::span("crate_def_map_query").detail(|| {
175 db.crate_graph()[krate].display_name.as_deref().unwrap_or_default().to_string() 185 db.crate_graph()[krate].display_name.as_deref().unwrap_or_default().to_string()
176 }); 186 });
177 let def_map = { 187 let edition = db.crate_graph()[krate].edition;
178 let edition = db.crate_graph()[krate].edition; 188 let def_map = DefMap::empty(krate, edition);
179 let mut modules: Arena<ModuleData> = Arena::default(); 189 let def_map = collector::collect_defs(db, def_map, None);
180 let root = modules.alloc(ModuleData::default());
181 DefMap {
182 krate,
183 edition,
184 extern_prelude: FxHashMap::default(),
185 prelude: None,
186 root,
187 modules,
188 diagnostics: Vec::new(),
189 }
190 };
191 let def_map = collector::collect_defs(db, def_map);
192 Arc::new(def_map) 190 Arc::new(def_map)
193 } 191 }
194 192
193 pub(crate) fn block_def_map_query(
194 db: &dyn DefDatabase,
195 krate: CrateId,
196 block: AstId<ast::BlockExpr>,
197 ) -> Arc<DefMap> {
198 let item_tree = db.item_tree(block.file_id);
199 let block_items = item_tree.inner_items_of_block(block.value);
200
201 let parent = parent_def_map(db, krate, block);
202
203 if block_items.is_empty() {
204 // If there are no inner items, nothing new is brought into scope, so we can just return
205 // the parent DefMap. This keeps DefMap parent chains short.
206 return parent;
207 }
208
209 let mut def_map = DefMap::empty(krate, parent.edition);
210 def_map.parent = Some(parent);
211
212 let def_map = collector::collect_defs(db, def_map, Some(block.value));
213 Arc::new(def_map)
214 }
215
216 fn empty(krate: CrateId, edition: Edition) -> DefMap {
217 let mut modules: Arena<ModuleData> = Arena::default();
218 let root = modules.alloc(ModuleData::default());
219 DefMap {
220 _c: Count::new(),
221 parent: None,
222 krate,
223 edition,
224 extern_prelude: FxHashMap::default(),
225 prelude: None,
226 root,
227 modules,
228 diagnostics: Vec::new(),
229 }
230 }
231
195 pub fn add_diagnostics( 232 pub fn add_diagnostics(
196 &self, 233 &self,
197 db: &dyn DefDatabase, 234 db: &dyn DefDatabase,
@@ -208,6 +245,26 @@ impl DefMap {
208 .map(|(id, _data)| id) 245 .map(|(id, _data)| id)
209 } 246 }
210 247
248 pub fn modules(&self) -> impl Iterator<Item = (LocalModuleId, &ModuleData)> + '_ {
249 self.modules.iter()
250 }
251
252 pub fn root(&self) -> LocalModuleId {
253 self.root
254 }
255
256 pub(crate) fn krate(&self) -> CrateId {
257 self.krate
258 }
259
260 pub(crate) fn prelude(&self) -> Option<ModuleId> {
261 self.prelude
262 }
263
264 pub(crate) fn extern_prelude(&self) -> impl Iterator<Item = (&Name, &ModuleDefId)> + '_ {
265 self.extern_prelude.iter()
266 }
267
211 pub(crate) fn resolve_path( 268 pub(crate) fn resolve_path(
212 &self, 269 &self,
213 db: &dyn DefDatabase, 270 db: &dyn DefDatabase,
@@ -224,7 +281,12 @@ impl DefMap {
224 // even), as this should be a great debugging aid. 281 // even), as this should be a great debugging aid.
225 pub fn dump(&self) -> String { 282 pub fn dump(&self) -> String {
226 let mut buf = String::new(); 283 let mut buf = String::new();
227 go(&mut buf, self, "crate", self.root); 284 let mut current_map = self;
285 while let Some(parent) = &current_map.parent {
286 go(&mut buf, current_map, "block scope", current_map.root);
287 current_map = &**parent;
288 }
289 go(&mut buf, current_map, "crate", current_map.root);
228 return buf; 290 return buf;
229 291
230 fn go(buf: &mut String, map: &DefMap, path: &str, module: LocalModuleId) { 292 fn go(buf: &mut String, map: &DefMap, path: &str, module: LocalModuleId) {
@@ -276,10 +338,40 @@ impl ModuleData {
276 } 338 }
277} 339}
278 340
341fn parent_def_map(
342 db: &dyn DefDatabase,
343 krate: CrateId,
344 block: AstId<ast::BlockExpr>,
345) -> Arc<DefMap> {
346 // FIXME: store this info in the item tree instead of reparsing here
347 let ast_id_map = db.ast_id_map(block.file_id);
348 let block_ptr = ast_id_map.get(block.value);
349 let root = match db.parse_or_expand(block.file_id) {
350 Some(it) => it,
351 None => {
352 return Arc::new(DefMap::empty(krate, Edition::Edition2018));
353 }
354 };
355 let ast = block_ptr.to_node(&root);
356
357 for ancestor in ast.syntax().ancestors().skip(1) {
358 if let Some(block_expr) = ast::BlockExpr::cast(ancestor) {
359 let ancestor_id = ast_id_map.ast_id(&block_expr);
360 let ast_id = InFile::new(block.file_id, ancestor_id);
361 let parent_map = db.block_def_map(krate, ast_id);
362 return parent_map;
363 }
364 }
365
366 // No enclosing block scope, so the parent is the crate-level DefMap.
367 db.crate_def_map(krate)
368}
369
279#[derive(Debug, Clone, PartialEq, Eq)] 370#[derive(Debug, Clone, PartialEq, Eq)]
280pub enum ModuleSource { 371pub enum ModuleSource {
281 SourceFile(ast::SourceFile), 372 SourceFile(ast::SourceFile),
282 Module(ast::Module), 373 Module(ast::Module),
374 BlockExpr(ast::BlockExpr),
283} 375}
284 376
285mod diagnostics { 377mod diagnostics {
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 61da56340..cd68efbe6 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -45,7 +45,11 @@ const GLOB_RECURSION_LIMIT: usize = 100;
45const EXPANSION_DEPTH_LIMIT: usize = 128; 45const EXPANSION_DEPTH_LIMIT: usize = 128;
46const FIXED_POINT_LIMIT: usize = 8192; 46const FIXED_POINT_LIMIT: usize = 8192;
47 47
48pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap) -> DefMap { 48pub(super) fn collect_defs(
49 db: &dyn DefDatabase,
50 mut def_map: DefMap,
51 block: Option<FileAstId<ast::BlockExpr>>,
52) -> DefMap {
49 let crate_graph = db.crate_graph(); 53 let crate_graph = db.crate_graph();
50 54
51 // populate external prelude 55 // populate external prelude
@@ -93,6 +97,14 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap) -> DefMap
93 exports_proc_macros: false, 97 exports_proc_macros: false,
94 from_glob_import: Default::default(), 98 from_glob_import: Default::default(),
95 }; 99 };
100 match block {
101 Some(block) => {
102 collector.seed_with_inner(block);
103 }
104 None => {
105 collector.seed_with_top_level();
106 }
107 }
96 collector.collect(); 108 collector.collect();
97 collector.finish() 109 collector.finish()
98} 110}
@@ -228,7 +240,7 @@ struct DefCollector<'a> {
228} 240}
229 241
230impl DefCollector<'_> { 242impl DefCollector<'_> {
231 fn collect(&mut self) { 243 fn seed_with_top_level(&mut self) {
232 let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id; 244 let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id;
233 let item_tree = self.db.item_tree(file_id.into()); 245 let item_tree = self.db.item_tree(file_id.into());
234 let module_id = self.def_map.root; 246 let module_id = self.def_map.root;
@@ -248,7 +260,31 @@ impl DefCollector<'_> {
248 } 260 }
249 .collect(item_tree.top_level_items()); 261 .collect(item_tree.top_level_items());
250 } 262 }
263 }
264
265 fn seed_with_inner(&mut self, block: FileAstId<ast::BlockExpr>) {
266 let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id;
267 let item_tree = self.db.item_tree(file_id.into());
268 let module_id = self.def_map.root;
269 self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id };
270 if item_tree
271 .top_level_attrs(self.db, self.def_map.krate)
272 .cfg()
273 .map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false))
274 {
275 ModCollector {
276 def_collector: &mut *self,
277 macro_depth: 0,
278 module_id,
279 file_id: file_id.into(),
280 item_tree: &item_tree,
281 mod_dir: ModDir::root(),
282 }
283 .collect(item_tree.inner_items_of_block(block));
284 }
285 }
251 286
287 fn collect(&mut self) {
252 // main name resolution fixed-point loop. 288 // main name resolution fixed-point loop.
253 let mut i = 0; 289 let mut i = 0;
254 loop { 290 loop {
@@ -1470,7 +1506,6 @@ impl ModCollector<'_, '_> {
1470mod tests { 1506mod tests {
1471 use crate::{db::DefDatabase, test_db::TestDB}; 1507 use crate::{db::DefDatabase, test_db::TestDB};
1472 use base_db::{fixture::WithFixture, SourceDatabase}; 1508 use base_db::{fixture::WithFixture, SourceDatabase};
1473 use la_arena::Arena;
1474 1509
1475 use super::*; 1510 use super::*;
1476 1511
@@ -1489,6 +1524,7 @@ mod tests {
1489 exports_proc_macros: false, 1524 exports_proc_macros: false,
1490 from_glob_import: Default::default(), 1525 from_glob_import: Default::default(),
1491 }; 1526 };
1527 collector.seed_with_top_level();
1492 collector.collect(); 1528 collector.collect();
1493 collector.def_map 1529 collector.def_map
1494 } 1530 }
@@ -1497,20 +1533,8 @@ mod tests {
1497 let (db, _file_id) = TestDB::with_single_file(&code); 1533 let (db, _file_id) = TestDB::with_single_file(&code);
1498 let krate = db.test_crate(); 1534 let krate = db.test_crate();
1499 1535
1500 let def_map = { 1536 let edition = db.crate_graph()[krate].edition;
1501 let edition = db.crate_graph()[krate].edition; 1537 let def_map = DefMap::empty(krate, edition);
1502 let mut modules: Arena<ModuleData> = Arena::default();
1503 let root = modules.alloc(ModuleData::default());
1504 DefMap {
1505 krate,
1506 edition,
1507 extern_prelude: FxHashMap::default(),
1508 prelude: None,
1509 root,
1510 modules,
1511 diagnostics: Vec::new(),
1512 }
1513 };
1514 do_collect_defs(&db, def_map) 1538 do_collect_defs(&db, def_map)
1515 } 1539 }
1516 1540
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs
index 096a7d0ac..ec90f4e65 100644
--- a/crates/hir_def/src/nameres/path_resolution.rs
+++ b/crates/hir_def/src/nameres/path_resolution.rs
@@ -104,6 +104,43 @@ impl DefMap {
104 path: &ModPath, 104 path: &ModPath,
105 shadow: BuiltinShadowMode, 105 shadow: BuiltinShadowMode,
106 ) -> ResolvePathResult { 106 ) -> ResolvePathResult {
107 let mut result = ResolvePathResult::empty(ReachedFixedPoint::No);
108 result.segment_index = Some(usize::max_value());
109
110 let mut current_map = self;
111 loop {
112 let new = current_map.resolve_path_fp_with_macro_single(
113 db,
114 mode,
115 original_module,
116 path,
117 shadow,
118 );
119
120 // Merge `new` into `result`.
121 result.resolved_def = result.resolved_def.or(new.resolved_def);
122 if result.reached_fixedpoint == ReachedFixedPoint::No {
123 result.reached_fixedpoint = new.reached_fixedpoint;
124 }
125 // FIXME: this doesn't seem right; what if the different namespace resolutions come from different crates?
126 result.krate = result.krate.or(new.krate);
127 result.segment_index = result.segment_index.min(new.segment_index);
128
129 match &current_map.parent {
130 Some(map) => current_map = map,
131 None => return result,
132 }
133 }
134 }
135
136 pub(super) fn resolve_path_fp_with_macro_single(
137 &self,
138 db: &dyn DefDatabase,
139 mode: ResolveMode,
140 original_module: LocalModuleId,
141 path: &ModPath,
142 shadow: BuiltinShadowMode,
143 ) -> ResolvePathResult {
107 let mut segments = path.segments.iter().enumerate(); 144 let mut segments = path.segments.iter().enumerate();
108 let mut curr_per_ns: PerNs = match path.kind { 145 let mut curr_per_ns: PerNs = match path.kind {
109 PathKind::DollarCrate(krate) => { 146 PathKind::DollarCrate(krate) => {
diff --git a/crates/hir_def/src/nameres/tests.rs b/crates/hir_def/src/nameres/tests.rs
index 723481c36..73e3a4702 100644
--- a/crates/hir_def/src/nameres/tests.rs
+++ b/crates/hir_def/src/nameres/tests.rs
@@ -4,11 +4,13 @@ mod macros;
4mod mod_resolution; 4mod mod_resolution;
5mod diagnostics; 5mod diagnostics;
6mod primitives; 6mod primitives;
7mod block;
7 8
8use std::sync::Arc; 9use std::sync::Arc;
9 10
10use base_db::{fixture::WithFixture, SourceDatabase}; 11use base_db::{fixture::WithFixture, SourceDatabase};
11use expect_test::{expect, Expect}; 12use expect_test::{expect, Expect};
13use hir_expand::db::AstDatabase;
12use test_utils::mark; 14use test_utils::mark;
13 15
14use crate::{db::DefDatabase, nameres::*, test_db::TestDB}; 16use crate::{db::DefDatabase, nameres::*, test_db::TestDB};
@@ -19,12 +21,30 @@ fn compute_crate_def_map(ra_fixture: &str) -> Arc<DefMap> {
19 db.crate_def_map(krate) 21 db.crate_def_map(krate)
20} 22}
21 23
24fn compute_block_def_map(ra_fixture: &str) -> Arc<DefMap> {
25 let (db, position) = TestDB::with_position(ra_fixture);
26 let module = db.module_for_file(position.file_id);
27 let ast_map = db.ast_id_map(position.file_id.into());
28 let ast = db.parse(position.file_id);
29 let block: ast::BlockExpr =
30 syntax::algo::find_node_at_offset(&ast.syntax_node(), position.offset).unwrap();
31 let block_id = ast_map.ast_id(&block);
32
33 db.block_def_map(module.krate, InFile::new(position.file_id.into(), block_id))
34}
35
22fn check(ra_fixture: &str, expect: Expect) { 36fn check(ra_fixture: &str, expect: Expect) {
23 let def_map = compute_crate_def_map(ra_fixture); 37 let def_map = compute_crate_def_map(ra_fixture);
24 let actual = def_map.dump(); 38 let actual = def_map.dump();
25 expect.assert_eq(&actual); 39 expect.assert_eq(&actual);
26} 40}
27 41
42fn check_at(ra_fixture: &str, expect: Expect) {
43 let def_map = compute_block_def_map(ra_fixture);
44 let actual = def_map.dump();
45 expect.assert_eq(&actual);
46}
47
28#[test] 48#[test]
29fn crate_def_map_smoke_test() { 49fn crate_def_map_smoke_test() {
30 check( 50 check(
diff --git a/crates/hir_def/src/nameres/tests/block.rs b/crates/hir_def/src/nameres/tests/block.rs
new file mode 100644
index 000000000..01d6326a7
--- /dev/null
+++ b/crates/hir_def/src/nameres/tests/block.rs
@@ -0,0 +1,97 @@
1use super::*;
2
3#[test]
4fn inner_item_smoke() {
5 check_at(
6 r#"
7struct inner {}
8fn outer() {
9 $0
10 fn inner() {}
11}
12"#,
13 expect![[r#"
14 block scope
15 inner: v
16 crate
17 inner: t
18 outer: v
19 "#]],
20 );
21}
22
23#[test]
24fn use_from_crate() {
25 check_at(
26 r#"
27struct Struct;
28fn outer() {
29 use Struct;
30 use crate::Struct as CrateStruct;
31 use self::Struct as SelfStruct;
32 $0
33}
34"#,
35 expect![[r#"
36 block scope
37 CrateStruct: t v
38 SelfStruct: t v
39 Struct: t v
40 crate
41 Struct: t v
42 outer: v
43 "#]],
44 );
45}
46
47#[test]
48fn merge_namespaces() {
49 check_at(
50 r#"
51struct name {}
52fn outer() {
53 fn name() {}
54
55 use name as imported; // should import both `name`s
56
57 $0
58}
59"#,
60 expect![[r#"
61 block scope
62 imported: t v
63 name: v
64 crate
65 name: t
66 outer: v
67 "#]],
68 );
69}
70
71#[test]
72fn nested_blocks() {
73 check_at(
74 r#"
75fn outer() {
76 struct inner1 {}
77 fn inner() {
78 use inner1;
79 use outer;
80 fn inner2() {}
81 $0
82 }
83}
84"#,
85 expect![[r#"
86 block scope
87 inner1: t
88 inner2: v
89 outer: v
90 block scope
91 inner: v
92 inner1: t
93 crate
94 outer: v
95 "#]],
96 );
97}
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs
index a505bf2be..b2f577649 100644
--- a/crates/hir_def/src/resolver.rs
+++ b/crates/hir_def/src/resolver.rs
@@ -146,6 +146,19 @@ impl Resolver {
146 self.resolve_module_path(db, path, BuiltinShadowMode::Module) 146 self.resolve_module_path(db, path, BuiltinShadowMode::Module)
147 } 147 }
148 148
149 pub fn resolve_module_path_in_trait_items(
150 &self,
151 db: &dyn DefDatabase,
152 path: &ModPath,
153 ) -> Option<TraitId> {
154 let (item_map, module) = self.module_scope()?;
155 let (module_res, ..) = item_map.resolve_path(db, module, &path, BuiltinShadowMode::Module);
156 match module_res.take_types()? {
157 ModuleDefId::TraitId(it) => Some(it),
158 _ => None,
159 }
160 }
161
149 pub fn resolve_path_in_type_ns( 162 pub fn resolve_path_in_type_ns(
150 &self, 163 &self,
151 db: &dyn DefDatabase, 164 db: &dyn DefDatabase,
@@ -416,7 +429,7 @@ impl Resolver {
416 let mut traits = FxHashSet::default(); 429 let mut traits = FxHashSet::default();
417 for scope in &self.scopes { 430 for scope in &self.scopes {
418 if let Scope::ModuleScope(m) = scope { 431 if let Scope::ModuleScope(m) = scope {
419 if let Some(prelude) = m.crate_def_map.prelude { 432 if let Some(prelude) = m.crate_def_map.prelude() {
420 let prelude_def_map = db.crate_def_map(prelude.krate); 433 let prelude_def_map = db.crate_def_map(prelude.krate);
421 traits.extend(prelude_def_map[prelude.local_id].scope.traits()); 434 traits.extend(prelude_def_map[prelude.local_id].scope.traits());
422 } 435 }
@@ -446,11 +459,11 @@ impl Resolver {
446 459
447 pub fn module(&self) -> Option<ModuleId> { 460 pub fn module(&self) -> Option<ModuleId> {
448 let (def_map, local_id) = self.module_scope()?; 461 let (def_map, local_id) = self.module_scope()?;
449 Some(ModuleId { krate: def_map.krate, local_id }) 462 Some(ModuleId { krate: def_map.krate(), local_id })
450 } 463 }
451 464
452 pub fn krate(&self) -> Option<CrateId> { 465 pub fn krate(&self) -> Option<CrateId> {
453 self.module_scope().map(|t| t.0.krate) 466 self.module_scope().map(|t| t.0.krate())
454 } 467 }
455 468
456 pub fn where_predicates_in_scope<'a>( 469 pub fn where_predicates_in_scope<'a>(
@@ -509,13 +522,13 @@ impl Scope {
509 seen.insert((name.clone(), scope)); 522 seen.insert((name.clone(), scope));
510 f(name.clone(), ScopeDef::PerNs(scope)); 523 f(name.clone(), ScopeDef::PerNs(scope));
511 }); 524 });
512 m.crate_def_map.extern_prelude.iter().for_each(|(name, &def)| { 525 m.crate_def_map.extern_prelude().for_each(|(name, &def)| {
513 f(name.clone(), ScopeDef::PerNs(PerNs::types(def, Visibility::Public))); 526 f(name.clone(), ScopeDef::PerNs(PerNs::types(def, Visibility::Public)));
514 }); 527 });
515 BUILTIN_SCOPE.iter().for_each(|(name, &def)| { 528 BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
516 f(name.clone(), ScopeDef::PerNs(def)); 529 f(name.clone(), ScopeDef::PerNs(def));
517 }); 530 });
518 if let Some(prelude) = m.crate_def_map.prelude { 531 if let Some(prelude) = m.crate_def_map.prelude() {
519 let prelude_def_map = db.crate_def_map(prelude.krate); 532 let prelude_def_map = db.crate_def_map(prelude.krate);
520 prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, def)| { 533 prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, def)| {
521 let seen_tuple = (name.clone(), def); 534 let seen_tuple = (name.clone(), def);
diff --git a/crates/hir_def/src/test_db.rs b/crates/hir_def/src/test_db.rs
index 574c0201a..4ff219fb7 100644
--- a/crates/hir_def/src/test_db.rs
+++ b/crates/hir_def/src/test_db.rs
@@ -75,7 +75,7 @@ impl TestDB {
75 pub(crate) fn module_for_file(&self, file_id: FileId) -> crate::ModuleId { 75 pub(crate) fn module_for_file(&self, file_id: FileId) -> crate::ModuleId {
76 for &krate in self.relevant_crates(file_id).iter() { 76 for &krate in self.relevant_crates(file_id).iter() {
77 let crate_def_map = self.crate_def_map(krate); 77 let crate_def_map = self.crate_def_map(krate);
78 for (local_id, data) in crate_def_map.modules.iter() { 78 for (local_id, data) in crate_def_map.modules() {
79 if data.origin.file_id() == Some(file_id) { 79 if data.origin.file_id() == Some(file_id) {
80 return crate::ModuleId { krate, local_id }; 80 return crate::ModuleId { krate, local_id };
81 } 81 }
@@ -110,7 +110,7 @@ impl TestDB {
110 let crate_graph = self.crate_graph(); 110 let crate_graph = self.crate_graph();
111 for krate in crate_graph.iter() { 111 for krate in crate_graph.iter() {
112 let crate_def_map = self.crate_def_map(krate); 112 let crate_def_map = self.crate_def_map(krate);
113 for (module_id, _) in crate_def_map.modules.iter() { 113 for (module_id, _) in crate_def_map.modules() {
114 let file_id = crate_def_map[module_id].origin.file_id(); 114 let file_id = crate_def_map[module_id].origin.file_id();
115 files.extend(file_id) 115 files.extend(file_id)
116 } 116 }
@@ -135,7 +135,7 @@ impl TestDB {
135 let crate_def_map = self.crate_def_map(krate); 135 let crate_def_map = self.crate_def_map(krate);
136 136
137 let mut sink = DiagnosticSinkBuilder::new().build(&mut cb); 137 let mut sink = DiagnosticSinkBuilder::new().build(&mut cb);
138 for (module_id, module) in crate_def_map.modules.iter() { 138 for (module_id, module) in crate_def_map.modules() {
139 crate_def_map.add_diagnostics(self, module_id, &mut sink); 139 crate_def_map.add_diagnostics(self, module_id, &mut sink);
140 140
141 for decl in module.scope.declarations() { 141 for decl in module.scope.declarations() {