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/body.rs63
-rw-r--r--crates/ra_hir_def/src/body/lower.rs57
-rw-r--r--crates/ra_hir_def/src/child_by_source.rs97
-rw-r--r--crates/ra_hir_def/src/data.rs12
-rw-r--r--crates/ra_hir_def/src/lib.rs283
-rw-r--r--crates/ra_hir_def/src/marks.rs1
-rw-r--r--crates/ra_hir_def/src/nameres.rs11
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs20
-rw-r--r--crates/ra_hir_def/src/nameres/path_resolution.rs5
-rw-r--r--crates/ra_hir_def/src/nameres/tests/globs.rs21
-rw-r--r--crates/ra_hir_def/src/path.rs41
-rw-r--r--crates/ra_hir_def/src/path/lower.rs6
-rw-r--r--crates/ra_hir_def/src/path/lower/lower_use.rs12
-rw-r--r--crates/ra_hir_def/src/resolver.rs19
-rw-r--r--crates/ra_hir_def/src/src.rs82
16 files changed, 325 insertions, 406 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/body.rs b/crates/ra_hir_def/src/body.rs
index 7787cb87f..401fe0b9b 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -3,10 +3,13 @@
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};
11use ra_syntax::{ast, AstNode, AstPtr}; 14use ra_syntax::{ast, AstNode, AstPtr};
12use rustc_hash::FxHashMap; 15use rustc_hash::FxHashMap;
@@ -15,15 +18,16 @@ use crate::{
15 db::DefDatabase, 18 db::DefDatabase,
16 expr::{Expr, ExprId, Pat, PatId}, 19 expr::{Expr, ExprId, Pat, PatId},
17 nameres::{BuiltinShadowMode, CrateDefMap}, 20 nameres::{BuiltinShadowMode, CrateDefMap},
18 path::Path, 21 path::{ModPath, Path},
19 src::HasSource, 22 src::HasSource,
20 DefWithBodyId, HasModule, Lookup, ModuleId, 23 DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId,
21}; 24};
22 25
23struct Expander { 26struct Expander {
24 crate_def_map: Arc<CrateDefMap>, 27 crate_def_map: Arc<CrateDefMap>,
25 current_file_id: HirFileId, 28 current_file_id: HirFileId,
26 hygiene: Hygiene, 29 hygiene: Hygiene,
30 ast_id_map: Arc<AstIdMap>,
27 module: ModuleId, 31 module: ModuleId,
28} 32}
29 33
@@ -31,7 +35,8 @@ impl Expander {
31 fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander { 35 fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander {
32 let crate_def_map = db.crate_def_map(module.krate); 36 let crate_def_map = db.crate_def_map(module.krate);
33 let hygiene = Hygiene::new(db, current_file_id); 37 let hygiene = Hygiene::new(db, current_file_id);
34 Expander { crate_def_map, current_file_id, hygiene, module } 38 let ast_id_map = db.ast_id_map(current_file_id);
39 Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module }
35 } 40 }
36 41
37 fn enter_expand( 42 fn enter_expand(
@@ -44,7 +49,7 @@ impl Expander {
44 db.ast_id_map(self.current_file_id).ast_id(&macro_call), 49 db.ast_id_map(self.current_file_id).ast_id(&macro_call),
45 ); 50 );
46 51
47 if let Some(path) = macro_call.path().and_then(|path| self.parse_path(path)) { 52 if let Some(path) = macro_call.path().and_then(|path| self.parse_mod_path(path)) {
48 if let Some(def) = self.resolve_path_as_macro(db, &path) { 53 if let Some(def) = self.resolve_path_as_macro(db, &path) {
49 let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id)); 54 let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id));
50 let file_id = call_id.as_file(); 55 let file_id = call_id.as_file();
@@ -52,9 +57,14 @@ impl Expander {
52 if let Some(expr) = ast::Expr::cast(node) { 57 if let Some(expr) = ast::Expr::cast(node) {
53 log::debug!("macro expansion {:#?}", expr.syntax()); 58 log::debug!("macro expansion {:#?}", expr.syntax());
54 59
55 let mark = Mark { file_id: self.current_file_id }; 60 let mark = Mark {
61 file_id: self.current_file_id,
62 ast_id_map: mem::take(&mut self.ast_id_map),
63 bomb: DropBomb::new("expansion mark dropped"),
64 };
56 self.hygiene = Hygiene::new(db, file_id); 65 self.hygiene = Hygiene::new(db, file_id);
57 self.current_file_id = file_id; 66 self.current_file_id = file_id;
67 self.ast_id_map = db.ast_id_map(file_id);
58 68
59 return Some((mark, expr)); 69 return Some((mark, expr));
60 } 70 }
@@ -67,10 +77,11 @@ impl Expander {
67 None 77 None
68 } 78 }
69 79
70 fn exit(&mut self, db: &impl DefDatabase, mark: Mark) { 80 fn exit(&mut self, db: &impl DefDatabase, mut mark: Mark) {
71 self.hygiene = Hygiene::new(db, mark.file_id); 81 self.hygiene = Hygiene::new(db, mark.file_id);
72 self.current_file_id = mark.file_id; 82 self.current_file_id = mark.file_id;
73 std::mem::forget(mark); 83 self.ast_id_map = mem::take(&mut mark.ast_id_map);
84 mark.bomb.defuse();
74 } 85 }
75 86
76 fn to_source<T>(&self, value: T) -> InFile<T> { 87 fn to_source<T>(&self, value: T) -> InFile<T> {
@@ -81,24 +92,27 @@ impl Expander {
81 Path::from_src(path, &self.hygiene) 92 Path::from_src(path, &self.hygiene)
82 } 93 }
83 94
84 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> { 95 fn parse_mod_path(&mut self, path: ast::Path) -> Option<ModPath> {
96 ModPath::from_src(path, &self.hygiene)
97 }
98
99 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &ModPath) -> Option<MacroDefId> {
85 self.crate_def_map 100 self.crate_def_map
86 .resolve_path(db, self.module.local_id, path.mod_path(), BuiltinShadowMode::Other) 101 .resolve_path(db, self.module.local_id, path, BuiltinShadowMode::Other)
87 .0 102 .0
88 .take_macros() 103 .take_macros()
89 } 104 }
105
106 fn ast_id<N: AstNode>(&self, item: &N) -> AstId<N> {
107 let file_local_id = self.ast_id_map.ast_id(item);
108 AstId::new(self.current_file_id, file_local_id)
109 }
90} 110}
91 111
92struct Mark { 112struct Mark {
93 file_id: HirFileId, 113 file_id: HirFileId,
94} 114 ast_id_map: Arc<AstIdMap>,
95 115 bomb: DropBomb,
96impl Drop for Mark {
97 fn drop(&mut self) {
98 if !std::thread::panicking() {
99 panic!("dropped mark")
100 }
101 }
102} 116}
103 117
104/// The body of an item (function, const etc.). 118/// The body of an item (function, const etc.).
@@ -115,6 +129,7 @@ pub struct Body {
115 pub params: Vec<PatId>, 129 pub params: Vec<PatId>,
116 /// The `ExprId` of the actual body expression. 130 /// The `ExprId` of the actual body expression.
117 pub body_expr: ExprId, 131 pub body_expr: ExprId,
132 pub defs: Vec<ModuleDefId>,
118} 133}
119 134
120pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>; 135pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>;
@@ -169,7 +184,7 @@ impl Body {
169 } 184 }
170 }; 185 };
171 let expander = Expander::new(db, file_id, module); 186 let expander = Expander::new(db, file_id, module);
172 let (body, source_map) = Body::new(db, expander, params, body); 187 let (body, source_map) = Body::new(db, def, expander, params, body);
173 (Arc::new(body), Arc::new(source_map)) 188 (Arc::new(body), Arc::new(source_map))
174 } 189 }
175 190
@@ -179,11 +194,12 @@ impl Body {
179 194
180 fn new( 195 fn new(
181 db: &impl DefDatabase, 196 db: &impl DefDatabase,
197 def: DefWithBodyId,
182 expander: Expander, 198 expander: Expander,
183 params: Option<ast::ParamList>, 199 params: Option<ast::ParamList>,
184 body: Option<ast::Expr>, 200 body: Option<ast::Expr>,
185 ) -> (Body, BodySourceMap) { 201 ) -> (Body, BodySourceMap) {
186 lower::lower(db, expander, params, body) 202 lower::lower(db, def, expander, params, body)
187 } 203 }
188} 204}
189 205
@@ -213,6 +229,11 @@ impl BodySourceMap {
213 self.expr_map.get(&src).cloned() 229 self.expr_map.get(&src).cloned()
214 } 230 }
215 231
232 pub fn field_init_shorthand_expr(&self, node: InFile<&ast::RecordField>) -> Option<ExprId> {
233 let src = node.map(|it| Either::Right(AstPtr::new(it)));
234 self.expr_map.get(&src).cloned()
235 }
236
216 pub fn pat_syntax(&self, pat: PatId) -> Option<PatSource> { 237 pub fn pat_syntax(&self, pat: PatId) -> Option<PatSource> {
217 self.pat_map_back.get(pat).copied() 238 self.pat_map_back.get(pat).copied()
218 } 239 }
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 61193b4d8..853e17bae 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,
@@ -466,6 +473,7 @@ where
466 Some(block) => block, 473 Some(block) => block,
467 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr), 474 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr),
468 }; 475 };
476 self.collect_block_items(&block);
469 let statements = block 477 let statements = block
470 .statements() 478 .statements()
471 .map(|s| match s { 479 .map(|s| match s {
@@ -482,6 +490,51 @@ where
482 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) 490 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr)
483 } 491 }
484 492
493 fn collect_block_items(&mut self, block: &ast::Block) {
494 let container = ContainerId::DefWithBodyId(self.def);
495 for item in block.items() {
496 let def: ModuleDefId = match item {
497 ast::ModuleItem::FnDef(def) => {
498 let ast_id = self.expander.ast_id(&def);
499 FunctionLoc { container: container.into(), ast_id }.intern(self.db).into()
500 }
501 ast::ModuleItem::TypeAliasDef(def) => {
502 let ast_id = self.expander.ast_id(&def);
503 TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into()
504 }
505 ast::ModuleItem::ConstDef(def) => {
506 let ast_id = self.expander.ast_id(&def);
507 ConstLoc { container: container.into(), ast_id }.intern(self.db).into()
508 }
509 ast::ModuleItem::StaticDef(def) => {
510 let ast_id = self.expander.ast_id(&def);
511 StaticLoc { container, ast_id }.intern(self.db).into()
512 }
513 ast::ModuleItem::StructDef(def) => {
514 let ast_id = self.expander.ast_id(&def);
515 StructLoc { container, ast_id }.intern(self.db).into()
516 }
517 ast::ModuleItem::EnumDef(def) => {
518 let ast_id = self.expander.ast_id(&def);
519 EnumLoc { container, ast_id }.intern(self.db).into()
520 }
521 ast::ModuleItem::UnionDef(def) => {
522 let ast_id = self.expander.ast_id(&def);
523 UnionLoc { container, ast_id }.intern(self.db).into()
524 }
525 ast::ModuleItem::TraitDef(def) => {
526 let ast_id = self.expander.ast_id(&def);
527 TraitLoc { container, ast_id }.intern(self.db).into()
528 }
529 ast::ModuleItem::ImplBlock(_)
530 | ast::ModuleItem::UseItem(_)
531 | ast::ModuleItem::ExternCrateItem(_)
532 | ast::ModuleItem::Module(_) => continue,
533 };
534 self.body.defs.push(def)
535 }
536 }
537
485 fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId { 538 fn collect_block_opt(&mut self, expr: Option<ast::BlockExpr>) -> ExprId {
486 if let Some(block) = expr { 539 if let Some(block) = expr {
487 self.collect_block(block) 540 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..f5a65ad40 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,47 +76,11 @@ 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));
82
83 for &impl_ in module_data.impls.iter() {
120 let src = impl_.lookup(db).source(db); 84 let src = impl_.lookup(db).source(db);
121 res[keys::IMPL].insert(src, impl_) 85 res[keys::IMPL].insert(src, impl_)
122 } 86 }
@@ -125,6 +89,46 @@ impl ChildBySource for ModuleId {
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..14e86936b 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -12,8 +12,8 @@ use 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, FunctionId, FunctionLoc, ImplId, Intern,
16 StaticId, TraitId, TypeAliasId, TypeAliasLoc, 16 Lookup, 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()
@@ -180,7 +180,7 @@ impl ImplData {
180 .map(|item_node| match item_node { 180 .map(|item_node| match item_node {
181 ast::ImplItem::FnDef(it) => { 181 ast::ImplItem::FnDef(it) => {
182 let def = FunctionLoc { 182 let def = FunctionLoc {
183 container: ContainerId::ImplId(id), 183 container: AssocContainerId::ImplId(id),
184 ast_id: AstId::new(src.file_id, items.ast_id(&it)), 184 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
185 } 185 }
186 .intern(db); 186 .intern(db);
@@ -188,7 +188,7 @@ impl ImplData {
188 } 188 }
189 ast::ImplItem::ConstDef(it) => { 189 ast::ImplItem::ConstDef(it) => {
190 let def = ConstLoc { 190 let def = ConstLoc {
191 container: ContainerId::ImplId(id), 191 container: AssocContainerId::ImplId(id),
192 ast_id: AstId::new(src.file_id, items.ast_id(&it)), 192 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
193 } 193 }
194 .intern(db); 194 .intern(db);
@@ -196,7 +196,7 @@ impl ImplData {
196 } 196 }
197 ast::ImplItem::TypeAliasDef(it) => { 197 ast::ImplItem::TypeAliasDef(it) => {
198 let def = TypeAliasLoc { 198 let def = TypeAliasLoc {
199 container: ContainerId::ImplId(id), 199 container: AssocContainerId::ImplId(id),
200 ast_id: AstId::new(src.file_id, items.ast_id(&it)), 200 ast_id: AstId::new(src.file_id, items.ast_id(&it)),
201 } 201 }
202 .intern(db); 202 .intern(db);
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index f085bbe87..8ed1599ff 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -45,7 +45,7 @@ use std::hash::Hash;
45use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId}; 45use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId};
46use ra_arena::{impl_arena_id, RawId}; 46use ra_arena::{impl_arena_id, RawId};
47use ra_db::{impl_intern_key, salsa, CrateId}; 47use ra_db::{impl_intern_key, salsa, CrateId};
48use ra_syntax::ast; 48use ra_syntax::{ast, AstNode};
49 49
50use crate::builtin_type::BuiltinType; 50use crate::builtin_type::BuiltinType;
51 51
@@ -65,101 +65,57 @@ pub struct ModuleId {
65pub struct LocalModuleId(RawId); 65pub struct LocalModuleId(RawId);
66impl_arena_id!(LocalModuleId); 66impl_arena_id!(LocalModuleId);
67 67
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)] 68#[derive(Debug, Clone, PartialEq, Eq, Hash)]
73pub struct FunctionLoc { 69pub struct ItemLoc<N: AstNode> {
74 pub container: ContainerId, 70 pub container: ContainerId,
75 pub ast_id: AstId<ast::FnDef>, 71 pub ast_id: AstId<N>,
76} 72}
77 73
78impl Intern for FunctionLoc { 74#[derive(Debug, Clone, PartialEq, Eq, Hash)]
79 type ID = FunctionId; 75pub struct AssocItemLoc<N: AstNode> {
80 fn intern(self, db: &impl db::DefDatabase) -> FunctionId { 76 pub container: AssocContainerId,
81 db.intern_function(self) 77 pub ast_id: AstId<N>,
82 }
83} 78}
84 79
85impl Lookup for FunctionId { 80macro_rules! impl_intern {
86 type Data = FunctionLoc; 81 ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => {
87 fn lookup(&self, db: &impl db::DefDatabase) -> FunctionLoc { 82 impl_intern_key!($id);
88 db.lookup_intern_function(*self)
89 }
90}
91 83
92#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 84 impl Intern for $loc {
93pub struct StructId(salsa::InternId); 85 type ID = $id;
94impl_intern_key!(StructId); 86 fn intern(self, db: &impl db::DefDatabase) -> $id {
87 db.$intern(self)
88 }
89 }
95 90
96#[derive(Debug, Clone, PartialEq, Eq, Hash)] 91 impl Lookup for $id {
97pub struct StructLoc { 92 type Data = $loc;
98 pub container: ModuleId, 93 fn lookup(&self, db: &impl db::DefDatabase) -> $loc {
99 pub ast_id: AstId<ast::StructDef>, 94 db.$lookup(*self)
95 }
96 }
97 };
100} 98}
101 99
102impl Intern for StructLoc { 100#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
103 type ID = StructId; 101pub struct FunctionId(salsa::InternId);
104 fn intern(self, db: &impl db::DefDatabase) -> StructId { 102type FunctionLoc = AssocItemLoc<ast::FnDef>;
105 db.intern_struct(self) 103impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function);
106 }
107}
108 104
109impl Lookup for StructId { 105#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
110 type Data = StructLoc; 106pub struct StructId(salsa::InternId);
111 fn lookup(&self, db: &impl db::DefDatabase) -> StructLoc { 107type StructLoc = ItemLoc<ast::StructDef>;
112 db.lookup_intern_struct(*self) 108impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct);
113 }
114}
115 109
116#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 110#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
117pub struct UnionId(salsa::InternId); 111pub struct UnionId(salsa::InternId);
118impl_intern_key!(UnionId); 112pub type UnionLoc = ItemLoc<ast::UnionDef>;
119 113impl_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 114
140#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 115#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
141pub struct EnumId(salsa::InternId); 116pub struct EnumId(salsa::InternId);
142impl_intern_key!(EnumId); 117pub type EnumLoc = ItemLoc<ast::EnumDef>;
143 118impl_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 119
164// FIXME: rename to `VariantId`, only enums can ave variants 120// FIXME: rename to `VariantId`, only enums can ave variants
165#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 121#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -184,122 +140,38 @@ impl_arena_id!(LocalStructFieldId);
184 140
185#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 141#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
186pub struct ConstId(salsa::InternId); 142pub struct ConstId(salsa::InternId);
187impl_intern_key!(ConstId); 143type ConstLoc = AssocItemLoc<ast::ConstDef>;
188#[derive(Debug, Clone, PartialEq, Eq, Hash)] 144impl_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 145
208#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 146#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
209pub struct StaticId(salsa::InternId); 147pub struct StaticId(salsa::InternId);
210impl_intern_key!(StaticId); 148pub type StaticLoc = ItemLoc<ast::StaticDef>;
211 149impl_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 150
232#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 151#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
233pub struct TraitId(salsa::InternId); 152pub struct TraitId(salsa::InternId);
234impl_intern_key!(TraitId); 153pub type TraitLoc = ItemLoc<ast::TraitDef>;
235 154impl_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 155
256#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 156#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
257pub struct TypeAliasId(salsa::InternId); 157pub struct TypeAliasId(salsa::InternId);
258impl_intern_key!(TypeAliasId); 158type TypeAliasLoc = AssocItemLoc<ast::TypeAliasDef>;
259 159impl_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 160
280#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 161#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
281pub struct ImplId(salsa::InternId); 162pub struct ImplId(salsa::InternId);
282impl_intern_key!(ImplId); 163type ImplLoc = ItemLoc<ast::ImplBlock>;
283 164impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl);
284#[derive(Debug, Clone, PartialEq, Eq, Hash)]
285pub struct ImplLoc {
286 pub container: ModuleId,
287 pub ast_id: AstId<ast::ImplBlock>,
288}
289 165
290impl Intern for ImplLoc { 166#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
291 type ID = ImplId; 167pub struct TypeParamId {
292 fn intern(self, db: &impl db::DefDatabase) -> ImplId { 168 pub parent: GenericDefId,
293 db.intern_impl(self) 169 pub local_id: LocalTypeParamId,
294 }
295} 170}
296 171
297impl Lookup for ImplId { 172#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
298 type Data = ImplLoc; 173pub struct LocalTypeParamId(RawId);
299 fn lookup(&self, db: &impl db::DefDatabase) -> ImplLoc { 174impl_arena_id!(LocalTypeParamId);
300 db.lookup_intern_impl(*self)
301 }
302}
303 175
304macro_rules! impl_froms { 176macro_rules! impl_froms {
305 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => { 177 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
@@ -321,21 +193,18 @@ macro_rules! impl_froms {
321} 193}
322 194
323#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 195#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
324pub struct TypeParamId { 196pub enum ContainerId {
325 pub parent: GenericDefId, 197 ModuleId(ModuleId),
326 pub local_id: LocalTypeParamId, 198 DefWithBodyId(DefWithBodyId),
327} 199}
328 200
329#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 201#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
330pub struct LocalTypeParamId(RawId); 202pub enum AssocContainerId {
331impl_arena_id!(LocalTypeParamId); 203 ContainerId(ContainerId),
332
333#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
334pub enum ContainerId {
335 ModuleId(ModuleId),
336 ImplId(ImplId), 204 ImplId(ImplId),
337 TraitId(TraitId), 205 TraitId(TraitId),
338} 206}
207impl_froms!(AssocContainerId: ContainerId);
339 208
340/// A Data Type 209/// A Data Type
341#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 210#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@@ -478,33 +347,28 @@ pub trait HasModule {
478 fn module(&self, db: &impl db::DefDatabase) -> ModuleId; 347 fn module(&self, db: &impl db::DefDatabase) -> ModuleId;
479} 348}
480 349
481impl HasModule for FunctionLoc { 350impl HasModule for ContainerId {
482 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 351 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
483 match self.container { 352 match *self {
484 ContainerId::ModuleId(it) => it, 353 ContainerId::ModuleId(it) => it,
485 ContainerId::ImplId(it) => it.lookup(db).container, 354 ContainerId::DefWithBodyId(it) => it.module(db),
486 ContainerId::TraitId(it) => it.lookup(db).container,
487 } 355 }
488 } 356 }
489} 357}
490 358
491impl HasModule for TypeAliasLoc { 359impl HasModule for AssocContainerId {
492 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 360 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
493 match self.container { 361 match *self {
494 ContainerId::ModuleId(it) => it, 362 AssocContainerId::ContainerId(it) => it.module(db),
495 ContainerId::ImplId(it) => it.lookup(db).container, 363 AssocContainerId::ImplId(it) => it.lookup(db).container.module(db),
496 ContainerId::TraitId(it) => it.lookup(db).container, 364 AssocContainerId::TraitId(it) => it.lookup(db).container.module(db),
497 } 365 }
498 } 366 }
499} 367}
500 368
501impl HasModule for ConstLoc { 369impl<N: AstNode> HasModule for AssocItemLoc<N> {
502 fn module(&self, db: &impl db::DefDatabase) -> ModuleId { 370 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
503 match self.container { 371 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 } 372 }
509} 373}
510 374
@@ -515,6 +379,7 @@ impl HasModule for AdtId {
515 AdtId::UnionId(it) => it.lookup(db).container, 379 AdtId::UnionId(it) => it.lookup(db).container,
516 AdtId::EnumId(it) => it.lookup(db).container, 380 AdtId::EnumId(it) => it.lookup(db).container,
517 } 381 }
382 .module(db)
518 } 383 }
519} 384}
520 385
@@ -533,17 +398,17 @@ impl HasModule for GenericDefId {
533 match self { 398 match self {
534 GenericDefId::FunctionId(it) => it.lookup(db).module(db), 399 GenericDefId::FunctionId(it) => it.lookup(db).module(db),
535 GenericDefId::AdtId(it) => it.module(db), 400 GenericDefId::AdtId(it) => it.module(db),
536 GenericDefId::TraitId(it) => it.lookup(db).container, 401 GenericDefId::TraitId(it) => it.lookup(db).container.module(db),
537 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), 402 GenericDefId::TypeAliasId(it) => it.lookup(db).module(db),
538 GenericDefId::ImplId(it) => it.lookup(db).container, 403 GenericDefId::ImplId(it) => it.lookup(db).container.module(db),
539 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container, 404 GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db),
540 GenericDefId::ConstId(it) => it.lookup(db).module(db), 405 GenericDefId::ConstId(it) => it.lookup(db).module(db),
541 } 406 }
542 } 407 }
543} 408}
544 409
545impl HasModule for StaticLoc { 410impl HasModule for StaticLoc {
546 fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { 411 fn module(&self, db: &impl db::DefDatabase) -> ModuleId {
547 self.container 412 self.container.module(db)
548 } 413 }
549} 414}
diff --git a/crates/ra_hir_def/src/marks.rs b/crates/ra_hir_def/src/marks.rs
index 65239ca0a..457ba4abe 100644
--- a/crates/ra_hir_def/src/marks.rs
+++ b/crates/ra_hir_def/src/marks.rs
@@ -5,6 +5,7 @@ test_utils::marks!(
5 name_res_works_for_broken_modules 5 name_res_works_for_broken_modules
6 can_import_enum_variant 6 can_import_enum_variant
7 glob_enum 7 glob_enum
8 glob_enum_group
8 glob_across_crates 9 glob_across_crates
9 std_prelude 10 std_prelude
10 macro_rules_from_other_crates_are_visible_with_macro_use 11 macro_rules_from_other_crates_are_visible_with_macro_use
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index 9aae7e48e..af52fa36e 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -57,9 +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, MacroDefId};
61 ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId,
62};
63use once_cell::sync::Lazy; 61use once_cell::sync::Lazy;
64use ra_arena::Arena; 62use ra_arena::Arena;
65use ra_db::{CrateId, Edition, FileId, FilePosition}; 63use ra_db::{CrateId, Edition, FileId, FilePosition};
@@ -76,7 +74,7 @@ use crate::{
76 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, 74 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode},
77 path::ModPath, 75 path::ModPath,
78 per_ns::PerNs, 76 per_ns::PerNs,
79 AstId, FunctionId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId, 77 AstId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId,
80}; 78};
81 79
82/// Contains all top-level defs from a macro-expanded crate 80/// Contains all top-level defs from a macro-expanded crate
@@ -176,11 +174,6 @@ pub struct ModuleData {
176 pub impls: Vec<ImplId>, 174 pub impls: Vec<ImplId>,
177} 175}
178 176
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)] 177#[derive(Debug, Default, PartialEq, Eq)]
185pub struct ModuleScope { 178pub struct ModuleScope {
186 items: FxHashMap<Name, Resolution>, 179 items: FxHashMap<Name, Resolution>,
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 8bbf7ffa2..e68bf4868 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -661,9 +661,10 @@ where
661 krate: self.def_collector.def_map.krate, 661 krate: self.def_collector.def_map.krate,
662 local_id: self.module_id, 662 local_id: self.module_id,
663 }; 663 };
664 let container = ContainerId::ModuleId(module);
664 let ast_id = self.raw_items[imp].ast_id; 665 let ast_id = self.raw_items[imp].ast_id;
665 let impl_id = 666 let impl_id =
666 ImplLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 667 ImplLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
667 .intern(self.def_collector.db); 668 .intern(self.def_collector.db);
668 self.def_collector.def_map.modules[self.module_id].impls.push(impl_id) 669 self.def_collector.def_map.modules[self.module_id].impls.push(impl_id)
669 } 670 }
@@ -760,10 +761,11 @@ where
760 self.collect_derives(attrs, def); 761 self.collect_derives(attrs, def);
761 762
762 let name = def.name.clone(); 763 let name = def.name.clone();
764 let container = ContainerId::ModuleId(module);
763 let def: PerNs = match def.kind { 765 let def: PerNs = match def.kind {
764 raw::DefKind::Function(ast_id) => { 766 raw::DefKind::Function(ast_id) => {
765 let def = FunctionLoc { 767 let def = FunctionLoc {
766 container: ContainerId::ModuleId(module), 768 container: container.into(),
767 ast_id: AstId::new(self.file_id, ast_id), 769 ast_id: AstId::new(self.file_id, ast_id),
768 } 770 }
769 .intern(self.def_collector.db); 771 .intern(self.def_collector.db);
@@ -771,23 +773,23 @@ where
771 PerNs::values(def.into()) 773 PerNs::values(def.into())
772 } 774 }
773 raw::DefKind::Struct(ast_id) => { 775 raw::DefKind::Struct(ast_id) => {
774 let def = StructLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 776 let def = StructLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
775 .intern(self.def_collector.db); 777 .intern(self.def_collector.db);
776 PerNs::both(def.into(), def.into()) 778 PerNs::both(def.into(), def.into())
777 } 779 }
778 raw::DefKind::Union(ast_id) => { 780 raw::DefKind::Union(ast_id) => {
779 let def = UnionLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 781 let def = UnionLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
780 .intern(self.def_collector.db); 782 .intern(self.def_collector.db);
781 PerNs::both(def.into(), def.into()) 783 PerNs::both(def.into(), def.into())
782 } 784 }
783 raw::DefKind::Enum(ast_id) => { 785 raw::DefKind::Enum(ast_id) => {
784 let def = EnumLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 786 let def = EnumLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
785 .intern(self.def_collector.db); 787 .intern(self.def_collector.db);
786 PerNs::types(def.into()) 788 PerNs::types(def.into())
787 } 789 }
788 raw::DefKind::Const(ast_id) => { 790 raw::DefKind::Const(ast_id) => {
789 let def = ConstLoc { 791 let def = ConstLoc {
790 container: ContainerId::ModuleId(module), 792 container: container.into(),
791 ast_id: AstId::new(self.file_id, ast_id), 793 ast_id: AstId::new(self.file_id, ast_id),
792 } 794 }
793 .intern(self.def_collector.db); 795 .intern(self.def_collector.db);
@@ -795,20 +797,20 @@ where
795 PerNs::values(def.into()) 797 PerNs::values(def.into())
796 } 798 }
797 raw::DefKind::Static(ast_id) => { 799 raw::DefKind::Static(ast_id) => {
798 let def = StaticLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 800 let def = StaticLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
799 .intern(self.def_collector.db); 801 .intern(self.def_collector.db);
800 802
801 PerNs::values(def.into()) 803 PerNs::values(def.into())
802 } 804 }
803 raw::DefKind::Trait(ast_id) => { 805 raw::DefKind::Trait(ast_id) => {
804 let def = TraitLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } 806 let def = TraitLoc { container, ast_id: AstId::new(self.file_id, ast_id) }
805 .intern(self.def_collector.db); 807 .intern(self.def_collector.db);
806 808
807 PerNs::types(def.into()) 809 PerNs::types(def.into())
808 } 810 }
809 raw::DefKind::TypeAlias(ast_id) => { 811 raw::DefKind::TypeAlias(ast_id) => {
810 let def = TypeAliasLoc { 812 let def = TypeAliasLoc {
811 container: ContainerId::ModuleId(module), 813 container: container.into(),
812 ast_id: AstId::new(self.file_id, ast_id), 814 ast_id: AstId::new(self.file_id, ast_id),
813 } 815 }
814 .intern(self.def_collector.db); 816 .intern(self.def_collector.db);
diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs
index 1dbc4f371..2dd779b66 100644
--- a/crates/ra_hir_def/src/nameres/path_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/path_resolution.rs
@@ -145,11 +145,6 @@ impl CrateDefMap {
145 return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude 145 return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude
146 } 146 }
147 } 147 }
148 PathKind::Type(_) => {
149 // This is handled in `infer::infer_path_expr`
150 // The result returned here does not matter
151 return ResolvePathResult::empty(ReachedFixedPoint::Yes);
152 }
153 }; 148 };
154 149
155 for (i, segment) in segments { 150 for (i, segment) in segments {
diff --git a/crates/ra_hir_def/src/nameres/tests/globs.rs b/crates/ra_hir_def/src/nameres/tests/globs.rs
index 5b03fe365..5e24cb94d 100644
--- a/crates/ra_hir_def/src/nameres/tests/globs.rs
+++ b/crates/ra_hir_def/src/nameres/tests/globs.rs
@@ -112,3 +112,24 @@ fn glob_enum() {
112 "### 112 "###
113 ); 113 );
114} 114}
115
116#[test]
117fn glob_enum_group() {
118 covers!(glob_enum_group);
119 let map = def_map(
120 "
121 //- /lib.rs
122 enum Foo {
123 Bar, Baz
124 }
125 use self::Foo::{*};
126 ",
127 );
128 assert_snapshot!(map, @r###"
129 â‹®crate
130 â‹®Bar: t v
131 â‹®Baz: t v
132 â‹®Foo: t
133 "###
134 );
135}
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index 9e37ac416..00325cd99 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -18,6 +18,18 @@ pub struct ModPath {
18 pub segments: Vec<Name>, 18 pub segments: Vec<Name>,
19} 19}
20 20
21#[derive(Debug, Clone, PartialEq, Eq, Hash)]
22pub enum PathKind {
23 Plain,
24 /// `self::` is `Super(0)`
25 Super(u8),
26 Crate,
27 /// Absolute path (::foo)
28 Abs,
29 /// `$crate` from macro expansion
30 DollarCrate(CrateId),
31}
32
21impl ModPath { 33impl ModPath {
22 pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option<ModPath> { 34 pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option<ModPath> {
23 lower::lower_path(path, hygiene).map(|it| it.mod_path) 35 lower::lower_path(path, hygiene).map(|it| it.mod_path)
@@ -70,6 +82,9 @@ impl ModPath {
70 82
71#[derive(Debug, Clone, PartialEq, Eq, Hash)] 83#[derive(Debug, Clone, PartialEq, Eq, Hash)]
72pub struct Path { 84pub struct Path {
85 /// Type based path like `<T>::foo`.
86 /// Note that paths like `<Type as Trait>::foo` are desugard to `Trait::<Self=Type>::foo`.
87 type_anchor: Option<Box<TypeRef>>,
73 mod_path: ModPath, 88 mod_path: ModPath,
74 /// Invariant: the same len as self.path.segments 89 /// Invariant: the same len as self.path.segments
75 generic_args: Vec<Option<Arc<GenericArgs>>>, 90 generic_args: Vec<Option<Arc<GenericArgs>>>,
@@ -97,19 +112,6 @@ pub enum GenericArg {
97 // or lifetime... 112 // or lifetime...
98} 113}
99 114
100#[derive(Debug, Clone, PartialEq, Eq, Hash)]
101pub enum PathKind {
102 Plain,
103 Super(u8),
104 Crate,
105 // Absolute path
106 Abs,
107 // Type based path like `<T>::foo`
108 Type(Box<TypeRef>),
109 // `$crate` from macro expansion
110 DollarCrate(CrateId),
111}
112
113impl Path { 115impl Path {
114 /// Converts an `ast::Path` to `Path`. Works with use trees. 116 /// Converts an `ast::Path` to `Path`. Works with use trees.
115 /// DEPRECATED: It does not handle `$crate` from macro call. 117 /// DEPRECATED: It does not handle `$crate` from macro call.
@@ -125,18 +127,17 @@ impl Path {
125 127
126 /// Converts an `ast::NameRef` into a single-identifier `Path`. 128 /// Converts an `ast::NameRef` into a single-identifier `Path`.
127 pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> Path { 129 pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> Path {
128 Path { mod_path: name_ref.as_name().into(), generic_args: vec![None] } 130 Path { type_anchor: None, mod_path: name_ref.as_name().into(), generic_args: vec![None] }
129 }
130
131 /// `true` if this path is just a standalone `self`
132 pub fn is_self(&self) -> bool {
133 self.mod_path.is_self()
134 } 131 }
135 132
136 pub fn kind(&self) -> &PathKind { 133 pub fn kind(&self) -> &PathKind {
137 &self.mod_path.kind 134 &self.mod_path.kind
138 } 135 }
139 136
137 pub fn type_anchor(&self) -> Option<&TypeRef> {
138 self.type_anchor.as_ref().map(|it| &**it)
139 }
140
140 pub fn segments(&self) -> PathSegments<'_> { 141 pub fn segments(&self) -> PathSegments<'_> {
141 PathSegments { 142 PathSegments {
142 segments: self.mod_path.segments.as_slice(), 143 segments: self.mod_path.segments.as_slice(),
@@ -153,6 +154,7 @@ impl Path {
153 return None; 154 return None;
154 } 155 }
155 let res = Path { 156 let res = Path {
157 type_anchor: self.type_anchor.clone(),
156 mod_path: ModPath { 158 mod_path: ModPath {
157 kind: self.mod_path.kind.clone(), 159 kind: self.mod_path.kind.clone(),
158 segments: self.mod_path.segments[..self.mod_path.segments.len() - 1].to_vec(), 160 segments: self.mod_path.segments[..self.mod_path.segments.len() - 1].to_vec(),
@@ -225,6 +227,7 @@ impl GenericArgs {
225impl From<Name> for Path { 227impl From<Name> for Path {
226 fn from(name: Name) -> Path { 228 fn from(name: Name) -> Path {
227 Path { 229 Path {
230 type_anchor: None,
228 mod_path: ModPath::from_simple_segments(PathKind::Plain, iter::once(name)), 231 mod_path: ModPath::from_simple_segments(PathKind::Plain, iter::once(name)),
229 generic_args: vec![None], 232 generic_args: vec![None],
230 } 233 }
diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs
index c71b52d89..62aafd508 100644
--- a/crates/ra_hir_def/src/path/lower.rs
+++ b/crates/ra_hir_def/src/path/lower.rs
@@ -22,6 +22,7 @@ pub(super) use lower_use::lower_use_tree;
22/// It correctly handles `$crate` based path from macro call. 22/// It correctly handles `$crate` based path from macro call.
23pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> { 23pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> {
24 let mut kind = PathKind::Plain; 24 let mut kind = PathKind::Plain;
25 let mut type_anchor = None;
25 let mut segments = Vec::new(); 26 let mut segments = Vec::new();
26 let mut generic_args = Vec::new(); 27 let mut generic_args = Vec::new();
27 loop { 28 loop {
@@ -63,7 +64,8 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
63 match trait_ref { 64 match trait_ref {
64 // <T>::foo 65 // <T>::foo
65 None => { 66 None => {
66 kind = PathKind::Type(Box::new(self_type)); 67 type_anchor = Some(Box::new(self_type));
68 kind = PathKind::Plain;
67 } 69 }
68 // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo 70 // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo
69 Some(trait_ref) => { 71 Some(trait_ref) => {
@@ -111,7 +113,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
111 segments.reverse(); 113 segments.reverse();
112 generic_args.reverse(); 114 generic_args.reverse();
113 let mod_path = ModPath { kind, segments }; 115 let mod_path = ModPath { kind, segments };
114 return Some(Path { mod_path, generic_args }); 116 return Some(Path { type_anchor, mod_path, generic_args });
115 117
116 fn qualifier(path: &ast::Path) -> Option<ast::Path> { 118 fn qualifier(path: &ast::Path) -> Option<ast::Path> {
117 if let Some(q) = path.qualifier() { 119 if let Some(q) = path.qualifier() {
diff --git a/crates/ra_hir_def/src/path/lower/lower_use.rs b/crates/ra_hir_def/src/path/lower/lower_use.rs
index 062c02063..3218eaf0a 100644
--- a/crates/ra_hir_def/src/path/lower/lower_use.rs
+++ b/crates/ra_hir_def/src/path/lower/lower_use.rs
@@ -9,6 +9,7 @@ use hir_expand::{
9 name::{AsName, Name}, 9 name::{AsName, Name},
10}; 10};
11use ra_syntax::ast::{self, NameOwner}; 11use ra_syntax::ast::{self, NameOwner};
12use test_utils::tested_by;
12 13
13use crate::path::{ModPath, PathKind}; 14use crate::path::{ModPath, PathKind};
14 15
@@ -34,6 +35,7 @@ pub(crate) fn lower_use_tree(
34 } 35 }
35 } else { 36 } else {
36 let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name()); 37 let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name());
38 let is_glob = tree.has_star();
37 if let Some(ast_path) = tree.path() { 39 if let Some(ast_path) = tree.path() {
38 // Handle self in a path. 40 // Handle self in a path.
39 // E.g. `use something::{self, <...>}` 41 // E.g. `use something::{self, <...>}`
@@ -48,11 +50,15 @@ pub(crate) fn lower_use_tree(
48 } 50 }
49 } 51 }
50 if let Some(path) = convert_path(prefix, ast_path, hygiene) { 52 if let Some(path) = convert_path(prefix, ast_path, hygiene) {
51 let is_glob = tree.has_star();
52 cb(path, &tree, is_glob, alias) 53 cb(path, &tree, is_glob, alias)
53 } 54 }
54 // FIXME: report errors somewhere 55 // FIXME: report errors somewhere
55 // We get here if we do 56 // We get here if we do
57 } else if is_glob {
58 tested_by!(glob_enum_group);
59 if let Some(prefix) = prefix {
60 cb(prefix, &tree, is_glob, None)
61 }
56 } 62 }
57 } 63 }
58} 64}
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 2694c0438..af9d194f8 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -17,9 +17,9 @@ use crate::{
17 nameres::{BuiltinShadowMode, CrateDefMap}, 17 nameres::{BuiltinShadowMode, CrateDefMap},
18 path::{ModPath, PathKind}, 18 path::{ModPath, PathKind},
19 per_ns::PerNs, 19 per_ns::PerNs,
20 AdtId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, 20 AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId,
21 HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, 21 FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId,
22 TypeAliasId, TypeParamId, VariantId, 22 StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId,
23}; 23};
24 24
25#[derive(Debug, Clone, Default)] 25#[derive(Debug, Clone, Default)]
@@ -583,9 +583,18 @@ impl HasResolver for DefWithBodyId {
583impl HasResolver for ContainerId { 583impl HasResolver for ContainerId {
584 fn resolver(self, db: &impl DefDatabase) -> Resolver { 584 fn resolver(self, db: &impl DefDatabase) -> Resolver {
585 match self { 585 match self {
586 ContainerId::TraitId(it) => it.resolver(db),
587 ContainerId::ImplId(it) => it.resolver(db),
588 ContainerId::ModuleId(it) => it.resolver(db), 586 ContainerId::ModuleId(it) => it.resolver(db),
587 ContainerId::DefWithBodyId(it) => it.resolver(db),
588 }
589 }
590}
591
592impl HasResolver for AssocContainerId {
593 fn resolver(self, db: &impl DefDatabase) -> Resolver {
594 match self {
595 AssocContainerId::ContainerId(it) => it.resolver(db),
596 AssocContainerId::TraitId(it) => it.resolver(db),
597 AssocContainerId::ImplId(it) => it.resolver(db),
589 } 598 }
590 } 599 }
591} 600}
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 }