aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/item_tree.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/item_tree.rs')
-rw-r--r--crates/hir_def/src/item_tree.rs52
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)]
302struct TraitRefStorage {
303 arena: Arena<Arc<TraitRef>>,
304 map: FxHashMap<Arc<TraitRef>, Idx<Arc<TraitRef>>>,
305}
306
307impl 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)]
308struct ItemTreeData { 327struct 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
588impl 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
568impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree { 596impl<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)]
702pub struct Impl { 730pub 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>,