aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir_def/src/item_tree.rs136
-rw-r--r--crates/ra_hir_def/src/item_tree/lower.rs40
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs7
3 files changed, 130 insertions, 53 deletions
diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs
index a13a989dd..9656f845e 100644
--- a/crates/ra_hir_def/src/item_tree.rs
+++ b/crates/ra_hir_def/src/item_tree.rs
@@ -3,6 +3,9 @@
3mod lower; 3mod lower;
4 4
5use std::{ 5use std::{
6 fmt::{self, Debug},
7 hash::{Hash, Hasher},
8 marker::PhantomData,
6 ops::{Index, Range}, 9 ops::{Index, Range},
7 sync::Arc, 10 sync::Arc,
8}; 11};
@@ -109,6 +112,68 @@ impl ItemTree {
109 } 112 }
110} 113}
111 114
115pub trait ItemTreeNode: Sized {
116 fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self;
117}
118
119pub struct FileItemTreeId<N: ItemTreeNode> {
120 index: Idx<N>,
121 _p: PhantomData<N>,
122}
123
124impl<N: ItemTreeNode> Clone for FileItemTreeId<N> {
125 fn clone(&self) -> Self {
126 Self { index: self.index, _p: PhantomData }
127 }
128}
129impl<N: ItemTreeNode> Copy for FileItemTreeId<N> {}
130
131impl<N: ItemTreeNode> PartialEq for FileItemTreeId<N> {
132 fn eq(&self, other: &FileItemTreeId<N>) -> bool {
133 self.index == other.index
134 }
135}
136impl<N: ItemTreeNode> Eq for FileItemTreeId<N> {}
137
138impl<N: ItemTreeNode> Hash for FileItemTreeId<N> {
139 fn hash<H: Hasher>(&self, state: &mut H) {
140 self.index.hash(state)
141 }
142}
143
144impl<N: ItemTreeNode> fmt::Debug for FileItemTreeId<N> {
145 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146 self.index.fmt(f)
147 }
148}
149
150pub type ItemTreeId<N> = InFile<FileItemTreeId<N>>;
151
152macro_rules! nodes {
153 ( $($node:ident in $fld:ident),+ $(,)? ) => { $(
154 impl ItemTreeNode for $node {
155 fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self {
156 &tree.$fld[index]
157 }
158 }
159 )+ };
160}
161
162nodes!(
163 Import in imports,
164 Function in functions,
165 Struct in structs,
166 Union in unions,
167 Enum in enums,
168 Const in consts,
169 Static in statics,
170 Trait in traits,
171 Impl in impls,
172 TypeAlias in type_aliases,
173 Mod in mods,
174 MacroCall in macro_calls,
175);
176
112macro_rules! impl_index { 177macro_rules! impl_index {
113 ( $($fld:ident: $t:ty),+ $(,)? ) => { 178 ( $($fld:ident: $t:ty),+ $(,)? ) => {
114 $( 179 $(
@@ -141,6 +206,13 @@ impl_index!(
141 exprs: Expr, 206 exprs: Expr,
142); 207);
143 208
209impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
210 type Output = N;
211 fn index(&self, id: FileItemTreeId<N>) -> &N {
212 N::lookup(self, id.index)
213 }
214}
215
144/// A desugared `extern crate` or `use` import. 216/// A desugared `extern crate` or `use` import.
145#[derive(Debug, Clone, Eq, PartialEq)] 217#[derive(Debug, Clone, Eq, PartialEq)]
146pub struct Import { 218pub struct Import {
@@ -304,48 +376,48 @@ macro_rules! impl_froms {
304 376
305#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 377#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
306pub enum ModItem { 378pub enum ModItem {
307 Import(Idx<Import>), 379 Import(FileItemTreeId<Import>),
308 Function(Idx<Function>), 380 Function(FileItemTreeId<Function>),
309 Struct(Idx<Struct>), 381 Struct(FileItemTreeId<Struct>),
310 Union(Idx<Union>), 382 Union(FileItemTreeId<Union>),
311 Enum(Idx<Enum>), 383 Enum(FileItemTreeId<Enum>),
312 Const(Idx<Const>), 384 Const(FileItemTreeId<Const>),
313 Static(Idx<Static>), 385 Static(FileItemTreeId<Static>),
314 Trait(Idx<Trait>), 386 Trait(FileItemTreeId<Trait>),
315 Impl(Idx<Impl>), 387 Impl(FileItemTreeId<Impl>),
316 TypeAlias(Idx<TypeAlias>), 388 TypeAlias(FileItemTreeId<TypeAlias>),
317 Mod(Idx<Mod>), 389 Mod(FileItemTreeId<Mod>),
318 MacroCall(Idx<MacroCall>), 390 MacroCall(FileItemTreeId<MacroCall>),
319} 391}
320 392
321impl_froms!(ModItem { 393impl_froms!(ModItem {
322 Import(Idx<Import>), 394 Import(FileItemTreeId<Import>),
323 Function(Idx<Function>), 395 Function(FileItemTreeId<Function>),
324 Struct(Idx<Struct>), 396 Struct(FileItemTreeId<Struct>),
325 Union(Idx<Union>), 397 Union(FileItemTreeId<Union>),
326 Enum(Idx<Enum>), 398 Enum(FileItemTreeId<Enum>),
327 Const(Idx<Const>), 399 Const(FileItemTreeId<Const>),
328 Static(Idx<Static>), 400 Static(FileItemTreeId<Static>),
329 Trait(Idx<Trait>), 401 Trait(FileItemTreeId<Trait>),
330 Impl(Idx<Impl>), 402 Impl(FileItemTreeId<Impl>),
331 TypeAlias(Idx<TypeAlias>), 403 TypeAlias(FileItemTreeId<TypeAlias>),
332 Mod(Idx<Mod>), 404 Mod(FileItemTreeId<Mod>),
333 MacroCall(Idx<MacroCall>), 405 MacroCall(FileItemTreeId<MacroCall>),
334}); 406});
335 407
336#[derive(Debug, Eq, PartialEq)] 408#[derive(Debug, Eq, PartialEq)]
337pub enum AssocItem { 409pub enum AssocItem {
338 Function(Idx<Function>), 410 Function(FileItemTreeId<Function>),
339 TypeAlias(Idx<TypeAlias>), 411 TypeAlias(FileItemTreeId<TypeAlias>),
340 Const(Idx<Const>), 412 Const(FileItemTreeId<Const>),
341 MacroCall(Idx<MacroCall>), 413 MacroCall(FileItemTreeId<MacroCall>),
342} 414}
343 415
344impl_froms!(AssocItem { 416impl_froms!(AssocItem {
345 Function(Idx<Function>), 417 Function(FileItemTreeId<Function>),
346 TypeAlias(Idx<TypeAlias>), 418 TypeAlias(FileItemTreeId<TypeAlias>),
347 Const(Idx<Const>), 419 Const(FileItemTreeId<Const>),
348 MacroCall(Idx<MacroCall>), 420 MacroCall(FileItemTreeId<MacroCall>),
349}); 421});
350 422
351#[derive(Debug, Eq, PartialEq)] 423#[derive(Debug, Eq, PartialEq)]
diff --git a/crates/ra_hir_def/src/item_tree/lower.rs b/crates/ra_hir_def/src/item_tree/lower.rs
index d123a7310..0c9454848 100644
--- a/crates/ra_hir_def/src/item_tree/lower.rs
+++ b/crates/ra_hir_def/src/item_tree/lower.rs
@@ -5,6 +5,10 @@ use ra_syntax::ast::{self, ModuleItemOwner};
5use smallvec::SmallVec; 5use smallvec::SmallVec;
6use std::sync::Arc; 6use std::sync::Arc;
7 7
8fn id<N: ItemTreeNode>(index: Idx<N>) -> FileItemTreeId<N> {
9 FileItemTreeId { index, _p: PhantomData }
10}
11
8struct ModItems(SmallVec<[ModItem; 1]>); 12struct ModItems(SmallVec<[ModItem; 1]>);
9 13
10impl<T> From<T> for ModItems 14impl<T> From<T> for ModItems
@@ -38,54 +42,54 @@ impl Ctx {
38 let attrs = Attrs::new(item, &self.hygiene); 42 let attrs = Attrs::new(item, &self.hygiene);
39 let items = match item { 43 let items = match item {
40 ast::ModuleItem::StructDef(ast) => { 44 ast::ModuleItem::StructDef(ast) => {
41 self.lower_struct(ast).map(|data| self.tree.structs.alloc(data).into()) 45 self.lower_struct(ast).map(|data| id(self.tree.structs.alloc(data)).into())
42 } 46 }
43 ast::ModuleItem::UnionDef(ast) => { 47 ast::ModuleItem::UnionDef(ast) => {
44 self.lower_union(ast).map(|data| self.tree.unions.alloc(data).into()) 48 self.lower_union(ast).map(|data| id(self.tree.unions.alloc(data)).into())
45 } 49 }
46 ast::ModuleItem::EnumDef(ast) => { 50 ast::ModuleItem::EnumDef(ast) => {
47 self.lower_enum(ast).map(|data| self.tree.enums.alloc(data).into()) 51 self.lower_enum(ast).map(|data| id(self.tree.enums.alloc(data)).into())
48 } 52 }
49 ast::ModuleItem::FnDef(ast) => { 53 ast::ModuleItem::FnDef(ast) => {
50 self.lower_function(ast).map(|data| self.tree.functions.alloc(data).into()) 54 self.lower_function(ast).map(|data| id(self.tree.functions.alloc(data)).into())
51 } 55 }
52 ast::ModuleItem::TypeAliasDef(ast) => { 56 ast::ModuleItem::TypeAliasDef(ast) => {
53 self.lower_type_alias(ast).map(|data| self.tree.type_aliases.alloc(data).into()) 57 self.lower_type_alias(ast).map(|data| id(self.tree.type_aliases.alloc(data)).into())
54 } 58 }
55 ast::ModuleItem::StaticDef(ast) => { 59 ast::ModuleItem::StaticDef(ast) => {
56 self.lower_static(ast).map(|data| self.tree.statics.alloc(data).into()) 60 self.lower_static(ast).map(|data| id(self.tree.statics.alloc(data)).into())
57 } 61 }
58 ast::ModuleItem::ConstDef(ast) => { 62 ast::ModuleItem::ConstDef(ast) => {
59 let data = self.lower_const(ast); 63 let data = self.lower_const(ast);
60 Some(self.tree.consts.alloc(data).into()) 64 Some(id(self.tree.consts.alloc(data)).into())
61 } 65 }
62 ast::ModuleItem::Module(ast) => { 66 ast::ModuleItem::Module(ast) => {
63 self.lower_module(ast).map(|data| self.tree.mods.alloc(data).into()) 67 self.lower_module(ast).map(|data| id(self.tree.mods.alloc(data)).into())
64 } 68 }
65 ast::ModuleItem::TraitDef(ast) => { 69 ast::ModuleItem::TraitDef(ast) => {
66 self.lower_trait(ast).map(|data| self.tree.traits.alloc(data).into()) 70 self.lower_trait(ast).map(|data| id(self.tree.traits.alloc(data)).into())
67 } 71 }
68 ast::ModuleItem::ImplDef(ast) => { 72 ast::ModuleItem::ImplDef(ast) => {
69 self.lower_impl(ast).map(|data| self.tree.impls.alloc(data).into()) 73 self.lower_impl(ast).map(|data| id(self.tree.impls.alloc(data)).into())
70 } 74 }
71 ast::ModuleItem::UseItem(ast) => Some(ModItems( 75 ast::ModuleItem::UseItem(ast) => Some(ModItems(
72 self.lower_use(ast) 76 self.lower_use(ast)
73 .into_iter() 77 .into_iter()
74 .map(|data| self.tree.imports.alloc(data).into()) 78 .map(|data| id(self.tree.imports.alloc(data)).into())
75 .collect::<SmallVec<_>>(), 79 .collect::<SmallVec<_>>(),
76 )), 80 )),
77 ast::ModuleItem::ExternCrateItem(ast) => { 81 ast::ModuleItem::ExternCrateItem(ast) => {
78 self.lower_extern_crate(ast).map(|data| self.tree.imports.alloc(data).into()) 82 self.lower_extern_crate(ast).map(|data| id(self.tree.imports.alloc(data)).into())
79 } 83 }
80 ast::ModuleItem::MacroCall(ast) => { 84 ast::ModuleItem::MacroCall(ast) => {
81 self.lower_macro_call(ast).map(|data| self.tree.macro_calls.alloc(data).into()) 85 self.lower_macro_call(ast).map(|data| id(self.tree.macro_calls.alloc(data)).into())
82 } 86 }
83 ast::ModuleItem::ExternBlock(ast) => Some(ModItems( 87 ast::ModuleItem::ExternBlock(ast) => Some(ModItems(
84 self.lower_extern_block(ast) 88 self.lower_extern_block(ast)
85 .into_iter() 89 .into_iter()
86 .map(|item| match item { 90 .map(|item| match item {
87 Either::Left(func) => self.tree.functions.alloc(func).into(), 91 Either::Left(func) => id(self.tree.functions.alloc(func)).into(),
88 Either::Right(statik) => self.tree.statics.alloc(statik).into(), 92 Either::Right(statik) => id(self.tree.statics.alloc(statik)).into(),
89 }) 93 })
90 .collect::<SmallVec<_>>(), 94 .collect::<SmallVec<_>>(),
91 )), 95 )),
@@ -103,14 +107,14 @@ impl Ctx {
103 fn lower_assoc_item(&mut self, item: &ast::AssocItem) -> Option<AssocItem> { 107 fn lower_assoc_item(&mut self, item: &ast::AssocItem) -> Option<AssocItem> {
104 match item { 108 match item {
105 ast::AssocItem::FnDef(ast) => { 109 ast::AssocItem::FnDef(ast) => {
106 self.lower_function(ast).map(|data| self.tree.functions.alloc(data).into()) 110 self.lower_function(ast).map(|data| id(self.tree.functions.alloc(data)).into())
107 } 111 }
108 ast::AssocItem::TypeAliasDef(ast) => { 112 ast::AssocItem::TypeAliasDef(ast) => {
109 self.lower_type_alias(ast).map(|data| self.tree.type_aliases.alloc(data).into()) 113 self.lower_type_alias(ast).map(|data| id(self.tree.type_aliases.alloc(data)).into())
110 } 114 }
111 ast::AssocItem::ConstDef(ast) => { 115 ast::AssocItem::ConstDef(ast) => {
112 let data = self.lower_const(ast); 116 let data = self.lower_const(ast);
113 Some(self.tree.consts.alloc(data).into()) 117 Some(id(self.tree.consts.alloc(data)).into())
114 } 118 }
115 } 119 }
116 } 120 }
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index b899a5fb3..c227b6da1 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -20,7 +20,9 @@ use test_utils::mark;
20use crate::{ 20use crate::{
21 attr::Attrs, 21 attr::Attrs,
22 db::DefDatabase, 22 db::DefDatabase,
23 item_tree::{Import, ItemTree, MacroCall, Mod, ModItem, ModKind, StructDefKind}, 23 item_tree::{
24 FileItemTreeId, Import, ItemTree, MacroCall, Mod, ModItem, ModKind, StructDefKind,
25 },
24 nameres::{ 26 nameres::{
25 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 27 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
26 BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode, 28 BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode,
@@ -32,7 +34,6 @@ use crate::{
32 FunctionLoc, ImplLoc, Intern, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, 34 FunctionLoc, ImplLoc, Intern, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc,
33 TraitLoc, TypeAliasLoc, UnionLoc, 35 TraitLoc, TypeAliasLoc, UnionLoc,
34}; 36};
35use ra_arena::Idx;
36 37
37pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { 38pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
38 let crate_graph = db.crate_graph(); 39 let crate_graph = db.crate_graph();
@@ -107,7 +108,7 @@ impl PartialResolvedImport {
107#[derive(Clone, Debug, Eq, PartialEq)] 108#[derive(Clone, Debug, Eq, PartialEq)]
108struct ImportDirective { 109struct ImportDirective {
109 module_id: LocalModuleId, 110 module_id: LocalModuleId,
110 import_id: Idx<Import>, 111 import_id: FileItemTreeId<Import>,
111 import: Import, 112 import: Import,
112 status: PartialResolvedImport, 113 status: PartialResolvedImport,
113} 114}