aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/Cargo.toml1
-rw-r--r--crates/ra_hir_def/src/adt.rs2
-rw-r--r--crates/ra_hir_def/src/body.rs76
-rw-r--r--crates/ra_hir_def/src/body/lower.rs60
-rw-r--r--crates/ra_hir_def/src/child_by_source.rs101
-rw-r--r--crates/ra_hir_def/src/data.rs147
-rw-r--r--crates/ra_hir_def/src/db.rs11
-rw-r--r--crates/ra_hir_def/src/expr.rs1
-rw-r--r--crates/ra_hir_def/src/item_scope.rs155
-rw-r--r--crates/ra_hir_def/src/lang_item.rs2
-rw-r--r--crates/ra_hir_def/src/lib.rs289
-rw-r--r--crates/ra_hir_def/src/nameres.rs119
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs106
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs78
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs19
-rw-r--r--crates/ra_hir_def/src/nameres/tests/incremental.rs4
-rw-r--r--crates/ra_hir_def/src/nameres/tests/macros.rs4
-rw-r--r--crates/ra_hir_def/src/path.rs3
-rw-r--r--crates/ra_hir_def/src/resolver.rs22
-rw-r--r--crates/ra_hir_def/src/src.rs82
-rw-r--r--crates/ra_hir_def/src/trace.rs8
21 files changed, 611 insertions, 679 deletions
diff --git a/crates/ra_hir_def/Cargo.toml b/crates/ra_hir_def/Cargo.toml
index b1923bbf2..2c368f690 100644
--- a/crates/ra_hir_def/Cargo.toml
+++ b/crates/ra_hir_def/Cargo.toml
@@ -13,6 +13,7 @@ once_cell = "1.0.1"
13rustc-hash = "1.0" 13rustc-hash = "1.0"
14either = "1.5" 14either = "1.5"
15anymap = "0.12" 15anymap = "0.12"
16drop_bomb = "0.1.4"
16 17
17ra_arena = { path = "../ra_arena" } 18ra_arena = { path = "../ra_arena" }
18ra_db = { path = "../ra_db" } 19ra_db = { path = "../ra_db" }
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index ec3d57d1a..d9ea693e3 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -8,6 +8,7 @@ use hir_expand::{
8 InFile, 8 InFile,
9}; 9};
10use ra_arena::{map::ArenaMap, Arena}; 10use ra_arena::{map::ArenaMap, Arena};
11use ra_prof::profile;
11use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; 12use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
12 13
13use crate::{ 14use crate::{
@@ -72,6 +73,7 @@ impl StructData {
72 73
73impl EnumData { 74impl EnumData {
74 pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc<EnumData> { 75 pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc<EnumData> {
76 let _p = profile("enum_data_query");
75 let src = e.lookup(db).source(db); 77 let src = e.lookup(db).source(db);
76 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); 78 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name());
77 let mut trace = Trace::new_for_arena(); 79 let mut trace = Trace::new_for_arena();
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index d4cab0561..148ff007e 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -3,42 +3,53 @@
3mod lower; 3mod lower;
4pub mod scope; 4pub mod scope;
5 5
6use std::{ops::Index, sync::Arc}; 6use std::{mem, ops::Index, sync::Arc};
7 7
8use drop_bomb::DropBomb;
8use either::Either; 9use either::Either;
9use hir_expand::{hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId}; 10use hir_expand::{
11 ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId,
12};
10use ra_arena::{map::ArenaMap, Arena}; 13use ra_arena::{map::ArenaMap, Arena};
14use ra_prof::profile;
11use ra_syntax::{ast, AstNode, AstPtr}; 15use ra_syntax::{ast, AstNode, AstPtr};
12use rustc_hash::FxHashMap; 16use rustc_hash::FxHashMap;
13 17
14use crate::{ 18use crate::{
15 db::DefDatabase, 19 db::DefDatabase,
16 expr::{Expr, ExprId, Pat, PatId}, 20 expr::{Expr, ExprId, Pat, PatId},
17 nameres::{BuiltinShadowMode, CrateDefMap}, 21 item_scope::BuiltinShadowMode,
22 nameres::CrateDefMap,
18 path::{ModPath, Path}, 23 path::{ModPath, Path},
19 src::HasSource, 24 src::HasSource,
20 DefWithBodyId, HasModule, Lookup, ModuleId, 25 DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId,
21}; 26};
22 27
23struct Expander { 28pub(crate) struct Expander {
24 crate_def_map: Arc<CrateDefMap>, 29 crate_def_map: Arc<CrateDefMap>,
25 current_file_id: HirFileId, 30 current_file_id: HirFileId,
26 hygiene: Hygiene, 31 hygiene: Hygiene,
32 ast_id_map: Arc<AstIdMap>,
27 module: ModuleId, 33 module: ModuleId,
28} 34}
29 35
30impl Expander { 36impl Expander {
31 fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander { 37 pub(crate) fn new(
38 db: &impl DefDatabase,
39 current_file_id: HirFileId,
40 module: ModuleId,
41 ) -> Expander {
32 let crate_def_map = db.crate_def_map(module.krate); 42 let crate_def_map = db.crate_def_map(module.krate);
33 let hygiene = Hygiene::new(db, current_file_id); 43 let hygiene = Hygiene::new(db, current_file_id);
34 Expander { crate_def_map, current_file_id, hygiene, module } 44 let ast_id_map = db.ast_id_map(current_file_id);
45 Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module }
35 } 46 }
36 47
37 fn enter_expand( 48 pub(crate) fn enter_expand<T: ast::AstNode, DB: DefDatabase>(
38 &mut self, 49 &mut self,
39 db: &impl DefDatabase, 50 db: &DB,
40 macro_call: ast::MacroCall, 51 macro_call: ast::MacroCall,
41 ) -> Option<(Mark, ast::Expr)> { 52 ) -> Option<(Mark, T)> {
42 let ast_id = AstId::new( 53 let ast_id = AstId::new(
43 self.current_file_id, 54 self.current_file_id,
44 db.ast_id_map(self.current_file_id).ast_id(&macro_call), 55 db.ast_id_map(self.current_file_id).ast_id(&macro_call),
@@ -49,12 +60,17 @@ impl Expander {
49 let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id)); 60 let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id));
50 let file_id = call_id.as_file(); 61 let file_id = call_id.as_file();
51 if let Some(node) = db.parse_or_expand(file_id) { 62 if let Some(node) = db.parse_or_expand(file_id) {
52 if let Some(expr) = ast::Expr::cast(node) { 63 if let Some(expr) = T::cast(node) {
53 log::debug!("macro expansion {:#?}", expr.syntax()); 64 log::debug!("macro expansion {:#?}", expr.syntax());
54 65
55 let mark = Mark { file_id: self.current_file_id }; 66 let mark = Mark {
67 file_id: self.current_file_id,
68 ast_id_map: mem::take(&mut self.ast_id_map),
69 bomb: DropBomb::new("expansion mark dropped"),
70 };
56 self.hygiene = Hygiene::new(db, file_id); 71 self.hygiene = Hygiene::new(db, file_id);
57 self.current_file_id = file_id; 72 self.current_file_id = file_id;
73 self.ast_id_map = db.ast_id_map(file_id);
58 74
59 return Some((mark, expr)); 75 return Some((mark, expr));
60 } 76 }
@@ -67,13 +83,14 @@ impl Expander {
67 None 83 None
68 } 84 }
69 85
70 fn exit(&mut self, db: &impl DefDatabase, mark: Mark) { 86 pub(crate) fn exit(&mut self, db: &impl DefDatabase, mut mark: Mark) {
71 self.hygiene = Hygiene::new(db, mark.file_id); 87 self.hygiene = Hygiene::new(db, mark.file_id);
72 self.current_file_id = mark.file_id; 88 self.current_file_id = mark.file_id;
73 std::mem::forget(mark); 89 self.ast_id_map = mem::take(&mut mark.ast_id_map);
90 mark.bomb.defuse();
74 } 91 }
75 92
76 fn to_source<T>(&self, value: T) -> InFile<T> { 93 pub(crate) fn to_source<T>(&self, value: T) -> InFile<T> {
77 InFile { file_id: self.current_file_id, value } 94 InFile { file_id: self.current_file_id, value }
78 } 95 }
79 96
@@ -91,18 +108,17 @@ impl Expander {
91 .0 108 .0
92 .take_macros() 109 .take_macros()
93 } 110 }
94}
95 111
96struct Mark { 112 fn ast_id<N: AstNode>(&self, item: &N) -> AstId<N> {
97 file_id: HirFileId, 113 let file_local_id = self.ast_id_map.ast_id(item);
114 AstId::new(self.current_file_id, file_local_id)
115 }
98} 116}
99 117
100impl Drop for Mark { 118pub(crate) struct Mark {
101 fn drop(&mut self) { 119 file_id: HirFileId,
102 if !std::thread::panicking() { 120 ast_id_map: Arc<AstIdMap>,
103 panic!("dropped mark") 121 bomb: DropBomb,
104 }
105 }
106} 122}
107 123
108/// The body of an item (function, const etc.). 124/// The body of an item (function, const etc.).
@@ -119,6 +135,7 @@ pub struct Body {
119 pub params: Vec<PatId>, 135 pub params: Vec<PatId>,
120 /// The `ExprId` of the actual body expression. 136 /// The `ExprId` of the actual body expression.
121 pub body_expr: ExprId, 137 pub body_expr: ExprId,
138 pub defs: Vec<ModuleDefId>,
122} 139}
123 140
124pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>; 141pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>;
@@ -152,6 +169,7 @@ impl Body {
152 db: &impl DefDatabase, 169 db: &impl DefDatabase,
153 def: DefWithBodyId, 170 def: DefWithBodyId,
154 ) -> (Arc<Body>, Arc<BodySourceMap>) { 171 ) -> (Arc<Body>, Arc<BodySourceMap>) {
172 let _p = profile("body_with_source_map_query");
155 let mut params = None; 173 let mut params = None;
156 174
157 let (file_id, module, body) = match def { 175 let (file_id, module, body) = match def {
@@ -173,7 +191,7 @@ impl Body {
173 } 191 }
174 }; 192 };
175 let expander = Expander::new(db, file_id, module); 193 let expander = Expander::new(db, file_id, module);
176 let (body, source_map) = Body::new(db, expander, params, body); 194 let (body, source_map) = Body::new(db, def, expander, params, body);
177 (Arc::new(body), Arc::new(source_map)) 195 (Arc::new(body), Arc::new(source_map))
178 } 196 }
179 197
@@ -183,11 +201,12 @@ impl Body {
183 201
184 fn new( 202 fn new(
185 db: &impl DefDatabase, 203 db: &impl DefDatabase,
204 def: DefWithBodyId,
186 expander: Expander, 205 expander: Expander,
187 params: Option<ast::ParamList>, 206 params: Option<ast::ParamList>,
188 body: Option<ast::Expr>, 207 body: Option<ast::Expr>,
189 ) -> (Body, BodySourceMap) { 208 ) -> (Body, BodySourceMap) {
190 lower::lower(db, expander, params, body) 209 lower::lower(db, def, expander, params, body)
191 } 210 }
192} 211}
193 212
@@ -217,6 +236,11 @@ impl BodySourceMap {
217 self.expr_map.get(&src).cloned() 236 self.expr_map.get(&src).cloned()
218 } 237 }
219 238
239 pub fn field_init_shorthand_expr(&self, node: InFile<&ast::RecordField>) -> Option<ExprId> {
240 let src = node.map(|it| Either::Right(AstPtr::new(it)));
241 self.expr_map.get(&src).cloned()
242 }
243
220 pub fn pat_syntax(&self, pat: PatId) -> Option<PatSource> { 244 pub fn pat_syntax(&self, pat: PatId) -> Option<PatSource> {
221 self.pat_map_back.get(pat).copied() 245 self.pat_map_back.get(pat).copied()
222 } 246 }
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 61193b4d8..be5d17d85 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -2,11 +2,12 @@
2//! representation. 2//! representation.
3 3
4use either::Either; 4use either::Either;
5
5use hir_expand::name::{name, AsName, Name}; 6use hir_expand::name::{name, AsName, Name};
6use ra_arena::Arena; 7use ra_arena::Arena;
7use ra_syntax::{ 8use ra_syntax::{
8 ast::{ 9 ast::{
9 self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner, 10 self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, ModuleItemOwner, NameOwner,
10 TypeAscriptionOwner, 11 TypeAscriptionOwner,
11 }, 12 },
12 AstNode, AstPtr, 13 AstNode, AstPtr,
@@ -24,23 +25,28 @@ use crate::{
24 path::GenericArgs, 25 path::GenericArgs,
25 path::Path, 26 path::Path,
26 type_ref::{Mutability, TypeRef}, 27 type_ref::{Mutability, TypeRef},
28 ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, StaticLoc,
29 StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
27}; 30};
28 31
29pub(super) fn lower( 32pub(super) fn lower(
30 db: &impl DefDatabase, 33 db: &impl DefDatabase,
34 def: DefWithBodyId,
31 expander: Expander, 35 expander: Expander,
32 params: Option<ast::ParamList>, 36 params: Option<ast::ParamList>,
33 body: Option<ast::Expr>, 37 body: Option<ast::Expr>,
34) -> (Body, BodySourceMap) { 38) -> (Body, BodySourceMap) {
35 ExprCollector { 39 ExprCollector {
36 expander,
37 db, 40 db,
41 def,
42 expander,
38 source_map: BodySourceMap::default(), 43 source_map: BodySourceMap::default(),
39 body: Body { 44 body: Body {
40 exprs: Arena::default(), 45 exprs: Arena::default(),
41 pats: Arena::default(), 46 pats: Arena::default(),
42 params: Vec::new(), 47 params: Vec::new(),
43 body_expr: ExprId::dummy(), 48 body_expr: ExprId::dummy(),
49 defs: Vec::new(),
44 }, 50 },
45 } 51 }
46 .collect(params, body) 52 .collect(params, body)
@@ -48,6 +54,7 @@ pub(super) fn lower(
48 54
49struct ExprCollector<DB> { 55struct ExprCollector<DB> {
50 db: DB, 56 db: DB,
57 def: DefWithBodyId,
51 expander: Expander, 58 expander: Expander,
52 59
53 body: Body, 60 body: Body,
@@ -365,8 +372,9 @@ where
365 arg_types.push(type_ref); 372 arg_types.push(type_ref);
366 } 373 }
367 } 374 }
375 let ret_type = e.ret_type().and_then(|r| r.type_ref()).map(TypeRef::from_ast);
368 let body = self.collect_expr_opt(e.body()); 376 let body = self.collect_expr_opt(e.body());
369 self.alloc_expr(Expr::Lambda { args, arg_types, body }, syntax_ptr) 377 self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr)
370 } 378 }
371 ast::Expr::BinExpr(e) => { 379 ast::Expr::BinExpr(e) => {
372 let lhs = self.collect_expr_opt(e.lhs()); 380 let lhs = self.collect_expr_opt(e.lhs());
@@ -466,6 +474,7 @@ where
466 Some(block) => block, 474 Some(block) => block,
467 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr), 475 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr),
468 }; 476 };
477 self.collect_block_items(&block);
469 let statements = block 478 let statements = block
470 .statements() 479 .statements()
471 .map(|s| match s { 480 .map(|s| match s {
@@ -482,6 +491,51 @@ where
482 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) 491 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr)
483 } 492 }
484 493
494 fn collect_block_items(&mut self, block: &ast::Block) {
495 let container = ContainerId::DefWithBodyId(self.def);
496 for item in block.items() {
497 let def: ModuleDefId = match item {
498 ast::ModuleItem::FnDef(def) => {
499 let ast_id = self.expander.ast_id(&def);
500 FunctionLoc { container: container.into(), ast_id }.intern(self.db).into()
501 }
502 ast::ModuleItem::TypeAliasDef(def) => {
503 let ast_id = self.expander.ast_id(&def);
504 TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into()
505 }
506 ast::ModuleItem::ConstDef(def) => {
507 let ast_id = self.expander.ast_id(&def);
508 ConstLoc { container: container.into(), ast_id }.intern(self.db).into()
509 }
510 ast::ModuleItem::StaticDef(def) => {
511 let ast_id = self.expander.ast_id(&def);
512 StaticLoc { container, ast_id }.intern(self.db).into()
513 }
514 ast::ModuleItem::StructDef(def) => {
515 let ast_id = self.expander.ast_id(&def);
516 StructLoc { container, ast_id }.intern(self.db).into()
517 }
518 ast::ModuleItem::EnumDef(def) => {
519 let ast_id = self.expander.ast_id(&def);
520 EnumLoc { container, ast_id }.intern(self.db).into()
521 }
522 ast::ModuleItem::UnionDef(def) => {
523 let ast_id = self.expander.ast_id(&def);
524 UnionLoc { container, ast_id }.intern(self.db).into()
525 }
526 ast::ModuleItem::TraitDef(def) => {
527 let ast_id = self.expander.ast_id(&def);
528 TraitLoc { container, ast_id }.intern(self.db).into()
529 }
530 ast::ModuleItem::ImplBlock(_)
531 | ast::ModuleItem::UseItem(_)
532 | ast::ModuleItem::ExternCrateItem(_)
533 | ast::ModuleItem::Module(_) => continue,
534 };
535 self.body.defs.push(def)
536 }
537 }
538
485 fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId { 539 fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId {
486 if let Some(block) = expr { 540 if let Some(block) = expr {
487 self.collect_block(block) 541 self.collect_block(block)
diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs
index 3c9379b15..4488e8502 100644
--- a/crates/ra_hir_def/src/child_by_source.rs
+++ b/crates/ra_hir_def/src/child_by_source.rs
@@ -11,8 +11,8 @@ use crate::{
11 dyn_map::DynMap, 11 dyn_map::DynMap,
12 keys, 12 keys,
13 src::{HasChildSource, HasSource}, 13 src::{HasChildSource, HasSource},
14 AdtId, AssocItemId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, ModuleId, 14 AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId,
15 StructFieldId, TraitId, VariantId, 15 ModuleId, StructFieldId, TraitId, VariantId,
16}; 16};
17 17
18pub trait ChildBySource { 18pub trait ChildBySource {
@@ -76,55 +76,59 @@ impl ChildBySource for ModuleId {
76 let mut res = DynMap::default(); 76 let mut res = DynMap::default();
77 77
78 let crate_def_map = db.crate_def_map(self.krate); 78 let crate_def_map = db.crate_def_map(self.krate);
79 for item in crate_def_map[self.local_id].scope.declarations() { 79 let module_data = &crate_def_map[self.local_id];
80 match item {
81 ModuleDefId::FunctionId(func) => {
82 let src = func.lookup(db).source(db);
83 res[keys::FUNCTION].insert(src, func)
84 }
85 ModuleDefId::ConstId(konst) => {
86 let src = konst.lookup(db).source(db);
87 res[keys::CONST].insert(src, konst)
88 }
89 ModuleDefId::StaticId(statik) => {
90 let src = statik.lookup(db).source(db);
91 res[keys::STATIC].insert(src, statik)
92 }
93 ModuleDefId::TypeAliasId(ty) => {
94 let src = ty.lookup(db).source(db);
95 res[keys::TYPE_ALIAS].insert(src, ty)
96 }
97 ModuleDefId::TraitId(trait_) => {
98 let src = trait_.lookup(db).source(db);
99 res[keys::TRAIT].insert(src, trait_)
100 }
101 ModuleDefId::AdtId(adt) => match adt {
102 AdtId::StructId(strukt) => {
103 let src = strukt.lookup(db).source(db);
104 res[keys::STRUCT].insert(src, strukt)
105 }
106 AdtId::UnionId(union_) => {
107 let src = union_.lookup(db).source(db);
108 res[keys::UNION].insert(src, union_)
109 }
110 AdtId::EnumId(enum_) => {
111 let src = enum_.lookup(db).source(db);
112 res[keys::ENUM].insert(src, enum_)
113 }
114 },
115 _ => (),
116 }
117 }
118 80
119 for &impl_ in crate_def_map[self.local_id].impls.iter() { 81 module_data.scope.declarations().for_each(|item| add_module_def(db, &mut res, item));
120 let src = impl_.lookup(db).source(db); 82
121 res[keys::IMPL].insert(src, impl_) 83 for imp in module_data.scope.impls() {
84 let src = imp.lookup(db).source(db);
85 res[keys::IMPL].insert(src, imp)
122 } 86 }
123 87
124 res 88 res
125 } 89 }
126} 90}
127 91
92fn add_module_def(db: &impl DefDatabase, map: &mut DynMap, item: ModuleDefId) {
93 match item {
94 ModuleDefId::FunctionId(func) => {
95 let src = func.lookup(db).source(db);
96 map[keys::FUNCTION].insert(src, func)
97 }
98 ModuleDefId::ConstId(konst) => {
99 let src = konst.lookup(db).source(db);
100 map[keys::CONST].insert(src, konst)
101 }
102 ModuleDefId::StaticId(statik) => {
103 let src = statik.lookup(db).source(db);
104 map[keys::STATIC].insert(src, statik)
105 }
106 ModuleDefId::TypeAliasId(ty) => {
107 let src = ty.lookup(db).source(db);
108 map[keys::TYPE_ALIAS].insert(src, ty)
109 }
110 ModuleDefId::TraitId(trait_) => {
111 let src = trait_.lookup(db).source(db);
112 map[keys::TRAIT].insert(src, trait_)
113 }
114 ModuleDefId::AdtId(adt) => match adt {
115 AdtId::StructId(strukt) => {
116 let src = strukt.lookup(db).source(db);
117 map[keys::STRUCT].insert(src, strukt)
118 }
119 AdtId::UnionId(union_) => {
120 let src = union_.lookup(db).source(db);
121 map[keys::UNION].insert(src, union_)
122 }
123 AdtId::EnumId(enum_) => {
124 let src = enum_.lookup(db).source(db);
125 map[keys::ENUM].insert(src, enum_)
126 }
127 },
128 _ => (),
129 }
130}
131
128impl ChildBySource for VariantId { 132impl ChildBySource for VariantId {
129 fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { 133 fn child_by_source(&self, db: &impl DefDatabase) -> DynMap {
130 let mut res = DynMap::default(); 134 let mut res = DynMap::default();
@@ -160,3 +164,12 @@ impl ChildBySource for EnumId {
160 res 164 res
161 } 165 }
162} 166}
167
168impl ChildBySource for DefWithBodyId {
169 fn child_by_source(&self, db: &impl DefDatabase) -> DynMap {
170 let mut res = DynMap::default();
171 let body = db.body(*self);
172 body.defs.iter().copied().for_each(|item| add_module_def(db, &mut res, item));
173 res
174 }
175}
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
index 4f4ef57cc..1aa9a9b7d 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -4,16 +4,16 @@ use std::sync::Arc;
4 4
5use hir_expand::{ 5use hir_expand::{
6 name::{name, AsName, Name}, 6 name::{name, AsName, Name},
7 AstId, 7 AstId, InFile,
8}; 8};
9use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; 9use ra_syntax::ast::{self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAscriptionOwner};
10 10
11use crate::{ 11use crate::{
12 db::DefDatabase, 12 db::DefDatabase,
13 src::HasSource, 13 src::HasSource,
14 type_ref::{Mutability, TypeRef}, 14 type_ref::{Mutability, TypeRef},
15 AssocItemId, ConstId, ConstLoc, ContainerId, FunctionId, FunctionLoc, ImplId, Intern, Lookup, 15 AssocContainerId, AssocItemId, ConstId, ConstLoc, Expander, FunctionId, FunctionLoc, HasModule,
16 StaticId, TraitId, TypeAliasId, TypeAliasLoc, 16 ImplId, Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
17}; 17};
18 18
19#[derive(Debug, Clone, PartialEq, Eq)] 19#[derive(Debug, Clone, PartialEq, Eq)]
@@ -99,7 +99,7 @@ impl TraitData {
99 let auto = src.value.is_auto(); 99 let auto = src.value.is_auto();
100 let ast_id_map = db.ast_id_map(src.file_id); 100 let ast_id_map = db.ast_id_map(src.file_id);
101 101
102 let container = ContainerId::TraitId(tr); 102 let container = AssocContainerId::TraitId(tr);
103 let items = if let Some(item_list) = src.value.item_list() { 103 let items = if let Some(item_list) = src.value.item_list() {
104 item_list 104 item_list
105 .impl_items() 105 .impl_items()
@@ -167,46 +167,24 @@ pub struct ImplData {
167 167
168impl ImplData { 168impl ImplData {
169 pub(crate) fn impl_data_query(db: &impl DefDatabase, id: ImplId) -> Arc<ImplData> { 169 pub(crate) fn impl_data_query(db: &impl DefDatabase, id: ImplId) -> Arc<ImplData> {
170 let src = id.lookup(db).source(db); 170 let impl_loc = id.lookup(db);
171 let items = db.ast_id_map(src.file_id); 171 let src = impl_loc.source(db);
172 172
173 let target_trait = src.value.target_trait().map(TypeRef::from_ast); 173 let target_trait = src.value.target_trait().map(TypeRef::from_ast);
174 let target_type = TypeRef::from_ast_opt(src.value.target_type()); 174 let target_type = TypeRef::from_ast_opt(src.value.target_type());
175 let is_negative = src.value.is_negative(); 175 let is_negative = src.value.is_negative();
176 let module_id = impl_loc.container.module(db);
176 177
177 let items = if let Some(item_list) = src.value.item_list() { 178 let mut items = Vec::new();
178 item_list 179 if let Some(item_list) = src.value.item_list() {
179 .impl_items() 180 items.extend(collect_impl_items(db, item_list.impl_items(), src.file_id, id));
180 .map(|item_node| match item_node { 181 items.extend(collect_impl_items_in_macros(
181 ast::ImplItem::FnDef(it) => { 182 db,
182 let def = FunctionLoc { 183 module_id,
183 container: ContainerId::ImplId(id), 184 &src.with_value(item_list),
184 ast_id: AstId::new(src.file_id, items.ast_id(&it)), 185 id,
185 } 186 ));
186 .intern(db); 187 }
187 def.into()
188 }
189 ast::ImplItem::ConstDef(it) => {
190 let def = ConstLoc {
191 container: ContainerId::ImplId(id),
192 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
193 }
194 .intern(db);
195 def.into()
196 }
197 ast::ImplItem::TypeAliasDef(it) => {
198 let def = TypeAliasLoc {
199 container: ContainerId::ImplId(id),
200 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
201 }
202 .intern(db);
203 def.into()
204 }
205 })
206 .collect()
207 } else {
208 Vec::new()
209 };
210 188
211 let res = ImplData { target_trait, target_type, items, is_negative }; 189 let res = ImplData { target_trait, target_type, items, is_negative };
212 Arc::new(res) 190 Arc::new(res)
@@ -237,3 +215,92 @@ impl ConstData {
237 ConstData { name, type_ref } 215 ConstData { name, type_ref }
238 } 216 }
239} 217}
218
219fn collect_impl_items_in_macros(
220 db: &impl DefDatabase,
221 module_id: ModuleId,
222 impl_block: &InFile<ast::ItemList>,
223 id: ImplId,
224) -> Vec<AssocItemId> {
225 let mut expander = Expander::new(db, impl_block.file_id, module_id);
226 let mut res = Vec::new();
227
228 // We set a limit to protect against infinite recursion
229 let limit = 100;
230
231 for m in impl_block.value.syntax().children().filter_map(ast::MacroCall::cast) {
232 res.extend(collect_impl_items_in_macro(db, &mut expander, m, id, limit))
233 }
234
235 res
236}
237
238fn collect_impl_items_in_macro(
239 db: &impl DefDatabase,
240 expander: &mut Expander,
241 m: ast::MacroCall,
242 id: ImplId,
243 limit: usize,
244) -> Vec<AssocItemId> {
245 if limit == 0 {
246 return Vec::new();
247 }
248
249 if let Some((mark, items)) = expander.enter_expand(db, m) {
250 let items: InFile<ast::MacroItems> = expander.to_source(items);
251 let mut res = collect_impl_items(
252 db,
253 items.value.items().filter_map(|it| ImplItem::cast(it.syntax().clone())),
254 items.file_id,
255 id,
256 );
257 // Recursive collect macros
258 // Note that ast::ModuleItem do not include ast::MacroCall
259 // We cannot use ModuleItemOwner::items here
260 for it in items.value.syntax().children().filter_map(ast::MacroCall::cast) {
261 res.extend(collect_impl_items_in_macro(db, expander, it, id, limit - 1))
262 }
263 expander.exit(db, mark);
264 res
265 } else {
266 Vec::new()
267 }
268}
269
270fn collect_impl_items(
271 db: &impl DefDatabase,
272 impl_items: impl Iterator<Item = ImplItem>,
273 file_id: crate::HirFileId,
274 id: ImplId,
275) -> Vec<AssocItemId> {
276 let items = db.ast_id_map(file_id);
277
278 impl_items
279 .map(|item_node| match item_node {
280 ast::ImplItem::FnDef(it) => {
281 let def = FunctionLoc {
282 container: AssocContainerId::ImplId(id),
283 ast_id: AstId::new(file_id, items.ast_id(&it)),
284 }
285 .intern(db);
286 def.into()
287 }
288 ast::ImplItem::ConstDef(it) => {
289 let def = ConstLoc {
290 container: AssocContainerId::ImplId(id),
291 ast_id: AstId::new(file_id, items.ast_id(&it)),
292 }
293 .intern(db);
294 def.into()
295 }
296 ast::ImplItem::TypeAliasDef(it) => {
297 let def = TypeAliasLoc {
298 container: AssocContainerId::ImplId(id),
299 ast_id: AstId::new(file_id, items.ast_id(&it)),
300 }
301 .intern(db);
302 def.into()
303 }
304 })
305 .collect()
306}
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index 98bff6cb7..c55fd4111 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -13,10 +13,7 @@ use crate::{
13 docs::Documentation, 13 docs::Documentation,
14 generics::GenericParams, 14 generics::GenericParams,
15 lang_item::{LangItemTarget, LangItems}, 15 lang_item::{LangItemTarget, LangItems},
16 nameres::{ 16 nameres::{raw::RawItems, CrateDefMap},
17 raw::{ImportSourceMap, RawItems},
18 CrateDefMap,
19 },
20 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, 17 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc,
21 GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, 18 GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId,
22 TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, 19 TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc,
@@ -46,12 +43,6 @@ pub trait InternDatabase: SourceDatabase {
46 43
47#[salsa::query_group(DefDatabaseStorage)] 44#[salsa::query_group(DefDatabaseStorage)]
48pub trait DefDatabase: InternDatabase + AstDatabase { 45pub trait DefDatabase: InternDatabase + AstDatabase {
49 #[salsa::invoke(RawItems::raw_items_with_source_map_query)]
50 fn raw_items_with_source_map(
51 &self,
52 file_id: HirFileId,
53 ) -> (Arc<RawItems>, Arc<ImportSourceMap>);
54
55 #[salsa::invoke(RawItems::raw_items_query)] 46 #[salsa::invoke(RawItems::raw_items_query)]
56 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; 47 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>;
57 48
diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs
index 6fad80a8d..a75ef9970 100644
--- a/crates/ra_hir_def/src/expr.rs
+++ b/crates/ra_hir_def/src/expr.rs
@@ -143,6 +143,7 @@ pub enum Expr {
143 Lambda { 143 Lambda {
144 args: Vec<PatId>, 144 args: Vec<PatId>,
145 arg_types: Vec<Option<TypeRef>>, 145 arg_types: Vec<Option<TypeRef>>,
146 ret_type: Option<TypeRef>,
146 body: ExprId, 147 body: ExprId,
147 }, 148 },
148 Tuple { 149 Tuple {
diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs
new file mode 100644
index 000000000..9e082c5f7
--- /dev/null
+++ b/crates/ra_hir_def/src/item_scope.rs
@@ -0,0 +1,155 @@
1//! Describes items defined or visible (ie, imported) in a certain scope.
2//! This is shared between modules and blocks.
3
4use hir_expand::name::Name;
5use once_cell::sync::Lazy;
6use rustc_hash::FxHashMap;
7
8use crate::{per_ns::PerNs, BuiltinType, ImplId, MacroDefId, ModuleDefId, TraitId};
9
10#[derive(Debug, Default, PartialEq, Eq)]
11pub struct ItemScope {
12 items: FxHashMap<Name, Resolution>,
13 impls: Vec<ImplId>,
14 /// Macros visible in current module in legacy textual scope
15 ///
16 /// For macros invoked by an unqualified identifier like `bar!()`, `legacy_macros` will be searched in first.
17 /// If it yields no result, then it turns to module scoped `macros`.
18 /// It macros with name qualified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped,
19 /// and only normal scoped `macros` will be searched in.
20 ///
21 /// Note that this automatically inherit macros defined textually before the definition of module itself.
22 ///
23 /// Module scoped macros will be inserted into `items` instead of here.
24 // FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will
25 // be all resolved to the last one defined if shadowing happens.
26 legacy_macros: FxHashMap<Name, MacroDefId>,
27}
28
29static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
30 BuiltinType::ALL
31 .iter()
32 .map(|(name, ty)| {
33 (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: false })
34 })
35 .collect()
36});
37
38/// Shadow mode for builtin type which can be shadowed by module.
39#[derive(Debug, Copy, Clone, PartialEq, Eq)]
40pub(crate) enum BuiltinShadowMode {
41 // Prefer Module
42 Module,
43 // Prefer Other Types
44 Other,
45}
46
47/// Legacy macros can only be accessed through special methods like `get_legacy_macros`.
48/// Other methods will only resolve values, types and module scoped macros only.
49impl ItemScope {
50 pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, &'a Resolution)> + 'a {
51 //FIXME: shadowing
52 self.items.iter().chain(BUILTIN_SCOPE.iter())
53 }
54
55 pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
56 self.entries()
57 .filter_map(|(_name, res)| if !res.import { Some(res.def) } else { None })
58 .flat_map(|per_ns| {
59 per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
60 })
61 }
62
63 pub fn impls(&self) -> impl Iterator<Item = ImplId> + ExactSizeIterator + '_ {
64 self.impls.iter().copied()
65 }
66
67 /// Iterate over all module scoped macros
68 pub(crate) fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
69 self.items
70 .iter()
71 .filter_map(|(name, res)| res.def.take_macros().map(|macro_| (name, macro_)))
72 }
73
74 /// Iterate over all legacy textual scoped macros visible at the end of the module
75 pub(crate) fn legacy_macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
76 self.legacy_macros.iter().map(|(name, def)| (name, *def))
77 }
78
79 /// Get a name from current module scope, legacy macros are not included
80 pub(crate) fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> {
81 match shadow {
82 BuiltinShadowMode::Module => self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)),
83 BuiltinShadowMode::Other => {
84 let item = self.items.get(name);
85 if let Some(res) = item {
86 if let Some(ModuleDefId::ModuleId(_)) = res.def.take_types() {
87 return BUILTIN_SCOPE.get(name).or(item);
88 }
89 }
90
91 item.or_else(|| BUILTIN_SCOPE.get(name))
92 }
93 }
94 }
95
96 pub(crate) fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a {
97 self.items.values().filter_map(|r| match r.def.take_types() {
98 Some(ModuleDefId::TraitId(t)) => Some(t),
99 _ => None,
100 })
101 }
102
103 pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option<MacroDefId> {
104 self.legacy_macros.get(name).copied()
105 }
106
107 pub(crate) fn define_impl(&mut self, imp: ImplId) {
108 self.impls.push(imp)
109 }
110
111 pub(crate) fn define_legacy_macro(&mut self, name: Name, mac: MacroDefId) {
112 self.legacy_macros.insert(name, mac);
113 }
114
115 pub(crate) fn push_res(&mut self, name: Name, res: &Resolution, import: bool) -> bool {
116 let mut changed = false;
117 let existing = self.items.entry(name.clone()).or_default();
118
119 if existing.def.types.is_none() && res.def.types.is_some() {
120 existing.def.types = res.def.types;
121 existing.import = import || res.import;
122 changed = true;
123 }
124 if existing.def.values.is_none() && res.def.values.is_some() {
125 existing.def.values = res.def.values;
126 existing.import = import || res.import;
127 changed = true;
128 }
129 if existing.def.macros.is_none() && res.def.macros.is_some() {
130 existing.def.macros = res.def.macros;
131 existing.import = import || res.import;
132 changed = true;
133 }
134
135 if existing.def.is_none() && res.def.is_none() && !existing.import && res.import {
136 existing.import = res.import;
137 }
138 changed
139 }
140
141 pub(crate) fn collect_resolutions(&self) -> Vec<(Name, Resolution)> {
142 self.items.iter().map(|(name, res)| (name.clone(), res.clone())).collect()
143 }
144
145 pub(crate) fn collect_legacy_macros(&self) -> FxHashMap<Name, MacroDefId> {
146 self.legacy_macros.clone()
147 }
148}
149
150#[derive(Debug, Clone, PartialEq, Eq, Default)]
151pub struct Resolution {
152 /// None for unresolved
153 pub def: PerNs,
154 pub(crate) import: bool,
155}
diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs
index f4fdbdcfc..cef061837 100644
--- a/crates/ra_hir_def/src/lang_item.rs
+++ b/crates/ra_hir_def/src/lang_item.rs
@@ -81,7 +81,7 @@ impl LangItems {
81 // Look for impl targets 81 // Look for impl targets
82 let def_map = db.crate_def_map(module.krate); 82 let def_map = db.crate_def_map(module.krate);
83 let module_data = &def_map[module.local_id]; 83 let module_data = &def_map[module.local_id];
84 for &impl_block in module_data.impls.iter() { 84 for impl_block in module_data.scope.impls() {
85 self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlockId) 85 self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlockId)
86 } 86 }
87 87
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index f085bbe87..f6c7f38d1 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -15,6 +15,7 @@ pub mod type_ref;
15pub mod builtin_type; 15pub mod builtin_type;
16pub mod diagnostics; 16pub mod diagnostics;
17pub mod per_ns; 17pub mod per_ns;
18pub mod item_scope;
18 19
19pub mod dyn_map; 20pub mod dyn_map;
20pub mod keys; 21pub mod keys;
@@ -45,15 +46,12 @@ use std::hash::Hash;
45use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId}; 46use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId};
46use ra_arena::{impl_arena_id, RawId}; 47use ra_arena::{impl_arena_id, RawId};
47use ra_db::{impl_intern_key, salsa, CrateId}; 48use ra_db::{impl_intern_key, salsa, CrateId};
48use ra_syntax::ast; 49use ra_syntax::{ast, AstNode};
49 50
51use crate::body::Expander;
50use crate::builtin_type::BuiltinType; 52use crate::builtin_type::BuiltinType;
51 53
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
53pub struct LocalImportId(RawId);
54impl_arena_id!(LocalImportId);
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
57pub struct ModuleId { 55pub struct ModuleId {
58 pub krate: CrateId, 56 pub krate: CrateId,
59 pub local_id: LocalModuleId, 57 pub local_id: LocalModuleId,
@@ -65,101 +63,57 @@ pub struct ModuleId {
65pub struct LocalModuleId(RawId); 63pub struct LocalModuleId(RawId);
66impl_arena_id!(LocalModuleId); 64impl_arena_id!(LocalModuleId);
67 65
68#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
69pub struct FunctionId(salsa::InternId);
70impl_intern_key!(FunctionId);
71
72#[derive(Debug, Clone, PartialEq, Eq, Hash)] 66#[derive(Debug, Clone, PartialEq, Eq, Hash)]
73pub struct FunctionLoc { 67pub struct ItemLoc<N: AstNode> {
74 pub container: ContainerId, 68 pub container: ContainerId,
75 pub ast_id: AstId<ast::FnDef>, 69 pub ast_id: AstId<N>,
76} 70}
77 71
78impl Intern for FunctionLoc { 72#[derive(Debug, Clone, PartialEq, Eq, Hash)]
79 type ID = FunctionId; 73pub struct AssocItemLoc<N: AstNode> {
80 fn intern(self, db: &impl db::DefDatabase) -> FunctionId { 74 pub container: AssocContainerId,
81 db.intern_function(self) 75 pub ast_id: AstId<N>,
82 }
83} 76}
84 77
85impl Lookup for FunctionId { 78macro_rules! impl_intern {
86 type Data = FunctionLoc; 79 ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
87 fn lookup(&self, db: &impl db::DefDatabase) -> FunctionLoc { 80 impl_intern_key!($id);
88 db.lookup_intern_function(*self)
89 }
90}
91 81
92#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 82 impl Intern for $loc {
93pub struct StructId(salsa::InternId); 83 type ID = $id;
94impl_intern_key!(StructId); 84 fn intern(self, db: &impl db::DefDatabase) -> $id {
85 db.$intern(self)
86 }
87 }
95 88
96#[derive(Debug, Clone, PartialEq, Eq, Hash)] 89 impl Lookup for $id {
97pub struct StructLoc { 90 type Data = $loc;
98 pub container: ModuleId, 91 fn lookup(&self, db: &impl db::DefDatabase) -> $loc {
99 pub ast_id: AstId<ast::StructDef>, 92 db.$lookup(*self)
93 }
94 }
95 };
100} 96}
101 97
102impl Intern for StructLoc { 98#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
103 type ID = StructId; 99pub struct FunctionId(salsa::InternId);
104 fn intern(self, db: &impl db::DefDatabase) -> StructId { 100type FunctionLoc = AssocItemLoc<ast::FnDef>;
105 db.intern_struct(self) 101impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
106 }
107}
108 102
109impl Lookup for StructId { 103#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
110 type Data = StructLoc; 104pub struct StructId(salsa::InternId);
111 fn lookup(&self, db: &impl db::DefDatabase) -> StructLoc { 105type StructLoc = ItemLoc<ast::StructDef>;
112 db.lookup_intern_struct(*self) 106impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
113 }
114}
115 107
116#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 108#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
117pub struct UnionId(salsa::InternId); 109pub struct UnionId(salsa::InternId);
118impl_intern_key!(UnionId); 110pub type UnionLoc = ItemLoc<ast::UnionDef>;
119 111impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union);
120#[derive(Debug, Clone, PartialEq, Eq, Hash)]
121pub struct UnionLoc {
122 pub container: ModuleId,
123 pub ast_id: AstId<ast::UnionDef>,
124}
125
126impl Intern for UnionLoc {
127 type ID = UnionId;
128 fn intern(self, db: &impl db::DefDatabase) -> UnionId {
129 db.intern_union(self)
130 }
131}
132
133impl Lookup for UnionId {
134 type Data = UnionLoc;
135 fn lookup(&self, db: &impl db::DefDatabase) -> UnionLoc {
136 db.lookup_intern_union(*self)
137 }
138}
139 112
140#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 113#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
141pub struct EnumId(salsa::InternId); 114pub struct EnumId(salsa::InternId);
142impl_intern_key!(EnumId); 115pub type EnumLoc = ItemLoc<ast::EnumDef>;
143 116impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum);
144#[derive(Debug, Clone, PartialEq, Eq, Hash)]
145pub struct EnumLoc {
146 pub container: ModuleId,
147 pub ast_id: AstId<ast::EnumDef>,
148}
149
150impl Intern for EnumLoc {
151 type ID = EnumId;
152 fn intern(self, db: &impl db::DefDatabase) -> EnumId {
153 db.intern_enum(self)
154 }
155}
156
157impl Lookup for EnumId {
158 type Data = EnumLoc;
159 fn lookup(&self, db: &impl db::DefDatabase) -> EnumLoc {
160 db.lookup_intern_enum(*self)
161 }
162}
163 117
164// FIXME: rename to `VariantId`, only enums can ave variants 118// FIXME: rename to `VariantId`, only enums can ave variants
165#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 119#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -184,122 +138,38 @@ impl_arena_id!(LocalStructFieldId);
184 138
185#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 139#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
186pub struct ConstId(salsa::InternId); 140pub struct ConstId(salsa::InternId);
187impl_intern_key!(ConstId); 141type ConstLoc = AssocItemLoc<ast::ConstDef>;
188#[derive(Debug, Clone, PartialEq, Eq, Hash)] 142impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const);
189pub struct ConstLoc {
190 pub container: ContainerId,
191 pub ast_id: AstId<ast::ConstDef>,
192}
193
194impl Intern for ConstLoc {
195 type ID = ConstId;
196 fn intern(self, db: &impl db::DefDatabase) -> ConstId {
197 db.intern_const(self)
198 }
199}
200
201impl Lookup for ConstId {
202 type Data = ConstLoc;
203 fn lookup(&self, db: &impl db::DefDatabase) -> ConstLoc {
204 db.lookup_intern_const(*self)
205 }
206}
207 143
208#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 144#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
209pub struct StaticId(salsa::InternId); 145pub struct StaticId(salsa::InternId);
210impl_intern_key!(StaticId); 146pub type StaticLoc = ItemLoc<ast::StaticDef>;
211 147impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
212#[derive(Debug, Clone, PartialEq, Eq, Hash)]
213pub struct StaticLoc {
214 pub container: ModuleId,
215 pub ast_id: AstId<ast::StaticDef>,
216}
217
218impl Intern for StaticLoc {
219 type ID = StaticId;
220 fn intern(self, db: &impl db::DefDatabase) -> StaticId {
221 db.intern_static(self)
222 }
223}
224
225impl Lookup for StaticId {
226 type Data = StaticLoc;
227 fn lookup(&self, db: &impl db::DefDatabase) -> StaticLoc {
228 db.lookup_intern_static(*self)
229 }
230}
231 148
232#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 149#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
233pub struct TraitId(salsa::InternId); 150pub struct TraitId(salsa::InternId);
234impl_intern_key!(TraitId); 151pub type TraitLoc = ItemLoc<ast::TraitDef>;
235 152impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait);
236#[derive(Debug, Clone, PartialEq, Eq, Hash)]
237pub struct TraitLoc {
238 pub container: ModuleId,
239 pub ast_id: AstId<ast::TraitDef>,
240}
241
242impl Intern for TraitLoc {
243 type ID = TraitId;
244 fn intern(self, db: &impl db::DefDatabase) -> TraitId {
245 db.intern_trait(self)
246 }
247}
248
249impl Lookup for TraitId {
250 type Data = TraitLoc;
251 fn lookup(&self, db: &impl db::DefDatabase) -> TraitLoc {
252 db.lookup_intern_trait(*self)
253 }
254}
255 153
256#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 154#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
257pub struct TypeAliasId(salsa::InternId); 155pub struct TypeAliasId(salsa::InternId);
258impl_intern_key!(TypeAliasId); 156type TypeAliasLoc = AssocItemLoc<ast::TypeAliasDef>;
259 157impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias);
260#[derive(Debug, Clone, PartialEq, Eq, Hash)]
261pub struct TypeAliasLoc {
262 pub container: ContainerId,
263 pub ast_id: AstId<ast::TypeAliasDef>,
264}
265
266impl Intern for TypeAliasLoc {
267 type ID = TypeAliasId;
268 fn intern(self, db: &impl db::DefDatabase) -> TypeAliasId {
269 db.intern_type_alias(self)
270 }
271}
272
273impl Lookup for TypeAliasId {
274 type Data = TypeAliasLoc;
275 fn lookup(&self, db: &impl db::DefDatabase) -> TypeAliasLoc {
276 db.lookup_intern_type_alias(*self)
277 }
278}
279 158
280#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 159#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
281pub struct ImplId(salsa::InternId); 160pub struct ImplId(salsa::InternId);
282impl_intern_key!(ImplId); 161type ImplLoc = ItemLoc<ast::ImplBlock>;
162impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
283 163
284#[derive(Debug, Clone, PartialEq, Eq, Hash)] 164#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
285pub struct ImplLoc { 165pub struct TypeParamId {
286 pub container: ModuleId, 166 pub parent: GenericDefId,
287 pub ast_id: AstId<ast::ImplBlock>, 167 pub local_id: LocalTypeParamId,
288}
289
290impl Intern for ImplLoc {
291 type ID = ImplId;
292 fn intern(self, db: &impl db::DefDatabase) -> ImplId {
293 db.intern_impl(self)
294 }
295} 168}
296 169
297impl Lookup for ImplId { 170#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
298 type Data = ImplLoc; 171pub struct LocalTypeParamId(RawId);
299 fn lookup(&self, db: &impl db::DefDatabase) -> ImplLoc { 172impl_arena_id!(LocalTypeParamId);
300 db.lookup_intern_impl(*self)
301 }
302}
303 173
304macro_rules! impl_froms { 174macro_rules! impl_froms {
305 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => { 175 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
@@ -321,21 +191,18 @@ macro_rules! impl_froms {
321} 191}
322 192
323#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 193#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
324pub struct TypeParamId { 194pub enum ContainerId {
325 pub parent: GenericDefId, 195 ModuleId(ModuleId),
326 pub local_id: LocalTypeParamId, 196 DefWithBodyId(DefWithBodyId),
327} 197}
328 198
329#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 199#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
330pub struct LocalTypeParamId(RawId); 200pub enum AssocContainerId {
331impl_arena_id!(LocalTypeParamId); 201 ContainerId(ContainerId),
332
333#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
334pub enum ContainerId {
335 ModuleId(ModuleId),
336 ImplId(ImplId), 202 ImplId(ImplId),
337 TraitId(TraitId), 203 TraitId(TraitId),
338} 204}
205impl_froms!(AssocContainerId: ContainerId);
339 206
340/// A Data Type 207/// A Data Type
341#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 208#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -478,33 +345,28 @@ pub trait HasModule {
478 fn module(&self, db: &impl db::DefDatabase) -> ModuleId; 345 fn module(&self, db: &impl db::DefDatabase) -> ModuleId;
479} 346}
480 347
481impl HasModule for FunctionLoc { 348impl HasModule for ContainerId {
482 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 349 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
483 match self.container { 350 match *self {
484 ContainerId::ModuleId(it) => it, 351 ContainerId::ModuleId(it) => it,
485 ContainerId::ImplId(it) => it.lookup(db).container, 352 ContainerId::DefWithBodyId(it) => it.module(db),
486 ContainerId::TraitId(it) => it.lookup(db).container,
487 } 353 }
488 } 354 }
489} 355}
490 356
491impl HasModule for TypeAliasLoc { 357impl HasModule for AssocContainerId {
492 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 358 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
493 match self.container { 359 match *self {
494 ContainerId::ModuleId(it) => it, 360 AssocContainerId::ContainerId(it) => it.module(db),
495 ContainerId::ImplId(it) => it.lookup(db).container, 361 AssocContainerId::ImplId(it) => it.lookup(db).container.module(db),
496 ContainerId::TraitId(it) => it.lookup(db).container, 362 AssocContainerId::TraitId(it) => it.lookup(db).container.module(db),
497 } 363 }
498 } 364 }
499} 365}
500 366
501impl HasModule for ConstLoc { 367impl<N: AstNode> HasModule for AssocItemLoc<N> {
502 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 368 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
503 match self.container { 369 self.container.module(db)
504 ContainerId::ModuleId(it) => it,
505 ContainerId::ImplId(it) => it.lookup(db).container,
506 ContainerId::TraitId(it) => it.lookup(db).container,
507 }
508 } 370 }
509} 371}
510 372
@@ -515,6 +377,7 @@ impl HasModule for AdtId {
515 AdtId::UnionId(it) => it.lookup(db).container, 377 AdtId::UnionId(it) => it.lookup(db).container,
516 AdtId::EnumId(it) => it.lookup(db).container, 378 AdtId::EnumId(it) => it.lookup(db).container,
517 } 379 }
380 .module(db)
518 } 381 }
519} 382}
520 383
@@ -533,17 +396,17 @@ impl HasModule for GenericDefId {
533 match self { 396 match self {
534 GenericDefId::FunctionId(it) => it.lookup(db).module(db), 397 GenericDefId::FunctionId(it) => it.lookup(db).module(db),
535 GenericDefId::AdtId(it) => it.module(db), 398 GenericDefId::AdtId(it) => it.module(db),
536 GenericDefId::TraitId(it) => it.lookup(db).container, 399 GenericDefId::TraitId(it) => it.lookup(db).container.module(db),
537 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), 400 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
538 GenericDefId::ImplId(it) => it.lookup(db).container, 401 GenericDefId::ImplId(it) => it.lookup(db).container.module(db),
539 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container, 402 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db),
540 GenericDefId::ConstId(it) => it.lookup(db).module(db), 403 GenericDefId::ConstId(it) => it.lookup(db).module(db),
541 } 404 }
542 } 405 }
543} 406}
544 407
545impl HasModule for StaticLoc { 408impl HasModule for StaticLoc {
546 fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { 409 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
547 self.container 410 self.container.module(db)
548 } 411 }
549} 412}
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index 9aae7e48e..5d4ca73a3 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -57,10 +57,7 @@ mod tests;
57 57
58use std::sync::Arc; 58use std::sync::Arc;
59 59
60use hir_expand::{ 60use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile};
61 ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId,
62};
63use once_cell::sync::Lazy;
64use ra_arena::Arena; 61use ra_arena::Arena;
65use ra_db::{CrateId, Edition, FileId, FilePosition}; 62use ra_db::{CrateId, Edition, FileId, FilePosition};
66use ra_prof::profile; 63use ra_prof::profile;
@@ -71,12 +68,12 @@ use ra_syntax::{
71use rustc_hash::FxHashMap; 68use rustc_hash::FxHashMap;
72 69
73use crate::{ 70use crate::{
74 builtin_type::BuiltinType,
75 db::DefDatabase, 71 db::DefDatabase,
72 item_scope::{BuiltinShadowMode, ItemScope},
76 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, 73 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode},
77 path::ModPath, 74 path::ModPath,
78 per_ns::PerNs, 75 per_ns::PerNs,
79 AstId, FunctionId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId, 76 AstId, LocalModuleId, ModuleDefId, ModuleId,
80}; 77};
81 78
82/// Contains all top-level defs from a macro-expanded crate 79/// Contains all top-level defs from a macro-expanded crate
@@ -168,118 +165,10 @@ impl ModuleOrigin {
168pub struct ModuleData { 165pub struct ModuleData {
169 pub parent: Option<LocalModuleId>, 166 pub parent: Option<LocalModuleId>,
170 pub children: FxHashMap<Name, LocalModuleId>, 167 pub children: FxHashMap<Name, LocalModuleId>,
171 pub scope: ModuleScope, 168 pub scope: ItemScope,
172 169
173 /// Where does this module come from? 170 /// Where does this module come from?
174 pub origin: ModuleOrigin, 171 pub origin: ModuleOrigin,
175
176 pub impls: Vec<ImplId>,
177}
178
179#[derive(Default, Debug, PartialEq, Eq)]
180pub(crate) struct Declarations {
181 fns: FxHashMap<FileAstId<ast::FnDef>, FunctionId>,
182}
183
184#[derive(Debug, Default, PartialEq, Eq)]
185pub struct ModuleScope {
186 items: FxHashMap<Name, Resolution>,
187 /// Macros visable in current module in legacy textual scope
188 ///
189 /// For macros invoked by an unquatified identifier like `bar!()`, `legacy_macros` will be searched in first.
190 /// If it yields no result, then it turns to module scoped `macros`.
191 /// It macros with name quatified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped,
192 /// and only normal scoped `macros` will be searched in.
193 ///
194 /// Note that this automatically inherit macros defined textually before the definition of module itself.
195 ///
196 /// Module scoped macros will be inserted into `items` instead of here.
197 // FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will
198 // be all resolved to the last one defined if shadowing happens.
199 legacy_macros: FxHashMap<Name, MacroDefId>,
200}
201
202static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| {
203 BuiltinType::ALL
204 .iter()
205 .map(|(name, ty)| {
206 (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: None })
207 })
208 .collect()
209});
210
211/// Shadow mode for builtin type which can be shadowed by module.
212#[derive(Debug, Copy, Clone, PartialEq, Eq)]
213pub enum BuiltinShadowMode {
214 // Prefer Module
215 Module,
216 // Prefer Other Types
217 Other,
218}
219
220/// Legacy macros can only be accessed through special methods like `get_legacy_macros`.
221/// Other methods will only resolve values, types and module scoped macros only.
222impl ModuleScope {
223 pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, &'a Resolution)> + 'a {
224 //FIXME: shadowing
225 self.items.iter().chain(BUILTIN_SCOPE.iter())
226 }
227
228 pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
229 self.entries()
230 .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None })
231 .flat_map(|per_ns| {
232 per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter())
233 })
234 }
235
236 /// Iterate over all module scoped macros
237 pub fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
238 self.items
239 .iter()
240 .filter_map(|(name, res)| res.def.take_macros().map(|macro_| (name, macro_)))
241 }
242
243 /// Iterate over all legacy textual scoped macros visable at the end of the module
244 pub fn legacy_macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
245 self.legacy_macros.iter().map(|(name, def)| (name, *def))
246 }
247
248 /// Get a name from current module scope, legacy macros are not included
249 pub fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> {
250 match shadow {
251 BuiltinShadowMode::Module => self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)),
252 BuiltinShadowMode::Other => {
253 let item = self.items.get(name);
254 if let Some(res) = item {
255 if let Some(ModuleDefId::ModuleId(_)) = res.def.take_types() {
256 return BUILTIN_SCOPE.get(name).or(item);
257 }
258 }
259
260 item.or_else(|| BUILTIN_SCOPE.get(name))
261 }
262 }
263 }
264
265 pub fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a {
266 self.items.values().filter_map(|r| match r.def.take_types() {
267 Some(ModuleDefId::TraitId(t)) => Some(t),
268 _ => None,
269 })
270 }
271
272 fn get_legacy_macro(&self, name: &Name) -> Option<MacroDefId> {
273 self.legacy_macros.get(name).copied()
274 }
275}
276
277#[derive(Debug, Clone, PartialEq, Eq, Default)]
278pub struct Resolution {
279 /// None for unresolved
280 pub def: PerNs,
281 /// ident by which this is imported into local scope.
282 pub import: Option<LocalImportId>,
283} 172}
284 173
285impl CrateDefMap { 174impl CrateDefMap {
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 8bbf7ffa2..2b194f488 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -18,15 +18,15 @@ use test_utils::tested_by;
18use crate::{ 18use crate::{
19 attr::Attrs, 19 attr::Attrs,
20 db::DefDatabase, 20 db::DefDatabase,
21 item_scope::Resolution,
21 nameres::{ 22 nameres::{
22 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 23 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
23 raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, Resolution, ResolveMode, 24 raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode,
24 }, 25 },
25 path::{ModPath, PathKind}, 26 path::{ModPath, PathKind},
26 per_ns::PerNs, 27 per_ns::PerNs,
27 AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, 28 AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern,
28 LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, 29 LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc,
29 TypeAliasLoc, UnionLoc,
30}; 30};
31 31
32pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { 32pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
@@ -92,7 +92,7 @@ impl PartialResolvedImport {
92#[derive(Clone, Debug, Eq, PartialEq)] 92#[derive(Clone, Debug, Eq, PartialEq)]
93struct ImportDirective { 93struct ImportDirective {
94 module_id: LocalModuleId, 94 module_id: LocalModuleId,
95 import_id: LocalImportId, 95 import_id: raw::Import,
96 import: raw::ImportData, 96 import: raw::ImportData,
97 status: PartialResolvedImport, 97 status: PartialResolvedImport,
98} 98}
@@ -109,7 +109,7 @@ struct MacroDirective {
109struct DefCollector<'a, DB> { 109struct DefCollector<'a, DB> {
110 db: &'a DB, 110 db: &'a DB,
111 def_map: CrateDefMap, 111 def_map: CrateDefMap,
112 glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, LocalImportId)>>, 112 glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, raw::Import)>>,
113 unresolved_imports: Vec<ImportDirective>, 113 unresolved_imports: Vec<ImportDirective>,
114 resolved_imports: Vec<ImportDirective>, 114 resolved_imports: Vec<ImportDirective>,
115 unexpanded_macros: Vec<MacroDirective>, 115 unexpanded_macros: Vec<MacroDirective>,
@@ -218,21 +218,21 @@ where
218 self.update( 218 self.update(
219 self.def_map.root, 219 self.def_map.root,
220 None, 220 None,
221 &[(name, Resolution { def: PerNs::macros(macro_), import: None })], 221 &[(name, Resolution { def: PerNs::macros(macro_), import: false })],
222 ); 222 );
223 } 223 }
224 } 224 }
225 225
226 /// Define a legacy textual scoped macro in module 226 /// Define a legacy textual scoped macro in module
227 /// 227 ///
228 /// We use a map `legacy_macros` to store all legacy textual scoped macros visable per module. 228 /// We use a map `legacy_macros` to store all legacy textual scoped macros visible per module.
229 /// It will clone all macros from parent legacy scope, whose definition is prior to 229 /// It will clone all macros from parent legacy scope, whose definition is prior to
230 /// the definition of current module. 230 /// the definition of current module.
231 /// And also, `macro_use` on a module will import all legacy macros visable inside to 231 /// And also, `macro_use` on a module will import all legacy macros visible inside to
232 /// current legacy scope, with possible shadowing. 232 /// current legacy scope, with possible shadowing.
233 fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, macro_: MacroDefId) { 233 fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, mac: MacroDefId) {
234 // Always shadowing 234 // Always shadowing
235 self.def_map.modules[module_id].scope.legacy_macros.insert(name, macro_); 235 self.def_map.modules[module_id].scope.define_legacy_macro(name, mac);
236 } 236 }
237 237
238 /// Import macros from `#[macro_use] extern crate`. 238 /// Import macros from `#[macro_use] extern crate`.
@@ -371,11 +371,7 @@ where
371 let scope = &item_map[m.local_id].scope; 371 let scope = &item_map[m.local_id].scope;
372 372
373 // Module scoped macros is included 373 // Module scoped macros is included
374 let items = scope 374 let items = scope.collect_resolutions();
375 .items
376 .iter()
377 .map(|(name, res)| (name.clone(), res.clone()))
378 .collect::<Vec<_>>();
379 375
380 self.update(module_id, Some(import_id), &items); 376 self.update(module_id, Some(import_id), &items);
381 } else { 377 } else {
@@ -385,11 +381,7 @@ where
385 let scope = &self.def_map[m.local_id].scope; 381 let scope = &self.def_map[m.local_id].scope;
386 382
387 // Module scoped macros is included 383 // Module scoped macros is included
388 let items = scope 384 let items = scope.collect_resolutions();
389 .items
390 .iter()
391 .map(|(name, res)| (name.clone(), res.clone()))
392 .collect::<Vec<_>>();
393 385
394 self.update(module_id, Some(import_id), &items); 386 self.update(module_id, Some(import_id), &items);
395 // record the glob import in case we add further items 387 // record the glob import in case we add further items
@@ -406,14 +398,14 @@ where
406 let resolutions = enum_data 398 let resolutions = enum_data
407 .variants 399 .variants
408 .iter() 400 .iter()
409 .filter_map(|(local_id, variant_data)| { 401 .map(|(local_id, variant_data)| {
410 let name = variant_data.name.clone(); 402 let name = variant_data.name.clone();
411 let variant = EnumVariantId { parent: e, local_id }; 403 let variant = EnumVariantId { parent: e, local_id };
412 let res = Resolution { 404 let res = Resolution {
413 def: PerNs::both(variant.into(), variant.into()), 405 def: PerNs::both(variant.into(), variant.into()),
414 import: Some(import_id), 406 import: true,
415 }; 407 };
416 Some((name, res)) 408 (name, res)
417 }) 409 })
418 .collect::<Vec<_>>(); 410 .collect::<Vec<_>>();
419 self.update(module_id, Some(import_id), &resolutions); 411 self.update(module_id, Some(import_id), &resolutions);
@@ -438,7 +430,7 @@ where
438 } 430 }
439 } 431 }
440 432
441 let resolution = Resolution { def, import: Some(import_id) }; 433 let resolution = Resolution { def, import: true };
442 self.update(module_id, Some(import_id), &[(name, resolution)]); 434 self.update(module_id, Some(import_id), &[(name, resolution)]);
443 } 435 }
444 None => tested_by!(bogus_paths), 436 None => tested_by!(bogus_paths),
@@ -449,7 +441,7 @@ where
449 fn update( 441 fn update(
450 &mut self, 442 &mut self,
451 module_id: LocalModuleId, 443 module_id: LocalModuleId,
452 import: Option<LocalImportId>, 444 import: Option<raw::Import>,
453 resolutions: &[(Name, Resolution)], 445 resolutions: &[(Name, Resolution)],
454 ) { 446 ) {
455 self.update_recursive(module_id, import, resolutions, 0) 447 self.update_recursive(module_id, import, resolutions, 0)
@@ -458,7 +450,7 @@ where
458 fn update_recursive( 450 fn update_recursive(
459 &mut self, 451 &mut self,
460 module_id: LocalModuleId, 452 module_id: LocalModuleId,
461 import: Option<LocalImportId>, 453 import: Option<raw::Import>,
462 resolutions: &[(Name, Resolution)], 454 resolutions: &[(Name, Resolution)],
463 depth: usize, 455 depth: usize,
464 ) { 456 ) {
@@ -466,34 +458,10 @@ where
466 // prevent stack overflows (but this shouldn't be possible) 458 // prevent stack overflows (but this shouldn't be possible)
467 panic!("infinite recursion in glob imports!"); 459 panic!("infinite recursion in glob imports!");
468 } 460 }
469 let module_items = &mut self.def_map.modules[module_id].scope; 461 let scope = &mut self.def_map.modules[module_id].scope;
470 let mut changed = false; 462 let mut changed = false;
471 for (name, res) in resolutions { 463 for (name, res) in resolutions {
472 let existing = module_items.items.entry(name.clone()).or_default(); 464 changed |= scope.push_res(name.clone(), res, import.is_some());
473
474 if existing.def.types.is_none() && res.def.types.is_some() {
475 existing.def.types = res.def.types;
476 existing.import = import.or(res.import);
477 changed = true;
478 }
479 if existing.def.values.is_none() && res.def.values.is_some() {
480 existing.def.values = res.def.values;
481 existing.import = import.or(res.import);
482 changed = true;
483 }
484 if existing.def.macros.is_none() && res.def.macros.is_some() {
485 existing.def.macros = res.def.macros;
486 existing.import = import.or(res.import);
487 changed = true;
488 }
489
490 if existing.def.is_none()
491 && res.def.is_none()
492 && existing.import.is_none()
493 && res.import.is_some()
494 {
495 existing.import = res.import;
496 }
497 } 465 }
498 466
499 if !changed { 467 if !changed {
@@ -661,11 +629,14 @@ where
661 krate: self.def_collector.def_map.krate, 629 krate: self.def_collector.def_map.krate,
662 local_id: self.module_id, 630 local_id: self.module_id,
663 }; 631 };
632 let container = ContainerId::ModuleId(module);
664 let ast_id = self.raw_items[imp].ast_id; 633 let ast_id = self.raw_items[imp].ast_id;
665 let impl_id = 634 let impl_id =
666 ImplLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 635 ImplLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
667 .intern(self.def_collector.db); 636 .intern(self.def_collector.db);
668 self.def_collector.def_map.modules[self.module_id].impls.push(impl_id) 637 self.def_collector.def_map.modules[self.module_id]
638 .scope
639 .define_impl(impl_id)
669 } 640 }
670 } 641 }
671 } 642 }
@@ -739,13 +710,15 @@ where
739 let res = modules.alloc(ModuleData::default()); 710 let res = modules.alloc(ModuleData::default());
740 modules[res].parent = Some(self.module_id); 711 modules[res].parent = Some(self.module_id);
741 modules[res].origin = ModuleOrigin::not_sure_file(definition, declaration); 712 modules[res].origin = ModuleOrigin::not_sure_file(definition, declaration);
742 modules[res].scope.legacy_macros = modules[self.module_id].scope.legacy_macros.clone(); 713 for (name, mac) in modules[self.module_id].scope.collect_legacy_macros() {
714 modules[res].scope.define_legacy_macro(name, mac)
715 }
743 modules[self.module_id].children.insert(name.clone(), res); 716 modules[self.module_id].children.insert(name.clone(), res);
744 let resolution = Resolution { 717 let resolution = Resolution {
745 def: PerNs::types( 718 def: PerNs::types(
746 ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(), 719 ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(),
747 ), 720 ),
748 import: None, 721 import: false,
749 }; 722 };
750 self.def_collector.update(self.module_id, None, &[(name, resolution)]); 723 self.def_collector.update(self.module_id, None, &[(name, resolution)]);
751 res 724 res
@@ -760,10 +733,11 @@ where
760 self.collect_derives(attrs, def); 733 self.collect_derives(attrs, def);
761 734
762 let name = def.name.clone(); 735 let name = def.name.clone();
736 let container = ContainerId::ModuleId(module);
763 let def: PerNs = match def.kind { 737 let def: PerNs = match def.kind {
764 raw::DefKind::Function(ast_id) => { 738 raw::DefKind::Function(ast_id) => {
765 let def = FunctionLoc { 739 let def = FunctionLoc {
766 container: ContainerId::ModuleId(module), 740 container: container.into(),
767 ast_id: AstId::new(self.file_id, ast_id), 741 ast_id: AstId::new(self.file_id, ast_id),
768 } 742 }
769 .intern(self.def_collector.db); 743 .intern(self.def_collector.db);
@@ -771,23 +745,23 @@ where
771 PerNs::values(def.into()) 745 PerNs::values(def.into())
772 } 746 }
773 raw::DefKind::Struct(ast_id) => { 747 raw::DefKind::Struct(ast_id) => {
774 let def = StructLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 748 let def = StructLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
775 .intern(self.def_collector.db); 749 .intern(self.def_collector.db);
776 PerNs::both(def.into(), def.into()) 750 PerNs::both(def.into(), def.into())
777 } 751 }
778 raw::DefKind::Union(ast_id) => { 752 raw::DefKind::Union(ast_id) => {
779 let def = UnionLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 753 let def = UnionLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
780 .intern(self.def_collector.db); 754 .intern(self.def_collector.db);
781 PerNs::both(def.into(), def.into()) 755 PerNs::both(def.into(), def.into())
782 } 756 }
783 raw::DefKind::Enum(ast_id) => { 757 raw::DefKind::Enum(ast_id) => {
784 let def = EnumLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 758 let def = EnumLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
785 .intern(self.def_collector.db); 759 .intern(self.def_collector.db);
786 PerNs::types(def.into()) 760 PerNs::types(def.into())
787 } 761 }
788 raw::DefKind::Const(ast_id) => { 762 raw::DefKind::Const(ast_id) => {
789 let def = ConstLoc { 763 let def = ConstLoc {
790 container: ContainerId::ModuleId(module), 764 container: container.into(),
791 ast_id: AstId::new(self.file_id, ast_id), 765 ast_id: AstId::new(self.file_id, ast_id),
792 } 766 }
793 .intern(self.def_collector.db); 767 .intern(self.def_collector.db);
@@ -795,20 +769,20 @@ where
795 PerNs::values(def.into()) 769 PerNs::values(def.into())
796 } 770 }
797 raw::DefKind::Static(ast_id) => { 771 raw::DefKind::Static(ast_id) => {
798 let def = StaticLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 772 let def = StaticLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
799 .intern(self.def_collector.db); 773 .intern(self.def_collector.db);
800 774
801 PerNs::values(def.into()) 775 PerNs::values(def.into())
802 } 776 }
803 raw::DefKind::Trait(ast_id) => { 777 raw::DefKind::Trait(ast_id) => {
804 let def = TraitLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 778 let def = TraitLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
805 .intern(self.def_collector.db); 779 .intern(self.def_collector.db);
806 780
807 PerNs::types(def.into()) 781 PerNs::types(def.into())
808 } 782 }
809 raw::DefKind::TypeAlias(ast_id) => { 783 raw::DefKind::TypeAlias(ast_id) => {
810 let def = TypeAliasLoc { 784 let def = TypeAliasLoc {
811 container: ContainerId::ModuleId(module), 785 container: container.into(),
812 ast_id: AstId::new(self.file_id, ast_id), 786 ast_id: AstId::new(self.file_id, ast_id),
813 } 787 }
814 .intern(self.def_collector.db); 788 .intern(self.def_collector.db);
@@ -816,7 +790,7 @@ where
816 PerNs::types(def.into()) 790 PerNs::types(def.into())
817 } 791 }
818 }; 792 };
819 let resolution = Resolution { def, import: None }; 793 let resolution = Resolution { def, import: false };
820 self.def_collector.update(self.module_id, None, &[(name, resolution)]) 794 self.def_collector.update(self.module_id, None, &[(name, resolution)])
821 } 795 }
822 796
@@ -902,7 +876,7 @@ where
902 } 876 }
903 877
904 fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) { 878 fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) {
905 let macros = self.def_collector.def_map[module_id].scope.legacy_macros.clone(); 879 let macros = self.def_collector.def_map[module_id].scope.collect_legacy_macros();
906 for (name, macro_) in macros { 880 for (name, macro_) in macros {
907 self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_); 881 self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_);
908 } 882 }
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index ecb4d7c03..73dc08745 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -7,24 +7,21 @@
7 7
8use std::{ops::Index, sync::Arc}; 8use std::{ops::Index, sync::Arc};
9 9
10use either::Either;
11use hir_expand::{ 10use hir_expand::{
12 ast_id_map::AstIdMap, 11 ast_id_map::AstIdMap,
13 db::AstDatabase, 12 db::AstDatabase,
14 hygiene::Hygiene, 13 hygiene::Hygiene,
15 name::{AsName, Name}, 14 name::{AsName, Name},
16}; 15};
17use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; 16use ra_arena::{impl_arena_id, Arena, RawId};
17use ra_prof::profile;
18use ra_syntax::{ 18use ra_syntax::{
19 ast::{self, AttrsOwner, NameOwner}, 19 ast::{self, AttrsOwner, NameOwner},
20 AstNode, AstPtr, 20 AstNode,
21}; 21};
22use test_utils::tested_by; 22use test_utils::tested_by;
23 23
24use crate::{ 24use crate::{attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile};
25 attr::Attrs, db::DefDatabase, path::ModPath, trace::Trace, FileAstId, HirFileId, InFile,
26 LocalImportId,
27};
28 25
29/// `RawItems` is a set of top-level items in a file (except for impls). 26/// `RawItems` is a set of top-level items in a file (except for impls).
30/// 27///
@@ -33,7 +30,7 @@ use crate::{
33#[derive(Debug, Default, PartialEq, Eq)] 30#[derive(Debug, Default, PartialEq, Eq)]
34pub struct RawItems { 31pub struct RawItems {
35 modules: Arena<Module, ModuleData>, 32 modules: Arena<Module, ModuleData>,
36 imports: Arena<LocalImportId, ImportData>, 33 imports: Arena<Import, ImportData>,
37 defs: Arena<Def, DefData>, 34 defs: Arena<Def, DefData>,
38 macros: Arena<Macro, MacroData>, 35 macros: Arena<Macro, MacroData>,
39 impls: Arena<Impl, ImplData>, 36 impls: Arena<Impl, ImplData>,
@@ -41,35 +38,15 @@ pub struct RawItems {
41 items: Vec<RawItem>, 38 items: Vec<RawItem>,
42} 39}
43 40
44#[derive(Debug, Default, PartialEq, Eq)]
45pub struct ImportSourceMap {
46 map: ArenaMap<LocalImportId, ImportSourcePtr>,
47}
48
49type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>;
50
51impl ImportSourceMap {
52 pub fn get(&self, import: LocalImportId) -> ImportSourcePtr {
53 self.map[import].clone()
54 }
55}
56
57impl RawItems { 41impl RawItems {
58 pub(crate) fn raw_items_query( 42 pub(crate) fn raw_items_query(
59 db: &(impl DefDatabase + AstDatabase), 43 db: &(impl DefDatabase + AstDatabase),
60 file_id: HirFileId, 44 file_id: HirFileId,
61 ) -> Arc<RawItems> { 45 ) -> Arc<RawItems> {
62 db.raw_items_with_source_map(file_id).0 46 let _p = profile("raw_items_query");
63 }
64
65 pub(crate) fn raw_items_with_source_map_query(
66 db: &(impl DefDatabase + AstDatabase),
67 file_id: HirFileId,
68 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) {
69 let mut collector = RawItemsCollector { 47 let mut collector = RawItemsCollector {
70 raw_items: RawItems::default(), 48 raw_items: RawItems::default(),
71 source_ast_id_map: db.ast_id_map(file_id), 49 source_ast_id_map: db.ast_id_map(file_id),
72 imports: Trace::new(),
73 file_id, 50 file_id,
74 hygiene: Hygiene::new(db, file_id), 51 hygiene: Hygiene::new(db, file_id),
75 }; 52 };
@@ -80,11 +57,8 @@ impl RawItems {
80 collector.process_module(None, item_list); 57 collector.process_module(None, item_list);
81 } 58 }
82 } 59 }
83 let mut raw_items = collector.raw_items; 60 let raw_items = collector.raw_items;
84 let (arena, map) = collector.imports.into_arena_and_map(); 61 Arc::new(raw_items)
85 raw_items.imports = arena;
86 let source_map = ImportSourceMap { map };
87 (Arc::new(raw_items), Arc::new(source_map))
88 } 62 }
89 63
90 pub(super) fn items(&self) -> &[RawItem] { 64 pub(super) fn items(&self) -> &[RawItem] {
@@ -99,9 +73,9 @@ impl Index<Module> for RawItems {
99 } 73 }
100} 74}
101 75
102impl Index<LocalImportId> for RawItems { 76impl Index<Import> for RawItems {
103 type Output = ImportData; 77 type Output = ImportData;
104 fn index(&self, idx: LocalImportId) -> &ImportData { 78 fn index(&self, idx: Import) -> &ImportData {
105 &self.imports[idx] 79 &self.imports[idx]
106 } 80 }
107} 81}
@@ -136,7 +110,7 @@ pub(super) struct RawItem {
136#[derive(Debug, PartialEq, Eq, Clone, Copy)] 110#[derive(Debug, PartialEq, Eq, Clone, Copy)]
137pub(super) enum RawItemKind { 111pub(super) enum RawItemKind {
138 Module(Module), 112 Module(Module),
139 Import(LocalImportId), 113 Import(Import),
140 Def(Def), 114 Def(Def),
141 Macro(Macro), 115 Macro(Macro),
142 Impl(Impl), 116 Impl(Impl),
@@ -152,6 +126,10 @@ pub(super) enum ModuleData {
152 Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> }, 126 Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> },
153} 127}
154 128
129#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
130pub(crate) struct Import(RawId);
131impl_arena_id!(Import);
132
155#[derive(Debug, Clone, PartialEq, Eq)] 133#[derive(Debug, Clone, PartialEq, Eq)]
156pub struct ImportData { 134pub struct ImportData {
157 pub(super) path: ModPath, 135 pub(super) path: ModPath,
@@ -223,7 +201,6 @@ pub(super) struct ImplData {
223 201
224struct RawItemsCollector { 202struct RawItemsCollector {
225 raw_items: RawItems, 203 raw_items: RawItems,
226 imports: Trace<LocalImportId, ImportData, ImportSourcePtr>,
227 source_ast_id_map: Arc<AstIdMap>, 204 source_ast_id_map: Arc<AstIdMap>,
228 file_id: HirFileId, 205 file_id: HirFileId,
229 hygiene: Hygiene, 206 hygiene: Hygiene,
@@ -330,7 +307,7 @@ impl RawItemsCollector {
330 ModPath::expand_use_item( 307 ModPath::expand_use_item(
331 InFile { value: use_item, file_id: self.file_id }, 308 InFile { value: use_item, file_id: self.file_id },
332 &self.hygiene, 309 &self.hygiene,
333 |path, use_tree, is_glob, alias| { 310 |path, _use_tree, is_glob, alias| {
334 let import_data = ImportData { 311 let import_data = ImportData {
335 path, 312 path,
336 alias, 313 alias,
@@ -339,11 +316,11 @@ impl RawItemsCollector {
339 is_extern_crate: false, 316 is_extern_crate: false,
340 is_macro_use: false, 317 is_macro_use: false,
341 }; 318 };
342 buf.push((import_data, Either::Left(AstPtr::new(use_tree)))); 319 buf.push(import_data);
343 }, 320 },
344 ); 321 );
345 for (import_data, ptr) in buf { 322 for import_data in buf {
346 self.push_import(current_module, attrs.clone(), import_data, ptr); 323 self.push_import(current_module, attrs.clone(), import_data);
347 } 324 }
348 } 325 }
349 326
@@ -366,12 +343,7 @@ impl RawItemsCollector {
366 is_extern_crate: true, 343 is_extern_crate: true,
367 is_macro_use, 344 is_macro_use,
368 }; 345 };
369 self.push_import( 346 self.push_import(current_module, attrs, import_data);
370 current_module,
371 attrs,
372 import_data,
373 Either::Right(AstPtr::new(&extern_crate)),
374 );
375 } 347 }
376 } 348 }
377 349
@@ -402,14 +374,8 @@ impl RawItemsCollector {
402 self.push_item(current_module, attrs, RawItemKind::Impl(imp)) 374 self.push_item(current_module, attrs, RawItemKind::Impl(imp))
403 } 375 }
404 376
405 fn push_import( 377 fn push_import(&mut self, current_module: Option<Module>, attrs: Attrs, data: ImportData) {
406 &mut self, 378 let import = self.raw_items.imports.alloc(data);
407 current_module: Option<Module>,
408 attrs: Attrs,
409 data: ImportData,
410 source: ImportSourcePtr,
411 ) {
412 let import = self.imports.alloc(|| source, || data);
413 self.push_item(current_module, attrs, RawItemKind::Import(import)) 379 self.push_item(current_module, attrs, RawItemKind::Import(import))
414 } 380 }
415 381
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index 61cdd768e..4e968bcc8 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -32,27 +32,22 @@ fn render_crate_def_map(map: &CrateDefMap) -> String {
32 *buf += path; 32 *buf += path;
33 *buf += "\n"; 33 *buf += "\n";
34 34
35 let mut entries = map.modules[module] 35 let mut entries = map.modules[module].scope.collect_resolutions();
36 .scope 36 entries.sort_by_key(|(name, _)| name.clone());
37 .items
38 .iter()
39 .map(|(name, res)| (name, res.def))
40 .collect::<Vec<_>>();
41 entries.sort_by_key(|(name, _)| *name);
42 37
43 for (name, res) in entries { 38 for (name, res) in entries {
44 *buf += &format!("{}:", name); 39 *buf += &format!("{}:", name);
45 40
46 if res.types.is_some() { 41 if res.def.types.is_some() {
47 *buf += " t"; 42 *buf += " t";
48 } 43 }
49 if res.values.is_some() { 44 if res.def.values.is_some() {
50 *buf += " v"; 45 *buf += " v";
51 } 46 }
52 if res.macros.is_some() { 47 if res.def.macros.is_some() {
53 *buf += " m"; 48 *buf += " m";
54 } 49 }
55 if res.is_none() { 50 if res.def.is_none() {
56 *buf += " _"; 51 *buf += " _";
57 } 52 }
58 53
@@ -587,6 +582,6 @@ mod b {
587 â‹®T: v 582 â‹®T: v
588 â‹® 583 â‹®
589 â‹®crate::a 584 â‹®crate::a
590 â‹®T: t v 585 â‹®T: t v
591"###); 586"###);
592} 587}
diff --git a/crates/ra_hir_def/src/nameres/tests/incremental.rs b/crates/ra_hir_def/src/nameres/tests/incremental.rs
index 903a22771..ef2e9435c 100644
--- a/crates/ra_hir_def/src/nameres/tests/incremental.rs
+++ b/crates/ra_hir_def/src/nameres/tests/incremental.rs
@@ -116,7 +116,7 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() {
116 let events = db.log_executed(|| { 116 let events = db.log_executed(|| {
117 let crate_def_map = db.crate_def_map(krate); 117 let crate_def_map = db.crate_def_map(krate);
118 let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); 118 let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
119 assert_eq!(module_data.scope.items.len(), 1); 119 assert_eq!(module_data.scope.collect_resolutions().len(), 1);
120 }); 120 });
121 assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) 121 assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
122 } 122 }
@@ -126,7 +126,7 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() {
126 let events = db.log_executed(|| { 126 let events = db.log_executed(|| {
127 let crate_def_map = db.crate_def_map(krate); 127 let crate_def_map = db.crate_def_map(krate);
128 let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); 128 let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
129 assert_eq!(module_data.scope.items.len(), 1); 129 assert_eq!(module_data.scope.collect_resolutions().len(), 1);
130 }); 130 });
131 assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) 131 assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
132 } 132 }
diff --git a/crates/ra_hir_def/src/nameres/tests/macros.rs b/crates/ra_hir_def/src/nameres/tests/macros.rs
index cfa4ecb1a..d104f5993 100644
--- a/crates/ra_hir_def/src/nameres/tests/macros.rs
+++ b/crates/ra_hir_def/src/nameres/tests/macros.rs
@@ -610,7 +610,7 @@ fn expand_derive() {
610 struct Foo; 610 struct Foo;
611 ", 611 ",
612 ); 612 );
613 assert_eq!(map.modules[map.root].impls.len(), 1); 613 assert_eq!(map.modules[map.root].scope.impls().len(), 1);
614} 614}
615 615
616#[test] 616#[test]
@@ -622,5 +622,5 @@ fn expand_multiple_derive() {
622 struct Foo; 622 struct Foo;
623 ", 623 ",
624 ); 624 );
625 assert_eq!(map.modules[map.root].impls.len(), 2); 625 assert_eq!(map.modules[map.root].scope.impls().len(), 2);
626} 626}
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index 7302cf0f1..8e1294201 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -135,7 +135,7 @@ impl Path {
135 } 135 }
136 136
137 pub fn type_anchor(&self) -> Option<&TypeRef> { 137 pub fn type_anchor(&self) -> Option<&TypeRef> {
138 self.type_anchor.as_ref().map(|it| &**it) 138 self.type_anchor.as_deref()
139 } 139 }
140 140
141 pub fn segments(&self) -> PathSegments<'_> { 141 pub fn segments(&self) -> PathSegments<'_> {
@@ -257,6 +257,7 @@ macro_rules! __known_path {
257 (std::ops::Try) => {}; 257 (std::ops::Try) => {};
258 (std::ops::Neg) => {}; 258 (std::ops::Neg) => {};
259 (std::ops::Not) => {}; 259 (std::ops::Not) => {};
260 (std::ops::Index) => {};
260 ($path:path) => { 261 ($path:path) => {
261 compile_error!("Please register your known path in the path module") 262 compile_error!("Please register your known path in the path module")
262 }; 263 };
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 2694c0438..83013fed3 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -14,12 +14,13 @@ use crate::{
14 db::DefDatabase, 14 db::DefDatabase,
15 expr::{ExprId, PatId}, 15 expr::{ExprId, PatId},
16 generics::GenericParams, 16 generics::GenericParams,
17 nameres::{BuiltinShadowMode, CrateDefMap}, 17 item_scope::BuiltinShadowMode,
18 nameres::CrateDefMap,
18 path::{ModPath, PathKind}, 19 path::{ModPath, PathKind},
19 per_ns::PerNs, 20 per_ns::PerNs,
20 AdtId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, 21 AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId,
21 HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, 22 FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId,
22 TypeAliasId, TypeParamId, VariantId, 23 StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId,
23}; 24};
24 25
25#[derive(Debug, Clone, Default)] 26#[derive(Debug, Clone, Default)]
@@ -583,9 +584,18 @@ impl HasResolver for DefWithBodyId {
583impl HasResolver for ContainerId { 584impl HasResolver for ContainerId {
584 fn resolver(self, db: &impl DefDatabase) -> Resolver { 585 fn resolver(self, db: &impl DefDatabase) -> Resolver {
585 match self { 586 match self {
586 ContainerId::TraitId(it) => it.resolver(db),
587 ContainerId::ImplId(it) => it.resolver(db),
588 ContainerId::ModuleId(it) => it.resolver(db), 587 ContainerId::ModuleId(it) => it.resolver(db),
588 ContainerId::DefWithBodyId(it) => it.resolver(db),
589 }
590 }
591}
592
593impl HasResolver for AssocContainerId {
594 fn resolver(self, db: &impl DefDatabase) -> Resolver {
595 match self {
596 AssocContainerId::ContainerId(it) => it.resolver(db),
597 AssocContainerId::TraitId(it) => it.resolver(db),
598 AssocContainerId::ImplId(it) => it.resolver(db),
589 } 599 }
590 } 600 }
591} 601}
diff --git a/crates/ra_hir_def/src/src.rs b/crates/ra_hir_def/src/src.rs
index 20200d1db..499375b80 100644
--- a/crates/ra_hir_def/src/src.rs
+++ b/crates/ra_hir_def/src/src.rs
@@ -2,94 +2,28 @@
2 2
3use hir_expand::InFile; 3use hir_expand::InFile;
4use ra_arena::map::ArenaMap; 4use ra_arena::map::ArenaMap;
5use ra_syntax::ast; 5use ra_syntax::AstNode;
6 6
7use crate::{ 7use crate::{db::DefDatabase, AssocItemLoc, ItemLoc};
8 db::DefDatabase, ConstLoc, EnumLoc, FunctionLoc, ImplLoc, StaticLoc, StructLoc, TraitLoc,
9 TypeAliasLoc, UnionLoc,
10};
11 8
12pub trait HasSource { 9pub trait HasSource {
13 type Value; 10 type Value;
14 fn source(&self, db: &impl DefDatabase) -> InFile<Self::Value>; 11 fn source(&self, db: &impl DefDatabase) -> InFile<Self::Value>;
15} 12}
16 13
17impl HasSource for FunctionLoc { 14impl<N: AstNode> HasSource for AssocItemLoc<N> {
18 type Value = ast::FnDef; 15 type Value = N;
19 16
20 fn source(&self, db: &impl DefDatabase) -> InFile<ast::FnDef> { 17 fn source(&self, db: &impl DefDatabase) -> InFile<N> {
21 let node = self.ast_id.to_node(db); 18 let node = self.ast_id.to_node(db);
22 InFile::new(self.ast_id.file_id, node) 19 InFile::new(self.ast_id.file_id, node)
23 } 20 }
24} 21}
25 22
26impl HasSource for TypeAliasLoc { 23impl<N: AstNode> HasSource for ItemLoc<N> {
27 type Value = ast::TypeAliasDef; 24 type Value = N;
28 25
29 fn source(&self, db: &impl DefDatabase) -> InFile<ast::TypeAliasDef> { 26 fn source(&self, db: &impl DefDatabase) -> InFile<N> {
30 let node = self.ast_id.to_node(db);
31 InFile::new(self.ast_id.file_id, node)
32 }
33}
34
35impl HasSource for ConstLoc {
36 type Value = ast::ConstDef;
37
38 fn source(&self, db: &impl DefDatabase) -> InFile<ast::ConstDef> {
39 let node = self.ast_id.to_node(db);
40 InFile::new(self.ast_id.file_id, node)
41 }
42}
43
44impl HasSource for StaticLoc {
45 type Value = ast::StaticDef;
46
47 fn source(&self, db: &impl DefDatabase) -> InFile<ast::StaticDef> {
48 let node = self.ast_id.to_node(db);
49 InFile::new(self.ast_id.file_id, node)
50 }
51}
52
53impl HasSource for ImplLoc {
54 type Value = ast::ImplBlock;
55
56 fn source(&self, db: &impl DefDatabase) -> InFile<ast::ImplBlock> {
57 let node = self.ast_id.to_node(db);
58 InFile::new(self.ast_id.file_id, node)
59 }
60}
61
62impl HasSource for TraitLoc {
63 type Value = ast::TraitDef;
64
65 fn source(&self, db: &impl DefDatabase) -> InFile<ast::TraitDef> {
66 let node = self.ast_id.to_node(db);
67 InFile::new(self.ast_id.file_id, node)
68 }
69}
70
71impl HasSource for StructLoc {
72 type Value = ast::StructDef;
73
74 fn source(&self, db: &impl DefDatabase) -> InFile<ast::StructDef> {
75 let node = self.ast_id.to_node(db);
76 InFile::new(self.ast_id.file_id, node)
77 }
78}
79
80impl HasSource for UnionLoc {
81 type Value = ast::UnionDef;
82
83 fn source(&self, db: &impl DefDatabase) -> InFile<ast::UnionDef> {
84 let node = self.ast_id.to_node(db);
85 InFile::new(self.ast_id.file_id, node)
86 }
87}
88
89impl HasSource for EnumLoc {
90 type Value = ast::EnumDef;
91
92 fn source(&self, db: &impl DefDatabase) -> InFile<ast::EnumDef> {
93 let node = self.ast_id.to_node(db); 27 let node = self.ast_id.to_node(db);
94 InFile::new(self.ast_id.file_id, node) 28 InFile::new(self.ast_id.file_id, node)
95 } 29 }
diff --git a/crates/ra_hir_def/src/trace.rs b/crates/ra_hir_def/src/trace.rs
index 2bcd707bc..9769e88df 100644
--- a/crates/ra_hir_def/src/trace.rs
+++ b/crates/ra_hir_def/src/trace.rs
@@ -18,10 +18,6 @@ pub(crate) struct Trace<ID: ArenaId, T, V> {
18} 18}
19 19
20impl<ID: ra_arena::ArenaId + Copy, T, V> Trace<ID, T, V> { 20impl<ID: ra_arena::ArenaId + Copy, T, V> Trace<ID, T, V> {
21 pub(crate) fn new() -> Trace<ID, T, V> {
22 Trace { arena: Some(Arena::default()), map: Some(ArenaMap::default()), len: 0 }
23 }
24
25 pub(crate) fn new_for_arena() -> Trace<ID, T, V> { 21 pub(crate) fn new_for_arena() -> Trace<ID, T, V> {
26 Trace { arena: Some(Arena::default()), map: None, len: 0 } 22 Trace { arena: Some(Arena::default()), map: None, len: 0 }
27 } 23 }
@@ -52,8 +48,4 @@ impl<ID: ra_arena::ArenaId + Copy, T, V> Trace<ID, T, V> {
52 pub(crate) fn into_map(mut self) -> ArenaMap<ID, V> { 48 pub(crate) fn into_map(mut self) -> ArenaMap<ID, V> {
53 self.map.take().unwrap() 49 self.map.take().unwrap()
54 } 50 }
55
56 pub(crate) fn into_arena_and_map(mut self) -> (Arena<ID, T>, ArenaMap<ID, V>) {
57 (self.arena.take().unwrap(), self.map.take().unwrap())
58 }
59} 51}