diff options
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 63 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 57 | ||||
-rw-r--r-- | crates/ra_hir_def/src/child_by_source.rs | 97 | ||||
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 283 | ||||
-rw-r--r-- | crates/ra_hir_def/src/marks.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/path_resolution.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests/globs.rs | 21 | ||||
-rw-r--r-- | crates/ra_hir_def/src/path.rs | 41 | ||||
-rw-r--r-- | crates/ra_hir_def/src/path/lower.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_def/src/path/lower/lower_use.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir_def/src/resolver.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir_def/src/src.rs | 82 |
15 files changed, 324 insertions, 406 deletions
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 @@ | |||
3 | mod lower; | 3 | mod lower; |
4 | pub mod scope; | 4 | pub mod scope; |
5 | 5 | ||
6 | use std::{ops::Index, sync::Arc}; | 6 | use std::{mem, ops::Index, sync::Arc}; |
7 | 7 | ||
8 | use drop_bomb::DropBomb; | ||
8 | use either::Either; | 9 | use either::Either; |
9 | use hir_expand::{hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId}; | 10 | use hir_expand::{ |
11 | ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId, | ||
12 | }; | ||
10 | use ra_arena::{map::ArenaMap, Arena}; | 13 | use ra_arena::{map::ArenaMap, Arena}; |
11 | use ra_syntax::{ast, AstNode, AstPtr}; | 14 | use ra_syntax::{ast, AstNode, AstPtr}; |
12 | use rustc_hash::FxHashMap; | 15 | use 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 | ||
23 | struct Expander { | 26 | struct 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(¯o_call), | 49 | db.ast_id_map(self.current_file_id).ast_id(¯o_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 | ||
92 | struct Mark { | 112 | struct Mark { |
93 | file_id: HirFileId, | 113 | file_id: HirFileId, |
94 | } | 114 | ast_id_map: Arc<AstIdMap>, |
95 | 115 | bomb: DropBomb, | |
96 | impl 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 | ||
120 | pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>; | 135 | pub 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 | ||
4 | use either::Either; | 4 | use either::Either; |
5 | |||
5 | use hir_expand::name::{name, AsName, Name}; | 6 | use hir_expand::name::{name, AsName, Name}; |
6 | use ra_arena::Arena; | 7 | use ra_arena::Arena; |
7 | use ra_syntax::{ | 8 | use 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 | ||
29 | pub(super) fn lower( | 32 | pub(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 | ||
49 | struct ExprCollector<DB> { | 55 | struct 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 | ||
18 | pub trait ChildBySource { | 18 | pub 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 | ||
92 | fn 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 | |||
128 | impl ChildBySource for VariantId { | 132 | impl 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 | |||
168 | impl 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; | |||
45 | use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId}; | 45 | use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId}; |
46 | use ra_arena::{impl_arena_id, RawId}; | 46 | use ra_arena::{impl_arena_id, RawId}; |
47 | use ra_db::{impl_intern_key, salsa, CrateId}; | 47 | use ra_db::{impl_intern_key, salsa, CrateId}; |
48 | use ra_syntax::ast; | 48 | use ra_syntax::{ast, AstNode}; |
49 | 49 | ||
50 | use crate::builtin_type::BuiltinType; | 50 | use crate::builtin_type::BuiltinType; |
51 | 51 | ||
@@ -65,101 +65,57 @@ pub struct ModuleId { | |||
65 | pub struct LocalModuleId(RawId); | 65 | pub struct LocalModuleId(RawId); |
66 | impl_arena_id!(LocalModuleId); | 66 | impl_arena_id!(LocalModuleId); |
67 | 67 | ||
68 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
69 | pub struct FunctionId(salsa::InternId); | ||
70 | impl_intern_key!(FunctionId); | ||
71 | |||
72 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 68 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
73 | pub struct FunctionLoc { | 69 | pub 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 | ||
78 | impl Intern for FunctionLoc { | 74 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
79 | type ID = FunctionId; | 75 | pub 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 | ||
85 | impl Lookup for FunctionId { | 80 | macro_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 { |
93 | pub struct StructId(salsa::InternId); | 85 | type ID = $id; |
94 | impl_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 { |
97 | pub 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 | ||
102 | impl Intern for StructLoc { | 100 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
103 | type ID = StructId; | 101 | pub struct FunctionId(salsa::InternId); |
104 | fn intern(self, db: &impl db::DefDatabase) -> StructId { | 102 | type FunctionLoc = AssocItemLoc<ast::FnDef>; |
105 | db.intern_struct(self) | 103 | impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function); |
106 | } | ||
107 | } | ||
108 | 104 | ||
109 | impl Lookup for StructId { | 105 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
110 | type Data = StructLoc; | 106 | pub struct StructId(salsa::InternId); |
111 | fn lookup(&self, db: &impl db::DefDatabase) -> StructLoc { | 107 | type StructLoc = ItemLoc<ast::StructDef>; |
112 | db.lookup_intern_struct(*self) | 108 | impl_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)] |
117 | pub struct UnionId(salsa::InternId); | 111 | pub struct UnionId(salsa::InternId); |
118 | impl_intern_key!(UnionId); | 112 | pub type UnionLoc = ItemLoc<ast::UnionDef>; |
119 | 113 | impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union); | |
120 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
121 | pub struct UnionLoc { | ||
122 | pub container: ModuleId, | ||
123 | pub ast_id: AstId<ast::UnionDef>, | ||
124 | } | ||
125 | |||
126 | impl Intern for UnionLoc { | ||
127 | type ID = UnionId; | ||
128 | fn intern(self, db: &impl db::DefDatabase) -> UnionId { | ||
129 | db.intern_union(self) | ||
130 | } | ||
131 | } | ||
132 | |||
133 | impl 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)] |
141 | pub struct EnumId(salsa::InternId); | 116 | pub struct EnumId(salsa::InternId); |
142 | impl_intern_key!(EnumId); | 117 | pub type EnumLoc = ItemLoc<ast::EnumDef>; |
143 | 118 | impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum); | |
144 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
145 | pub struct EnumLoc { | ||
146 | pub container: ModuleId, | ||
147 | pub ast_id: AstId<ast::EnumDef>, | ||
148 | } | ||
149 | |||
150 | impl Intern for EnumLoc { | ||
151 | type ID = EnumId; | ||
152 | fn intern(self, db: &impl db::DefDatabase) -> EnumId { | ||
153 | db.intern_enum(self) | ||
154 | } | ||
155 | } | ||
156 | |||
157 | impl 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)] |
186 | pub struct ConstId(salsa::InternId); | 142 | pub struct ConstId(salsa::InternId); |
187 | impl_intern_key!(ConstId); | 143 | type ConstLoc = AssocItemLoc<ast::ConstDef>; |
188 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 144 | impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const); |
189 | pub struct ConstLoc { | ||
190 | pub container: ContainerId, | ||
191 | pub ast_id: AstId<ast::ConstDef>, | ||
192 | } | ||
193 | |||
194 | impl Intern for ConstLoc { | ||
195 | type ID = ConstId; | ||
196 | fn intern(self, db: &impl db::DefDatabase) -> ConstId { | ||
197 | db.intern_const(self) | ||
198 | } | ||
199 | } | ||
200 | |||
201 | impl 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)] |
209 | pub struct StaticId(salsa::InternId); | 147 | pub struct StaticId(salsa::InternId); |
210 | impl_intern_key!(StaticId); | 148 | pub type StaticLoc = ItemLoc<ast::StaticDef>; |
211 | 149 | impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static); | |
212 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
213 | pub struct StaticLoc { | ||
214 | pub container: ModuleId, | ||
215 | pub ast_id: AstId<ast::StaticDef>, | ||
216 | } | ||
217 | |||
218 | impl Intern for StaticLoc { | ||
219 | type ID = StaticId; | ||
220 | fn intern(self, db: &impl db::DefDatabase) -> StaticId { | ||
221 | db.intern_static(self) | ||
222 | } | ||
223 | } | ||
224 | |||
225 | impl 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)] |
233 | pub struct TraitId(salsa::InternId); | 152 | pub struct TraitId(salsa::InternId); |
234 | impl_intern_key!(TraitId); | 153 | pub type TraitLoc = ItemLoc<ast::TraitDef>; |
235 | 154 | impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait); | |
236 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
237 | pub struct TraitLoc { | ||
238 | pub container: ModuleId, | ||
239 | pub ast_id: AstId<ast::TraitDef>, | ||
240 | } | ||
241 | |||
242 | impl Intern for TraitLoc { | ||
243 | type ID = TraitId; | ||
244 | fn intern(self, db: &impl db::DefDatabase) -> TraitId { | ||
245 | db.intern_trait(self) | ||
246 | } | ||
247 | } | ||
248 | |||
249 | impl 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)] |
257 | pub struct TypeAliasId(salsa::InternId); | 157 | pub struct TypeAliasId(salsa::InternId); |
258 | impl_intern_key!(TypeAliasId); | 158 | type TypeAliasLoc = AssocItemLoc<ast::TypeAliasDef>; |
259 | 159 | impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias); | |
260 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
261 | pub struct TypeAliasLoc { | ||
262 | pub container: ContainerId, | ||
263 | pub ast_id: AstId<ast::TypeAliasDef>, | ||
264 | } | ||
265 | |||
266 | impl 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 | |||
273 | impl 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)] |
281 | pub struct ImplId(salsa::InternId); | 162 | pub struct ImplId(salsa::InternId); |
282 | impl_intern_key!(ImplId); | 163 | type ImplLoc = ItemLoc<ast::ImplBlock>; |
283 | 164 | impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl); | |
284 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
285 | pub struct ImplLoc { | ||
286 | pub container: ModuleId, | ||
287 | pub ast_id: AstId<ast::ImplBlock>, | ||
288 | } | ||
289 | 165 | ||
290 | impl Intern for ImplLoc { | 166 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
291 | type ID = ImplId; | 167 | pub 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 | ||
297 | impl Lookup for ImplId { | 172 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
298 | type Data = ImplLoc; | 173 | pub struct LocalTypeParamId(RawId); |
299 | fn lookup(&self, db: &impl db::DefDatabase) -> ImplLoc { | 174 | impl_arena_id!(LocalTypeParamId); |
300 | db.lookup_intern_impl(*self) | ||
301 | } | ||
302 | } | ||
303 | 175 | ||
304 | macro_rules! impl_froms { | 176 | macro_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)] |
324 | pub struct TypeParamId { | 196 | pub 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)] |
330 | pub struct LocalTypeParamId(RawId); | 202 | pub enum AssocContainerId { |
331 | impl_arena_id!(LocalTypeParamId); | 203 | ContainerId(ContainerId), |
332 | |||
333 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
334 | pub enum ContainerId { | ||
335 | ModuleId(ModuleId), | ||
336 | ImplId(ImplId), | 204 | ImplId(ImplId), |
337 | TraitId(TraitId), | 205 | TraitId(TraitId), |
338 | } | 206 | } |
207 | impl_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 | ||
481 | impl HasModule for FunctionLoc { | 350 | impl 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 | ||
491 | impl HasModule for TypeAliasLoc { | 359 | impl 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 | ||
501 | impl HasModule for ConstLoc { | 369 | impl<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 | ||
545 | impl HasModule for StaticLoc { | 410 | impl 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 | ||
58 | use std::sync::Arc; | 58 | use std::sync::Arc; |
59 | 59 | ||
60 | use hir_expand::{ | 60 | use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId}; |
61 | ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId, | ||
62 | }; | ||
63 | use once_cell::sync::Lazy; | 61 | use once_cell::sync::Lazy; |
64 | use ra_arena::Arena; | 62 | use ra_arena::Arena; |
65 | use ra_db::{CrateId, Edition, FileId, FilePosition}; | 63 | use 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)] | ||
180 | pub(crate) struct Declarations { | ||
181 | fns: FxHashMap<FileAstId<ast::FnDef>, FunctionId>, | ||
182 | } | ||
183 | |||
184 | #[derive(Debug, Default, PartialEq, Eq)] | 177 | #[derive(Debug, Default, PartialEq, Eq)] |
185 | pub struct ModuleScope { | 178 | pub 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] | ||
117 | fn 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)] | ||
22 | pub 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 | |||
21 | impl ModPath { | 33 | impl 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)] |
72 | pub struct Path { | 84 | pub 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)] | ||
101 | pub 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 | |||
113 | impl Path { | 115 | impl 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 { | |||
225 | impl From<Name> for Path { | 227 | impl 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. |
23 | pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> { | 23 | pub(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 | }; |
11 | use ra_syntax::ast::{self, NameOwner}; | 11 | use ra_syntax::ast::{self, NameOwner}; |
12 | use test_utils::tested_by; | ||
12 | 13 | ||
13 | use crate::path::{ModPath, PathKind}; | 14 | use 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 { | |||
583 | impl HasResolver for ContainerId { | 583 | impl 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 | |||
592 | impl 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 | ||
3 | use hir_expand::InFile; | 3 | use hir_expand::InFile; |
4 | use ra_arena::map::ArenaMap; | 4 | use ra_arena::map::ArenaMap; |
5 | use ra_syntax::ast; | 5 | use ra_syntax::AstNode; |
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{db::DefDatabase, AssocItemLoc, ItemLoc}; |
8 | db::DefDatabase, ConstLoc, EnumLoc, FunctionLoc, ImplLoc, StaticLoc, StructLoc, TraitLoc, | ||
9 | TypeAliasLoc, UnionLoc, | ||
10 | }; | ||
11 | 8 | ||
12 | pub trait HasSource { | 9 | pub 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 | ||
17 | impl HasSource for FunctionLoc { | 14 | impl<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 | ||
26 | impl HasSource for TypeAliasLoc { | 23 | impl<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 | |||
35 | impl 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 | |||
44 | impl 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 | |||
53 | impl 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 | |||
62 | impl 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 | |||
71 | impl 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 | |||
80 | impl 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 | |||
89 | impl 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 | } |