aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def')
-rw-r--r--crates/hir_def/Cargo.toml2
-rw-r--r--crates/hir_def/src/adt.rs21
-rw-r--r--crates/hir_def/src/attr.rs2
-rw-r--r--crates/hir_def/src/body.rs11
-rw-r--r--crates/hir_def/src/body/lower.rs157
-rw-r--r--crates/hir_def/src/child_by_source.rs50
-rw-r--r--crates/hir_def/src/data.rs4
-rw-r--r--crates/hir_def/src/generics.rs4
-rw-r--r--crates/hir_def/src/item_scope.rs31
-rw-r--r--crates/hir_def/src/lib.rs56
-rw-r--r--crates/hir_def/src/nameres/collector.rs29
-rw-r--r--crates/hir_def/src/nameres/path_resolution.rs16
-rw-r--r--crates/hir_def/src/resolver.rs29
13 files changed, 107 insertions, 305 deletions
diff --git a/crates/hir_def/Cargo.toml b/crates/hir_def/Cargo.toml
index 2f07b6d01..c2d99280f 100644
--- a/crates/hir_def/Cargo.toml
+++ b/crates/hir_def/Cargo.toml
@@ -28,10 +28,10 @@ base_db = { path = "../base_db", version = "0.0.0" }
28syntax = { path = "../syntax", version = "0.0.0" } 28syntax = { path = "../syntax", version = "0.0.0" }
29profile = { path = "../profile", version = "0.0.0" } 29profile = { path = "../profile", version = "0.0.0" }
30hir_expand = { path = "../hir_expand", version = "0.0.0" } 30hir_expand = { path = "../hir_expand", version = "0.0.0" }
31test_utils = { path = "../test_utils", version = "0.0.0" }
32mbe = { path = "../mbe", version = "0.0.0" } 31mbe = { path = "../mbe", version = "0.0.0" }
33cfg = { path = "../cfg", version = "0.0.0" } 32cfg = { path = "../cfg", version = "0.0.0" }
34tt = { path = "../tt", version = "0.0.0" } 33tt = { path = "../tt", version = "0.0.0" }
35 34
36[dev-dependencies] 35[dev-dependencies]
36test_utils = { path = "../test_utils" }
37expect-test = "1.1" 37expect-test = "1.1"
diff --git a/crates/hir_def/src/adt.rs b/crates/hir_def/src/adt.rs
index ed36c3109..efbde17d8 100644
--- a/crates/hir_def/src/adt.rs
+++ b/crates/hir_def/src/adt.rs
@@ -21,8 +21,7 @@ use crate::{
21 trace::Trace, 21 trace::Trace,
22 type_ref::TypeRef, 22 type_ref::TypeRef,
23 visibility::RawVisibility, 23 visibility::RawVisibility,
24 EnumId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StructId, UnionId, 24 EnumId, LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StructId, UnionId, VariantId,
25 VariantId,
26}; 25};
27use cfg::CfgOptions; 26use cfg::CfgOptions;
28 27
@@ -92,10 +91,10 @@ fn parse_repr_tt(tt: &Subtree) -> Option<ReprKind> {
92impl StructData { 91impl StructData {
93 pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> { 92 pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> {
94 let loc = id.lookup(db); 93 let loc = id.lookup(db);
95 let krate = loc.container.module(db).krate; 94 let krate = loc.container.krate;
96 let item_tree = db.item_tree(loc.id.file_id); 95 let item_tree = db.item_tree(loc.id.file_id);
97 let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); 96 let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
98 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); 97 let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
99 98
100 let strukt = &item_tree[loc.id.value]; 99 let strukt = &item_tree[loc.id.value];
101 let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &strukt.fields, None); 100 let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &strukt.fields, None);
@@ -107,10 +106,10 @@ impl StructData {
107 } 106 }
108 pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> { 107 pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> {
109 let loc = id.lookup(db); 108 let loc = id.lookup(db);
110 let krate = loc.container.module(db).krate; 109 let krate = loc.container.krate;
111 let item_tree = db.item_tree(loc.id.file_id); 110 let item_tree = db.item_tree(loc.id.file_id);
112 let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); 111 let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
113 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); 112 let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
114 113
115 let union = &item_tree[loc.id.value]; 114 let union = &item_tree[loc.id.value];
116 let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &union.fields, None); 115 let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &union.fields, None);
@@ -126,7 +125,7 @@ impl StructData {
126impl EnumData { 125impl EnumData {
127 pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> { 126 pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> {
128 let loc = e.lookup(db); 127 let loc = e.lookup(db);
129 let krate = loc.container.module(db).krate; 128 let krate = loc.container.krate;
130 let item_tree = db.item_tree(loc.id.file_id); 129 let item_tree = db.item_tree(loc.id.file_id);
131 let cfg_options = db.crate_graph()[krate].cfg_options.clone(); 130 let cfg_options = db.crate_graph()[krate].cfg_options.clone();
132 131
@@ -168,7 +167,7 @@ impl HasChildSource<LocalEnumVariantId> for EnumId {
168 ) -> InFile<ArenaMap<LocalEnumVariantId, Self::Value>> { 167 ) -> InFile<ArenaMap<LocalEnumVariantId, Self::Value>> {
169 let src = self.lookup(db).source(db); 168 let src = self.lookup(db).source(db);
170 let mut trace = Trace::new_for_map(); 169 let mut trace = Trace::new_for_map();
171 lower_enum(db, &mut trace, &src, self.lookup(db).container.module(db)); 170 lower_enum(db, &mut trace, &src, self.lookup(db).container);
172 src.with_value(trace.into_map()) 171 src.with_value(trace.into_map())
173 } 172 }
174} 173}
@@ -238,10 +237,10 @@ impl HasChildSource<LocalFieldId> for VariantId {
238 // I don't really like the fact that we call into parent source 237 // I don't really like the fact that we call into parent source
239 // here, this might add to more queries then necessary. 238 // here, this might add to more queries then necessary.
240 let src = it.parent.child_source(db); 239 let src = it.parent.child_source(db);
241 (src.map(|map| map[it.local_id].kind()), it.parent.lookup(db).container.module(db)) 240 (src.map(|map| map[it.local_id].kind()), it.parent.lookup(db).container)
242 } 241 }
243 VariantId::StructId(it) => { 242 VariantId::StructId(it) => {
244 (it.lookup(db).source(db).map(|it| it.kind()), it.lookup(db).container.module(db)) 243 (it.lookup(db).source(db).map(|it| it.kind()), it.lookup(db).container)
245 } 244 }
246 VariantId::UnionId(it) => ( 245 VariantId::UnionId(it) => (
247 it.lookup(db).source(db).map(|it| { 246 it.lookup(db).source(db).map(|it| {
@@ -249,7 +248,7 @@ impl HasChildSource<LocalFieldId> for VariantId {
249 .map(ast::StructKind::Record) 248 .map(ast::StructKind::Record)
250 .unwrap_or(ast::StructKind::Unit) 249 .unwrap_or(ast::StructKind::Unit)
251 }), 250 }),
252 it.lookup(db).container.module(db), 251 it.lookup(db).container,
253 ), 252 ),
254 }; 253 };
255 let mut expander = CfgExpander::new(db, src.file_id, module_id.krate); 254 let mut expander = CfgExpander::new(db, src.file_id, module_id.krate);
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index b716d5f6e..97cdbbb9e 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -267,7 +267,7 @@ impl Attrs {
267 db: &dyn DefDatabase, 267 db: &dyn DefDatabase,
268 e: EnumId, 268 e: EnumId,
269 ) -> Arc<ArenaMap<LocalEnumVariantId, Attrs>> { 269 ) -> Arc<ArenaMap<LocalEnumVariantId, Attrs>> {
270 let krate = e.lookup(db).container.module(db).krate; 270 let krate = e.lookup(db).container.krate;
271 let src = e.child_source(db); 271 let src = e.child_source(db);
272 let mut res = ArenaMap::default(); 272 let mut res = ArenaMap::default();
273 273
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs
index b1a3fe1cb..19c4eb521 100644
--- a/crates/hir_def/src/body.rs
+++ b/crates/hir_def/src/body.rs
@@ -28,11 +28,10 @@ use crate::{
28 db::DefDatabase, 28 db::DefDatabase,
29 expr::{Expr, ExprId, Label, LabelId, Pat, PatId}, 29 expr::{Expr, ExprId, Label, LabelId, Pat, PatId},
30 item_scope::BuiltinShadowMode, 30 item_scope::BuiltinShadowMode,
31 item_scope::ItemScope,
32 nameres::DefMap, 31 nameres::DefMap,
33 path::{ModPath, Path}, 32 path::{ModPath, Path},
34 src::HasSource, 33 src::HasSource,
35 AsMacroCall, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleId, 34 AsMacroCall, BlockId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleId,
36}; 35};
37 36
38/// A subset of Expander that only deals with cfg attributes. We only need it to 37/// A subset of Expander that only deals with cfg attributes. We only need it to
@@ -226,7 +225,8 @@ pub struct Body {
226 pub params: Vec<PatId>, 225 pub params: Vec<PatId>,
227 /// The `ExprId` of the actual body expression. 226 /// The `ExprId` of the actual body expression.
228 pub body_expr: ExprId, 227 pub body_expr: ExprId,
229 pub item_scope: ItemScope, 228 /// Block expressions in this body that may contain inner items.
229 pub block_scopes: Vec<BlockId>,
230 _c: Count<Self>, 230 _c: Count<Self>,
231} 231}
232 232
@@ -295,7 +295,7 @@ impl Body {
295 } 295 }
296 }; 296 };
297 let expander = Expander::new(db, file_id, module); 297 let expander = Expander::new(db, file_id, module);
298 let (body, source_map) = Body::new(db, def, expander, params, body); 298 let (body, source_map) = Body::new(db, expander, params, body);
299 (Arc::new(body), Arc::new(source_map)) 299 (Arc::new(body), Arc::new(source_map))
300 } 300 }
301 301
@@ -305,12 +305,11 @@ impl Body {
305 305
306 fn new( 306 fn new(
307 db: &dyn DefDatabase, 307 db: &dyn DefDatabase,
308 def: DefWithBodyId,
309 expander: Expander, 308 expander: Expander,
310 params: Option<ast::ParamList>, 309 params: Option<ast::ParamList>,
311 body: Option<ast::Expr>, 310 body: Option<ast::Expr>,
312 ) -> (Body, BodySourceMap) { 311 ) -> (Body, BodySourceMap) {
313 lower::lower(db, def, expander, params, body) 312 lower::lower(db, expander, params, body)
314 } 313 }
315} 314}
316 315
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index d4abe819d..8c8eb8007 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -1,17 +1,16 @@
1//! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr` 1//! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr`
2//! representation. 2//! representation.
3 3
4use std::{any::type_name, mem, sync::Arc}; 4use std::mem;
5 5
6use either::Either; 6use either::Either;
7use hir_expand::{ 7use hir_expand::{
8 hygiene::Hygiene, 8 hygiene::Hygiene,
9 name::{name, AsName, Name}, 9 name::{name, AsName, Name},
10 ExpandError, HirFileId, MacroDefId, MacroDefKind, 10 ExpandError, HirFileId,
11}; 11};
12use la_arena::Arena; 12use la_arena::Arena;
13use profile::Count; 13use profile::Count;
14use rustc_hash::FxHashMap;
15use syntax::{ 14use syntax::{
16 ast::{ 15 ast::{
17 self, ArgListOwner, ArrayExprKind, AstChildren, LiteralKind, LoopBodyOwner, NameOwner, 16 self, ArgListOwner, ArrayExprKind, AstChildren, LiteralKind, LoopBodyOwner, NameOwner,
@@ -32,11 +31,9 @@ use crate::{
32 Statement, 31 Statement,
33 }, 32 },
34 item_scope::BuiltinShadowMode, 33 item_scope::BuiltinShadowMode,
35 item_tree::{ItemTree, ItemTreeId, ItemTreeNode},
36 path::{GenericArgs, Path}, 34 path::{GenericArgs, Path},
37 type_ref::{Mutability, Rawness, TypeRef}, 35 type_ref::{Mutability, Rawness, TypeRef},
38 AdtId, BlockLoc, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, 36 AdtId, BlockLoc, ModuleDefId,
39 ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
40}; 37};
41 38
42use super::{diagnostics::BodyDiagnostic, ExprSource, PatSource}; 39use super::{diagnostics::BodyDiagnostic, ExprSource, PatSource};
@@ -60,15 +57,12 @@ impl LowerCtx {
60 57
61pub(super) fn lower( 58pub(super) fn lower(
62 db: &dyn DefDatabase, 59 db: &dyn DefDatabase,
63 def: DefWithBodyId,
64 expander: Expander, 60 expander: Expander,
65 params: Option<ast::ParamList>, 61 params: Option<ast::ParamList>,
66 body: Option<ast::Expr>, 62 body: Option<ast::Expr>,
67) -> (Body, BodySourceMap) { 63) -> (Body, BodySourceMap) {
68 let item_tree = db.item_tree(expander.current_file_id);
69 ExprCollector { 64 ExprCollector {
70 db, 65 db,
71 def,
72 source_map: BodySourceMap::default(), 66 source_map: BodySourceMap::default(),
73 body: Body { 67 body: Body {
74 exprs: Arena::default(), 68 exprs: Arena::default(),
@@ -76,14 +70,9 @@ pub(super) fn lower(
76 labels: Arena::default(), 70 labels: Arena::default(),
77 params: Vec::new(), 71 params: Vec::new(),
78 body_expr: dummy_expr_id(), 72 body_expr: dummy_expr_id(),
79 item_scope: Default::default(), 73 block_scopes: Vec::new(),
80 _c: Count::new(), 74 _c: Count::new(),
81 }, 75 },
82 item_trees: {
83 let mut map = FxHashMap::default();
84 map.insert(expander.current_file_id, item_tree);
85 map
86 },
87 expander, 76 expander,
88 } 77 }
89 .collect(params, body) 78 .collect(params, body)
@@ -91,12 +80,9 @@ pub(super) fn lower(
91 80
92struct ExprCollector<'a> { 81struct ExprCollector<'a> {
93 db: &'a dyn DefDatabase, 82 db: &'a dyn DefDatabase,
94 def: DefWithBodyId,
95 expander: Expander, 83 expander: Expander,
96 body: Body, 84 body: Body,
97 source_map: BodySourceMap, 85 source_map: BodySourceMap,
98
99 item_trees: FxHashMap<HirFileId, Arc<ItemTree>>,
100} 86}
101 87
102impl ExprCollector<'_> { 88impl ExprCollector<'_> {
@@ -593,9 +579,6 @@ impl ExprCollector<'_> {
593 } else { 579 } else {
594 self.source_map.expansions.insert(macro_call, self.expander.current_file_id); 580 self.source_map.expansions.insert(macro_call, self.expander.current_file_id);
595 581
596 let item_tree = self.db.item_tree(self.expander.current_file_id);
597 self.item_trees.insert(self.expander.current_file_id, item_tree);
598
599 let id = collector(self, Some(expansion)); 582 let id = collector(self, Some(expansion));
600 self.expander.exit(self.db, mark); 583 self.expander.exit(self.db, mark);
601 id 584 id
@@ -605,32 +588,6 @@ impl ExprCollector<'_> {
605 } 588 }
606 } 589 }
607 590
608 fn find_inner_item<N: ItemTreeNode>(&self, ast: &N::Source) -> Option<ItemTreeId<N>> {
609 let id = self.expander.ast_id(ast);
610 let tree = &self.item_trees[&id.file_id];
611
612 // FIXME: This probably breaks with `use` items, since they produce multiple item tree nodes
613
614 // Root file (non-macro).
615 let item_tree_id = tree
616 .all_inner_items()
617 .chain(tree.top_level_items().iter().copied())
618 .filter_map(|mod_item| mod_item.downcast::<N>())
619 .find(|tree_id| tree[*tree_id].ast_id().upcast() == id.value.upcast())
620 .or_else(|| {
621 log::debug!(
622 "couldn't find inner {} item for {:?} (AST: `{}` - {:?})",
623 type_name::<N>(),
624 id,
625 ast.syntax(),
626 ast.syntax(),
627 );
628 None
629 })?;
630
631 Some(ItemTreeId::new(id.file_id, item_tree_id))
632 }
633
634 fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId { 591 fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId {
635 if let Some(expr) = expr { 592 if let Some(expr) = expr {
636 self.collect_expr(expr) 593 self.collect_expr(expr)
@@ -662,7 +619,6 @@ impl ExprCollector<'_> {
662 match expansion { 619 match expansion {
663 Some(expansion) => { 620 Some(expansion) => {
664 let statements: ast::MacroStmts = expansion; 621 let statements: ast::MacroStmts = expansion;
665 this.collect_stmts_items(statements.statements());
666 622
667 statements.statements().for_each(|stmt| { 623 statements.statements().for_each(|stmt| {
668 if let Some(mut r) = this.collect_stmt(stmt) { 624 if let Some(mut r) = this.collect_stmt(stmt) {
@@ -700,6 +656,8 @@ impl ExprCollector<'_> {
700 let block_loc = 656 let block_loc =
701 BlockLoc { ast_id, module: self.expander.def_map.module_id(self.expander.module) }; 657 BlockLoc { ast_id, module: self.expander.def_map.module_id(self.expander.module) };
702 let block_id = self.db.intern_block(block_loc); 658 let block_id = self.db.intern_block(block_loc);
659 self.body.block_scopes.push(block_id);
660
703 let opt_def_map = self.db.block_def_map(block_id); 661 let opt_def_map = self.db.block_def_map(block_id);
704 let has_def_map = opt_def_map.is_some(); 662 let has_def_map = opt_def_map.is_some();
705 let def_map = opt_def_map.unwrap_or_else(|| self.expander.def_map.clone()); 663 let def_map = opt_def_map.unwrap_or_else(|| self.expander.def_map.clone());
@@ -707,7 +665,6 @@ impl ExprCollector<'_> {
707 let prev_def_map = mem::replace(&mut self.expander.def_map, def_map); 665 let prev_def_map = mem::replace(&mut self.expander.def_map, def_map);
708 let prev_local_module = mem::replace(&mut self.expander.module, module); 666 let prev_local_module = mem::replace(&mut self.expander.module, module);
709 667
710 self.collect_stmts_items(block.statements());
711 let statements = 668 let statements =
712 block.statements().filter_map(|s| self.collect_stmt(s)).flatten().collect(); 669 block.statements().filter_map(|s| self.collect_stmt(s)).flatten().collect();
713 let tail = block.tail_expr().map(|e| self.collect_expr(e)); 670 let tail = block.tail_expr().map(|e| self.collect_expr(e));
@@ -722,108 +679,6 @@ impl ExprCollector<'_> {
722 expr_id 679 expr_id
723 } 680 }
724 681
725 fn collect_stmts_items(&mut self, stmts: ast::AstChildren<ast::Stmt>) {
726 let container = ContainerId::DefWithBodyId(self.def);
727
728 let items = stmts
729 .filter_map(|stmt| match stmt {
730 ast::Stmt::Item(it) => Some(it),
731 ast::Stmt::LetStmt(_) | ast::Stmt::ExprStmt(_) => None,
732 })
733 .filter_map(|item| {
734 let (def, name): (ModuleDefId, Option<ast::Name>) = match item {
735 ast::Item::Fn(def) => {
736 let id = self.find_inner_item(&def)?;
737 (
738 FunctionLoc { container: container.into(), id }.intern(self.db).into(),
739 def.name(),
740 )
741 }
742 ast::Item::TypeAlias(def) => {
743 let id = self.find_inner_item(&def)?;
744 (
745 TypeAliasLoc { container: container.into(), id }.intern(self.db).into(),
746 def.name(),
747 )
748 }
749 ast::Item::Const(def) => {
750 let id = self.find_inner_item(&def)?;
751 (
752 ConstLoc { container: container.into(), id }.intern(self.db).into(),
753 def.name(),
754 )
755 }
756 ast::Item::Static(def) => {
757 let id = self.find_inner_item(&def)?;
758 (StaticLoc { container, id }.intern(self.db).into(), def.name())
759 }
760 ast::Item::Struct(def) => {
761 let id = self.find_inner_item(&def)?;
762 (StructLoc { container, id }.intern(self.db).into(), def.name())
763 }
764 ast::Item::Enum(def) => {
765 let id = self.find_inner_item(&def)?;
766 (EnumLoc { container, id }.intern(self.db).into(), def.name())
767 }
768 ast::Item::Union(def) => {
769 let id = self.find_inner_item(&def)?;
770 (UnionLoc { container, id }.intern(self.db).into(), def.name())
771 }
772 ast::Item::Trait(def) => {
773 let id = self.find_inner_item(&def)?;
774 (TraitLoc { container, id }.intern(self.db).into(), def.name())
775 }
776 ast::Item::ExternBlock(_) => return None, // FIXME: collect from extern blocks
777 ast::Item::Impl(_)
778 | ast::Item::Use(_)
779 | ast::Item::ExternCrate(_)
780 | ast::Item::Module(_)
781 | ast::Item::MacroCall(_) => return None,
782 ast::Item::MacroRules(def) => {
783 return Some(Either::Right(ast::Macro::from(def)));
784 }
785 ast::Item::MacroDef(def) => {
786 return Some(Either::Right(ast::Macro::from(def)));
787 }
788 };
789
790 Some(Either::Left((def, name)))
791 })
792 .collect::<Vec<_>>();
793
794 for either in items {
795 match either {
796 Either::Left((def, name)) => {
797 self.body.item_scope.define_def(def);
798 if let Some(name) = name {
799 let vis = crate::visibility::Visibility::Public; // FIXME determine correctly
800 let has_constructor = match def {
801 ModuleDefId::AdtId(AdtId::StructId(s)) => {
802 self.db.struct_data(s).variant_data.kind() != StructKind::Record
803 }
804 _ => true,
805 };
806 self.body.item_scope.push_res(
807 name.as_name(),
808 crate::per_ns::PerNs::from_def(def, vis, has_constructor),
809 );
810 }
811 }
812 Either::Right(e) => {
813 let mac = MacroDefId {
814 krate: self.expander.def_map.krate(),
815 ast_id: Some(self.expander.ast_id(&e)),
816 kind: MacroDefKind::Declarative,
817 local_inner: false,
818 };
819 if let Some(name) = e.name() {
820 self.body.item_scope.define_legacy_macro(name.as_name(), mac);
821 }
822 }
823 }
824 }
825 }
826
827 fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId { 682 fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId {
828 if let Some(block) = expr { 683 if let Some(block) = expr {
829 self.collect_block(block) 684 self.collect_block(block)
diff --git a/crates/hir_def/src/child_by_source.rs b/crates/hir_def/src/child_by_source.rs
index 75c2d756b..2a331dcaf 100644
--- a/crates/hir_def/src/child_by_source.rs
+++ b/crates/hir_def/src/child_by_source.rs
@@ -17,13 +17,16 @@ use crate::{
17}; 17};
18 18
19pub trait ChildBySource { 19pub trait ChildBySource {
20 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap;
21}
22
23impl ChildBySource for TraitId {
24 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { 20 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap {
25 let mut res = DynMap::default(); 21 let mut res = DynMap::default();
22 self.child_by_source_to(db, &mut res);
23 res
24 }
25 fn child_by_source_to(&self, db: &dyn DefDatabase, map: &mut DynMap);
26}
26 27
28impl ChildBySource for TraitId {
29 fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) {
27 let data = db.trait_data(*self); 30 let data = db.trait_data(*self);
28 for (_name, item) in data.items.iter() { 31 for (_name, item) in data.items.iter() {
29 match *item { 32 match *item {
@@ -41,15 +44,11 @@ impl ChildBySource for TraitId {
41 } 44 }
42 } 45 }
43 } 46 }
44
45 res
46 } 47 }
47} 48}
48 49
49impl ChildBySource for ImplId { 50impl ChildBySource for ImplId {
50 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { 51 fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) {
51 let mut res = DynMap::default();
52
53 let data = db.impl_data(*self); 52 let data = db.impl_data(*self);
54 for &item in data.items.iter() { 53 for &item in data.items.iter() {
55 match item { 54 match item {
@@ -67,25 +66,21 @@ impl ChildBySource for ImplId {
67 } 66 }
68 } 67 }
69 } 68 }
70
71 res
72 } 69 }
73} 70}
74 71
75impl ChildBySource for ModuleId { 72impl ChildBySource for ModuleId {
76 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { 73 fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) {
77 let def_map = self.def_map(db); 74 let def_map = self.def_map(db);
78 let module_data = &def_map[self.local_id]; 75 let module_data = &def_map[self.local_id];
79 module_data.scope.child_by_source(db) 76 module_data.scope.child_by_source_to(db, res);
80 } 77 }
81} 78}
82 79
83impl ChildBySource for ItemScope { 80impl ChildBySource for ItemScope {
84 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { 81 fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) {
85 let mut res = DynMap::default(); 82 self.declarations().for_each(|item| add_module_def(db, res, item));
86 self.declarations().for_each(|item| add_module_def(db, &mut res, item)); 83 self.impls().for_each(|imp| add_impl(db, res, imp));
87 self.impls().for_each(|imp| add_impl(db, &mut res, imp));
88 return res;
89 84
90 fn add_module_def(db: &dyn DefDatabase, map: &mut DynMap, item: ModuleDefId) { 85 fn add_module_def(db: &dyn DefDatabase, map: &mut DynMap, item: ModuleDefId) {
91 match item { 86 match item {
@@ -134,9 +129,7 @@ impl ChildBySource for ItemScope {
134} 129}
135 130
136impl ChildBySource for VariantId { 131impl ChildBySource for VariantId {
137 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { 132 fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) {
138 let mut res = DynMap::default();
139
140 let arena_map = self.child_source(db); 133 let arena_map = self.child_source(db);
141 let arena_map = arena_map.as_ref(); 134 let arena_map = arena_map.as_ref();
142 for (local_id, source) in arena_map.value.iter() { 135 for (local_id, source) in arena_map.value.iter() {
@@ -150,28 +143,27 @@ impl ChildBySource for VariantId {
150 } 143 }
151 } 144 }
152 } 145 }
153 res
154 } 146 }
155} 147}
156 148
157impl ChildBySource for EnumId { 149impl ChildBySource for EnumId {
158 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { 150 fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) {
159 let mut res = DynMap::default();
160
161 let arena_map = self.child_source(db); 151 let arena_map = self.child_source(db);
162 let arena_map = arena_map.as_ref(); 152 let arena_map = arena_map.as_ref();
163 for (local_id, source) in arena_map.value.iter() { 153 for (local_id, source) in arena_map.value.iter() {
164 let id = EnumVariantId { parent: *self, local_id }; 154 let id = EnumVariantId { parent: *self, local_id };
165 res[keys::VARIANT].insert(arena_map.with_value(source.clone()), id) 155 res[keys::VARIANT].insert(arena_map.with_value(source.clone()), id)
166 } 156 }
167
168 res
169 } 157 }
170} 158}
171 159
172impl ChildBySource for DefWithBodyId { 160impl ChildBySource for DefWithBodyId {
173 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { 161 fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) {
174 let body = db.body(*self); 162 let body = db.body(*self);
175 body.item_scope.child_by_source(db) 163 for def_map in body.block_scopes.iter().filter_map(|block| db.block_def_map(*block)) {
164 // All block expressions are merged into the same map, because they logically all add
165 // inner items to the containing `DefWithBodyId`.
166 def_map[def_map.root()].scope.child_by_source_to(db, res);
167 }
176 } 168 }
177} 169}
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs
index d3380e0f4..aea53d527 100644
--- a/crates/hir_def/src/data.rs
+++ b/crates/hir_def/src/data.rs
@@ -97,7 +97,7 @@ impl TraitData {
97 let tr_def = &item_tree[tr_loc.id.value]; 97 let tr_def = &item_tree[tr_loc.id.value];
98 let name = tr_def.name.clone(); 98 let name = tr_def.name.clone();
99 let auto = tr_def.auto; 99 let auto = tr_def.auto;
100 let module_id = tr_loc.container.module(db); 100 let module_id = tr_loc.container;
101 let container = AssocContainerId::TraitId(tr); 101 let container = AssocContainerId::TraitId(tr);
102 let mut expander = Expander::new(db, tr_loc.id.file_id, module_id); 102 let mut expander = Expander::new(db, tr_loc.id.file_id, module_id);
103 103
@@ -147,7 +147,7 @@ impl ImplData {
147 let target_trait = impl_def.target_trait.map(|id| item_tree[id].clone()); 147 let target_trait = impl_def.target_trait.map(|id| item_tree[id].clone());
148 let target_type = item_tree[impl_def.target_type].clone(); 148 let target_type = item_tree[impl_def.target_type].clone();
149 let is_negative = impl_def.is_negative; 149 let is_negative = impl_def.is_negative;
150 let module_id = impl_loc.container.module(db); 150 let module_id = impl_loc.container;
151 let container = AssocContainerId::ImplId(id); 151 let container = AssocContainerId::ImplId(id);
152 let mut expander = Expander::new(db, impl_loc.id.file_id, module_id); 152 let mut expander = Expander::new(db, impl_loc.id.file_id, module_id);
153 153
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs
index 3ace3be1f..a056ab797 100644
--- a/crates/hir_def/src/generics.rs
+++ b/crates/hir_def/src/generics.rs
@@ -421,8 +421,7 @@ impl HasChildSource<LocalConstParamId> for GenericDefId {
421} 421}
422 422
423impl ChildBySource for GenericDefId { 423impl ChildBySource for GenericDefId {
424 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { 424 fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) {
425 let mut res = DynMap::default();
426 let (_, sm) = GenericParams::new(db, *self); 425 let (_, sm) = GenericParams::new(db, *self);
427 426
428 let sm = sm.as_ref(); 427 let sm = sm.as_ref();
@@ -440,6 +439,5 @@ impl ChildBySource for GenericDefId {
440 let id = ConstParamId { parent: *self, local_id }; 439 let id = ConstParamId { parent: *self, local_id };
441 res[keys::CONST_PARAM].insert(sm.with_value(src.clone()), id); 440 res[keys::CONST_PARAM].insert(sm.with_value(src.clone()), id);
442 } 441 }
443 res
444 } 442 }
445} 443}
diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs
index 919933813..aafd73b60 100644
--- a/crates/hir_def/src/item_scope.rs
+++ b/crates/hir_def/src/item_scope.rs
@@ -168,37 +168,6 @@ impl ItemScope {
168 self.unnamed_trait_imports.insert(tr, vis); 168 self.unnamed_trait_imports.insert(tr, vis);
169 } 169 }
170 170
171 pub(crate) fn push_res(&mut self, name: Name, def: PerNs) -> bool {
172 let mut changed = false;
173
174 if let Some(types) = def.types {
175 self.types.entry(name.clone()).or_insert_with(|| {
176 changed = true;
177 types
178 });
179 }
180 if let Some(values) = def.values {
181 self.values.entry(name.clone()).or_insert_with(|| {
182 changed = true;
183 values
184 });
185 }
186 if let Some(macros) = def.macros {
187 self.macros.entry(name.clone()).or_insert_with(|| {
188 changed = true;
189 macros
190 });
191 }
192
193 if def.is_none() {
194 if self.unresolved.insert(name) {
195 changed = true;
196 }
197 }
198
199 changed
200 }
201
202 pub(crate) fn push_res_with_import( 171 pub(crate) fn push_res_with_import(
203 &mut self, 172 &mut self,
204 glob_imports: &mut PerNsGlobImports, 173 glob_imports: &mut PerNsGlobImports,
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index 4498d94bb..6d11c5be4 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -108,7 +108,7 @@ pub type LocalModuleId = Idx<nameres::ModuleData>;
108 108
109#[derive(Debug)] 109#[derive(Debug)]
110pub struct ItemLoc<N: ItemTreeNode> { 110pub struct ItemLoc<N: ItemTreeNode> {
111 pub container: ContainerId, 111 pub container: ModuleId,
112 pub id: ItemTreeId<N>, 112 pub id: ItemTreeId<N>,
113} 113}
114 114
@@ -279,18 +279,12 @@ pub struct ConstParamId {
279pub type LocalConstParamId = Idx<generics::ConstParamData>; 279pub type LocalConstParamId = Idx<generics::ConstParamData>;
280 280
281#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 281#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
282pub enum ContainerId {
283 ModuleId(ModuleId),
284 DefWithBodyId(DefWithBodyId),
285}
286
287#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
288pub enum AssocContainerId { 282pub enum AssocContainerId {
289 ContainerId(ContainerId), 283 ModuleId(ModuleId),
290 ImplId(ImplId), 284 ImplId(ImplId),
291 TraitId(TraitId), 285 TraitId(TraitId),
292} 286}
293impl_from!(ContainerId for AssocContainerId); 287impl_from!(ModuleId for AssocContainerId);
294 288
295/// A Data Type 289/// A Data Type
296#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] 290#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
@@ -447,21 +441,12 @@ pub trait HasModule {
447 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId; 441 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId;
448} 442}
449 443
450impl HasModule for ContainerId {
451 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
452 match *self {
453 ContainerId::ModuleId(it) => it,
454 ContainerId::DefWithBodyId(it) => it.module(db),
455 }
456 }
457}
458
459impl HasModule for AssocContainerId { 444impl HasModule for AssocContainerId {
460 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { 445 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
461 match *self { 446 match *self {
462 AssocContainerId::ContainerId(it) => it.module(db), 447 AssocContainerId::ModuleId(it) => it,
463 AssocContainerId::ImplId(it) => it.lookup(db).container.module(db), 448 AssocContainerId::ImplId(it) => it.lookup(db).container,
464 AssocContainerId::TraitId(it) => it.lookup(db).container.module(db), 449 AssocContainerId::TraitId(it) => it.lookup(db).container,
465 } 450 }
466 } 451 }
467} 452}
@@ -479,16 +464,15 @@ impl HasModule for AdtId {
479 AdtId::UnionId(it) => it.lookup(db).container, 464 AdtId::UnionId(it) => it.lookup(db).container,
480 AdtId::EnumId(it) => it.lookup(db).container, 465 AdtId::EnumId(it) => it.lookup(db).container,
481 } 466 }
482 .module(db)
483 } 467 }
484} 468}
485 469
486impl HasModule for VariantId { 470impl HasModule for VariantId {
487 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { 471 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
488 match self { 472 match self {
489 VariantId::EnumVariantId(it) => it.parent.lookup(db).container.module(db), 473 VariantId::EnumVariantId(it) => it.parent.lookup(db).container,
490 VariantId::StructId(it) => it.lookup(db).container.module(db), 474 VariantId::StructId(it) => it.lookup(db).container,
491 VariantId::UnionId(it) => it.lookup(db).container.module(db), 475 VariantId::UnionId(it) => it.lookup(db).container,
492 } 476 }
493 } 477 }
494} 478}
@@ -518,18 +502,18 @@ impl HasModule for GenericDefId {
518 match self { 502 match self {
519 GenericDefId::FunctionId(it) => it.lookup(db).module(db), 503 GenericDefId::FunctionId(it) => it.lookup(db).module(db),
520 GenericDefId::AdtId(it) => it.module(db), 504 GenericDefId::AdtId(it) => it.module(db),
521 GenericDefId::TraitId(it) => it.lookup(db).container.module(db), 505 GenericDefId::TraitId(it) => it.lookup(db).container,
522 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), 506 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
523 GenericDefId::ImplId(it) => it.lookup(db).container.module(db), 507 GenericDefId::ImplId(it) => it.lookup(db).container,
524 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db), 508 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container,
525 GenericDefId::ConstId(it) => it.lookup(db).module(db), 509 GenericDefId::ConstId(it) => it.lookup(db).module(db),
526 } 510 }
527 } 511 }
528} 512}
529 513
530impl HasModule for StaticLoc { 514impl HasModule for StaticLoc {
531 fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { 515 fn module(&self, _db: &dyn db::DefDatabase) -> ModuleId {
532 self.container.module(db) 516 self.container
533 } 517 }
534} 518}
535 519
@@ -542,10 +526,10 @@ impl ModuleDefId {
542 ModuleDefId::ModuleId(id) => *id, 526 ModuleDefId::ModuleId(id) => *id,
543 ModuleDefId::FunctionId(id) => id.lookup(db).module(db), 527 ModuleDefId::FunctionId(id) => id.lookup(db).module(db),
544 ModuleDefId::AdtId(id) => id.module(db), 528 ModuleDefId::AdtId(id) => id.module(db),
545 ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container.module(db), 529 ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container,
546 ModuleDefId::ConstId(id) => id.lookup(db).container.module(db), 530 ModuleDefId::ConstId(id) => id.lookup(db).container.module(db),
547 ModuleDefId::StaticId(id) => id.lookup(db).container.module(db), 531 ModuleDefId::StaticId(id) => id.lookup(db).container,
548 ModuleDefId::TraitId(id) => id.lookup(db).container.module(db), 532 ModuleDefId::TraitId(id) => id.lookup(db).container,
549 ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db), 533 ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db),
550 ModuleDefId::BuiltinType(_) => return None, 534 ModuleDefId::BuiltinType(_) => return None,
551 }) 535 })
@@ -559,12 +543,12 @@ impl AttrDefId {
559 AttrDefId::FieldId(it) => it.parent.module(db).krate, 543 AttrDefId::FieldId(it) => it.parent.module(db).krate,
560 AttrDefId::AdtId(it) => it.module(db).krate, 544 AttrDefId::AdtId(it) => it.module(db).krate,
561 AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate, 545 AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate,
562 AttrDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db).krate, 546 AttrDefId::EnumVariantId(it) => it.parent.lookup(db).container.krate,
563 AttrDefId::StaticId(it) => it.lookup(db).module(db).krate, 547 AttrDefId::StaticId(it) => it.lookup(db).module(db).krate,
564 AttrDefId::ConstId(it) => it.lookup(db).module(db).krate, 548 AttrDefId::ConstId(it) => it.lookup(db).module(db).krate,
565 AttrDefId::TraitId(it) => it.lookup(db).container.module(db).krate, 549 AttrDefId::TraitId(it) => it.lookup(db).container.krate,
566 AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate, 550 AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate,
567 AttrDefId::ImplId(it) => it.lookup(db).container.module(db).krate, 551 AttrDefId::ImplId(it) => it.lookup(db).container.krate,
568 AttrDefId::GenericParamId(it) => { 552 AttrDefId::GenericParamId(it) => {
569 match it { 553 match it {
570 GenericParamId::TypeParamId(it) => it.parent, 554 GenericParamId::TypeParamId(it) => it.parent,
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 3bb69d935..9ed48c506 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -37,9 +37,9 @@ use crate::{
37 path::{ImportAlias, ModPath, PathKind}, 37 path::{ImportAlias, ModPath, PathKind},
38 per_ns::PerNs, 38 per_ns::PerNs,
39 visibility::{RawVisibility, Visibility}, 39 visibility::{RawVisibility, Visibility},
40 AdtId, AstId, AstIdWithPath, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, 40 AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern,
41 ImplLoc, Intern, LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, 41 LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
42 UnionLoc, UnresolvedMacro, 42 UnresolvedMacro,
43}; 43};
44 44
45const GLOB_RECURSION_LIMIT: usize = 100; 45const GLOB_RECURSION_LIMIT: usize = 100;
@@ -1042,7 +1042,6 @@ impl ModCollector<'_, '_> {
1042 } 1042 }
1043 } 1043 }
1044 let module = self.def_collector.def_map.module_id(self.module_id); 1044 let module = self.def_collector.def_map.module_id(self.module_id);
1045 let container = ContainerId::ModuleId(module);
1046 1045
1047 let mut def = None; 1046 let mut def = None;
1048 match item { 1047 match item {
@@ -1109,9 +1108,9 @@ impl ModCollector<'_, '_> {
1109 } 1108 }
1110 ModItem::Impl(imp) => { 1109 ModItem::Impl(imp) => {
1111 let module = self.def_collector.def_map.module_id(self.module_id); 1110 let module = self.def_collector.def_map.module_id(self.module_id);
1112 let container = ContainerId::ModuleId(module); 1111 let impl_id =
1113 let impl_id = ImplLoc { container, id: ItemTreeId::new(self.file_id, imp) } 1112 ImplLoc { container: module, id: ItemTreeId::new(self.file_id, imp) }
1114 .intern(self.def_collector.db); 1113 .intern(self.def_collector.db);
1115 self.def_collector.def_map.modules[self.module_id].scope.define_impl(impl_id) 1114 self.def_collector.def_map.modules[self.module_id].scope.define_impl(impl_id)
1116 } 1115 }
1117 ModItem::Function(id) => { 1116 ModItem::Function(id) => {
@@ -1121,7 +1120,7 @@ impl ModCollector<'_, '_> {
1121 1120
1122 def = Some(DefData { 1121 def = Some(DefData {
1123 id: FunctionLoc { 1122 id: FunctionLoc {
1124 container: container.into(), 1123 container: module.into(),
1125 id: ItemTreeId::new(self.file_id, id), 1124 id: ItemTreeId::new(self.file_id, id),
1126 } 1125 }
1127 .intern(self.def_collector.db) 1126 .intern(self.def_collector.db)
@@ -1140,7 +1139,7 @@ impl ModCollector<'_, '_> {
1140 self.collect_derives(&attrs, it.ast_id.upcast()); 1139 self.collect_derives(&attrs, it.ast_id.upcast());
1141 1140
1142 def = Some(DefData { 1141 def = Some(DefData {
1143 id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) } 1142 id: StructLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1144 .intern(self.def_collector.db) 1143 .intern(self.def_collector.db)
1145 .into(), 1144 .into(),
1146 name: &it.name, 1145 name: &it.name,
@@ -1157,7 +1156,7 @@ impl ModCollector<'_, '_> {
1157 self.collect_derives(&attrs, it.ast_id.upcast()); 1156 self.collect_derives(&attrs, it.ast_id.upcast());
1158 1157
1159 def = Some(DefData { 1158 def = Some(DefData {
1160 id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) } 1159 id: UnionLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1161 .intern(self.def_collector.db) 1160 .intern(self.def_collector.db)
1162 .into(), 1161 .into(),
1163 name: &it.name, 1162 name: &it.name,
@@ -1174,7 +1173,7 @@ impl ModCollector<'_, '_> {
1174 self.collect_derives(&attrs, it.ast_id.upcast()); 1173 self.collect_derives(&attrs, it.ast_id.upcast());
1175 1174
1176 def = Some(DefData { 1175 def = Some(DefData {
1177 id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) } 1176 id: EnumLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1178 .intern(self.def_collector.db) 1177 .intern(self.def_collector.db)
1179 .into(), 1178 .into(),
1180 name: &it.name, 1179 name: &it.name,
@@ -1188,7 +1187,7 @@ impl ModCollector<'_, '_> {
1188 if let Some(name) = &it.name { 1187 if let Some(name) = &it.name {
1189 def = Some(DefData { 1188 def = Some(DefData {
1190 id: ConstLoc { 1189 id: ConstLoc {
1191 container: container.into(), 1190 container: module.into(),
1192 id: ItemTreeId::new(self.file_id, id), 1191 id: ItemTreeId::new(self.file_id, id),
1193 } 1192 }
1194 .intern(self.def_collector.db) 1193 .intern(self.def_collector.db)
@@ -1203,7 +1202,7 @@ impl ModCollector<'_, '_> {
1203 let it = &self.item_tree[id]; 1202 let it = &self.item_tree[id];
1204 1203
1205 def = Some(DefData { 1204 def = Some(DefData {
1206 id: StaticLoc { container, id: ItemTreeId::new(self.file_id, id) } 1205 id: StaticLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1207 .intern(self.def_collector.db) 1206 .intern(self.def_collector.db)
1208 .into(), 1207 .into(),
1209 name: &it.name, 1208 name: &it.name,
@@ -1215,7 +1214,7 @@ impl ModCollector<'_, '_> {
1215 let it = &self.item_tree[id]; 1214 let it = &self.item_tree[id];
1216 1215
1217 def = Some(DefData { 1216 def = Some(DefData {
1218 id: TraitLoc { container, id: ItemTreeId::new(self.file_id, id) } 1217 id: TraitLoc { container: module, id: ItemTreeId::new(self.file_id, id) }
1219 .intern(self.def_collector.db) 1218 .intern(self.def_collector.db)
1220 .into(), 1219 .into(),
1221 name: &it.name, 1220 name: &it.name,
@@ -1228,7 +1227,7 @@ impl ModCollector<'_, '_> {
1228 1227
1229 def = Some(DefData { 1228 def = Some(DefData {
1230 id: TypeAliasLoc { 1229 id: TypeAliasLoc {
1231 container: container.into(), 1230 container: module.into(),
1232 id: ItemTreeId::new(self.file_id, id), 1231 id: ItemTreeId::new(self.file_id, id),
1233 } 1232 }
1234 .intern(self.def_collector.db) 1233 .intern(self.def_collector.db)
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs
index 8258dcffb..db459b1ed 100644
--- a/crates/hir_def/src/nameres/path_resolution.rs
+++ b/crates/hir_def/src/nameres/path_resolution.rs
@@ -156,7 +156,7 @@ impl DefMap {
156 } 156 }
157 } 157 }
158 158
159 pub(super) fn resolve_path_fp_with_macro_single( 159 fn resolve_path_fp_with_macro_single(
160 &self, 160 &self,
161 db: &dyn DefDatabase, 161 db: &dyn DefDatabase,
162 mode: ResolveMode, 162 mode: ResolveMode,
@@ -384,10 +384,16 @@ impl DefMap {
384 } 384 }
385 } 385 }
386 }; 386 };
387 let from_extern_prelude = self 387 // Give precedence to names in outer `DefMap`s over the extern prelude; only check prelude
388 .extern_prelude 388 // from the crate DefMap.
389 .get(name) 389 let from_extern_prelude = match self.block {
390 .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)); 390 Some(_) => PerNs::none(),
391 None => self
392 .extern_prelude
393 .get(name)
394 .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)),
395 };
396
391 let from_prelude = self.resolve_in_prelude(db, name); 397 let from_prelude = self.resolve_in_prelude(db, name);
392 398
393 from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude) 399 from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude)
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs
index 77ff21739..42736171e 100644
--- a/crates/hir_def/src/resolver.rs
+++ b/crates/hir_def/src/resolver.rs
@@ -19,10 +19,10 @@ use crate::{
19 path::{ModPath, PathKind}, 19 path::{ModPath, PathKind},
20 per_ns::PerNs, 20 per_ns::PerNs,
21 visibility::{RawVisibility, Visibility}, 21 visibility::{RawVisibility, Visibility},
22 AdtId, AssocContainerId, ConstId, ConstParamId, ContainerId, DefWithBodyId, EnumId, 22 AdtId, AssocContainerId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId,
23 EnumVariantId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, LifetimeParamId, 23 FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, LifetimeParamId, LocalModuleId,
24 LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, 24 Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId,
25 TypeParamId, VariantId, 25 VariantId,
26}; 26};
27 27
28#[derive(Debug, Clone, Default)] 28#[derive(Debug, Clone, Default)]
@@ -342,6 +342,16 @@ impl Resolver {
342 traits.extend(prelude_def_map[prelude.local_id].scope.traits()); 342 traits.extend(prelude_def_map[prelude.local_id].scope.traits());
343 } 343 }
344 traits.extend(m.def_map[m.module_id].scope.traits()); 344 traits.extend(m.def_map[m.module_id].scope.traits());
345
346 // Add all traits that are in scope because of the containing DefMaps
347 m.def_map.with_ancestor_maps(db, m.module_id, &mut |def_map, module| {
348 if let Some(prelude) = def_map.prelude() {
349 let prelude_def_map = prelude.def_map(db);
350 traits.extend(prelude_def_map[prelude.local_id].scope.traits());
351 }
352 traits.extend(def_map[module].scope.traits());
353 None::<()>
354 });
345 } 355 }
346 } 356 }
347 traits 357 traits
@@ -678,19 +688,10 @@ impl HasResolver for DefWithBodyId {
678 } 688 }
679} 689}
680 690
681impl HasResolver for ContainerId {
682 fn resolver(self, db: &dyn DefDatabase) -> Resolver {
683 match self {
684 ContainerId::ModuleId(it) => it.resolver(db),
685 ContainerId::DefWithBodyId(it) => it.module(db).resolver(db),
686 }
687 }
688}
689
690impl HasResolver for AssocContainerId { 691impl HasResolver for AssocContainerId {
691 fn resolver(self, db: &dyn DefDatabase) -> Resolver { 692 fn resolver(self, db: &dyn DefDatabase) -> Resolver {
692 match self { 693 match self {
693 AssocContainerId::ContainerId(it) => it.resolver(db), 694 AssocContainerId::ModuleId(it) => it.resolver(db),
694 AssocContainerId::TraitId(it) => it.resolver(db), 695 AssocContainerId::TraitId(it) => it.resolver(db),
695 AssocContainerId::ImplId(it) => it.resolver(db), 696 AssocContainerId::ImplId(it) => it.resolver(db),
696 } 697 }