diff options
-rw-r--r-- | crates/ra_hir_def/src/item_tree.rs | 136 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree/lower.rs | 40 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 7 |
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 @@ | |||
3 | mod lower; | 3 | mod lower; |
4 | 4 | ||
5 | use std::{ | 5 | use 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 | ||
115 | pub trait ItemTreeNode: Sized { | ||
116 | fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self; | ||
117 | } | ||
118 | |||
119 | pub struct FileItemTreeId<N: ItemTreeNode> { | ||
120 | index: Idx<N>, | ||
121 | _p: PhantomData<N>, | ||
122 | } | ||
123 | |||
124 | impl<N: ItemTreeNode> Clone for FileItemTreeId<N> { | ||
125 | fn clone(&self) -> Self { | ||
126 | Self { index: self.index, _p: PhantomData } | ||
127 | } | ||
128 | } | ||
129 | impl<N: ItemTreeNode> Copy for FileItemTreeId<N> {} | ||
130 | |||
131 | impl<N: ItemTreeNode> PartialEq for FileItemTreeId<N> { | ||
132 | fn eq(&self, other: &FileItemTreeId<N>) -> bool { | ||
133 | self.index == other.index | ||
134 | } | ||
135 | } | ||
136 | impl<N: ItemTreeNode> Eq for FileItemTreeId<N> {} | ||
137 | |||
138 | impl<N: ItemTreeNode> Hash for FileItemTreeId<N> { | ||
139 | fn hash<H: Hasher>(&self, state: &mut H) { | ||
140 | self.index.hash(state) | ||
141 | } | ||
142 | } | ||
143 | |||
144 | impl<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 | |||
150 | pub type ItemTreeId<N> = InFile<FileItemTreeId<N>>; | ||
151 | |||
152 | macro_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 | |||
162 | nodes!( | ||
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 | |||
112 | macro_rules! impl_index { | 177 | macro_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 | ||
209 | impl<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)] |
146 | pub struct Import { | 218 | pub 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)] |
306 | pub enum ModItem { | 378 | pub 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 | ||
321 | impl_froms!(ModItem { | 393 | impl_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)] |
337 | pub enum AssocItem { | 409 | pub 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 | ||
344 | impl_froms!(AssocItem { | 416 | impl_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}; | |||
5 | use smallvec::SmallVec; | 5 | use smallvec::SmallVec; |
6 | use std::sync::Arc; | 6 | use std::sync::Arc; |
7 | 7 | ||
8 | fn id<N: ItemTreeNode>(index: Idx<N>) -> FileItemTreeId<N> { | ||
9 | FileItemTreeId { index, _p: PhantomData } | ||
10 | } | ||
11 | |||
8 | struct ModItems(SmallVec<[ModItem; 1]>); | 12 | struct ModItems(SmallVec<[ModItem; 1]>); |
9 | 13 | ||
10 | impl<T> From<T> for ModItems | 14 | impl<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; | |||
20 | use crate::{ | 20 | use 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 | }; |
35 | use ra_arena::Idx; | ||
36 | 37 | ||
37 | pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { | 38 | pub(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)] |
108 | struct ImportDirective { | 109 | struct 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 | } |