diff options
Diffstat (limited to 'crates/hir_def/src/item_tree.rs')
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index ae2475b4e..5449bbf5d 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -31,7 +31,7 @@ use crate::{ | |||
31 | db::DefDatabase, | 31 | db::DefDatabase, |
32 | generics::GenericParams, | 32 | generics::GenericParams, |
33 | path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind}, | 33 | path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind}, |
34 | type_ref::{Mutability, TypeBound, TypeRef}, | 34 | type_ref::{Mutability, TraitRef, TypeBound, TypeRef}, |
35 | visibility::RawVisibility, | 35 | visibility::RawVisibility, |
36 | }; | 36 | }; |
37 | 37 | ||
@@ -110,15 +110,6 @@ impl ItemTree { | |||
110 | // still need to collect inner items. | 110 | // still need to collect inner items. |
111 | ctx.lower_inner_items(e.syntax()) | 111 | ctx.lower_inner_items(e.syntax()) |
112 | }, | 112 | }, |
113 | ast::ExprStmt(stmt) => { | ||
114 | // Macros can expand to stmt. We return an empty item tree in this case, but | ||
115 | // still need to collect inner items. | ||
116 | ctx.lower_inner_items(stmt.syntax()) | ||
117 | }, | ||
118 | ast::Item(item) => { | ||
119 | // Macros can expand to stmt and other item, and we add it as top level item | ||
120 | ctx.lower_single_item(item) | ||
121 | }, | ||
122 | _ => { | 113 | _ => { |
123 | panic!("cannot create item tree from {:?} {}", syntax, syntax); | 114 | panic!("cannot create item tree from {:?} {}", syntax, syntax); |
124 | }, | 115 | }, |
@@ -156,6 +147,7 @@ impl ItemTree { | |||
156 | vis, | 147 | vis, |
157 | generics, | 148 | generics, |
158 | type_refs, | 149 | type_refs, |
150 | trait_refs, | ||
159 | inner_items, | 151 | inner_items, |
160 | } = &mut **data; | 152 | } = &mut **data; |
161 | 153 | ||
@@ -182,6 +174,7 @@ impl ItemTree { | |||
182 | generics.arena.shrink_to_fit(); | 174 | generics.arena.shrink_to_fit(); |
183 | type_refs.arena.shrink_to_fit(); | 175 | type_refs.arena.shrink_to_fit(); |
184 | type_refs.map.shrink_to_fit(); | 176 | type_refs.map.shrink_to_fit(); |
177 | trait_refs.map.shrink_to_fit(); | ||
185 | 178 | ||
186 | inner_items.shrink_to_fit(); | 179 | inner_items.shrink_to_fit(); |
187 | } | 180 | } |
@@ -304,6 +297,32 @@ impl TypeRefStorage { | |||
304 | } | 297 | } |
305 | } | 298 | } |
306 | 299 | ||
300 | /// `TraitRef` interner. | ||
301 | #[derive(Default, Debug, Eq, PartialEq)] | ||
302 | struct TraitRefStorage { | ||
303 | arena: Arena<Arc<TraitRef>>, | ||
304 | map: FxHashMap<Arc<TraitRef>, Idx<Arc<TraitRef>>>, | ||
305 | } | ||
306 | |||
307 | impl TraitRefStorage { | ||
308 | // Note: We lie about the `Idx<TraitRef>` to hide the interner details. | ||
309 | |||
310 | fn intern(&mut self, ty: TraitRef) -> Idx<TraitRef> { | ||
311 | if let Some(id) = self.map.get(&ty) { | ||
312 | return Idx::from_raw(id.into_raw()); | ||
313 | } | ||
314 | |||
315 | let ty = Arc::new(ty); | ||
316 | let idx = self.arena.alloc(ty.clone()); | ||
317 | self.map.insert(ty, idx); | ||
318 | Idx::from_raw(idx.into_raw()) | ||
319 | } | ||
320 | |||
321 | fn lookup(&self, id: Idx<TraitRef>) -> &TraitRef { | ||
322 | &self.arena[Idx::from_raw(id.into_raw())] | ||
323 | } | ||
324 | } | ||
325 | |||
307 | #[derive(Default, Debug, Eq, PartialEq)] | 326 | #[derive(Default, Debug, Eq, PartialEq)] |
308 | struct ItemTreeData { | 327 | struct ItemTreeData { |
309 | imports: Arena<Import>, | 328 | imports: Arena<Import>, |
@@ -328,6 +347,7 @@ struct ItemTreeData { | |||
328 | vis: ItemVisibilities, | 347 | vis: ItemVisibilities, |
329 | generics: GenericParamsStorage, | 348 | generics: GenericParamsStorage, |
330 | type_refs: TypeRefStorage, | 349 | type_refs: TypeRefStorage, |
350 | trait_refs: TraitRefStorage, | ||
331 | 351 | ||
332 | inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>, | 352 | inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>, |
333 | } | 353 | } |
@@ -565,6 +585,14 @@ impl Index<Idx<TypeRef>> for ItemTree { | |||
565 | } | 585 | } |
566 | } | 586 | } |
567 | 587 | ||
588 | impl Index<Idx<TraitRef>> for ItemTree { | ||
589 | type Output = TraitRef; | ||
590 | |||
591 | fn index(&self, id: Idx<TraitRef>) -> &Self::Output { | ||
592 | self.data().trait_refs.lookup(id) | ||
593 | } | ||
594 | } | ||
595 | |||
568 | impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree { | 596 | impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree { |
569 | type Output = N; | 597 | type Output = N; |
570 | fn index(&self, id: FileItemTreeId<N>) -> &N { | 598 | fn index(&self, id: FileItemTreeId<N>) -> &N { |
@@ -701,8 +729,8 @@ pub struct Trait { | |||
701 | #[derive(Debug, Clone, Eq, PartialEq)] | 729 | #[derive(Debug, Clone, Eq, PartialEq)] |
702 | pub struct Impl { | 730 | pub struct Impl { |
703 | pub generic_params: GenericParamsId, | 731 | pub generic_params: GenericParamsId, |
704 | pub target_trait: Option<Idx<TypeRef>>, | 732 | pub target_trait: Option<Idx<TraitRef>>, |
705 | pub target_type: Idx<TypeRef>, | 733 | pub self_ty: Idx<TypeRef>, |
706 | pub is_negative: bool, | 734 | pub is_negative: bool, |
707 | pub items: Box<[AssocItem]>, | 735 | pub items: Box<[AssocItem]>, |
708 | pub ast_id: FileAstId<ast::Impl>, | 736 | pub ast_id: FileAstId<ast::Impl>, |