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.rs43
1 files changed, 40 insertions, 3 deletions
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index ca0048b16..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
@@ -147,6 +147,7 @@ impl ItemTree {
147 vis, 147 vis,
148 generics, 148 generics,
149 type_refs, 149 type_refs,
150 trait_refs,
150 inner_items, 151 inner_items,
151 } = &mut **data; 152 } = &mut **data;
152 153
@@ -173,6 +174,7 @@ impl ItemTree {
173 generics.arena.shrink_to_fit(); 174 generics.arena.shrink_to_fit();
174 type_refs.arena.shrink_to_fit(); 175 type_refs.arena.shrink_to_fit();
175 type_refs.map.shrink_to_fit(); 176 type_refs.map.shrink_to_fit();
177 trait_refs.map.shrink_to_fit();
176 178
177 inner_items.shrink_to_fit(); 179 inner_items.shrink_to_fit();
178 } 180 }
@@ -295,6 +297,32 @@ impl TypeRefStorage {
295 } 297 }
296} 298}
297 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
298#[derive(Default, Debug, Eq, PartialEq)] 326#[derive(Default, Debug, Eq, PartialEq)]
299struct ItemTreeData { 327struct ItemTreeData {
300 imports: Arena<Import>, 328 imports: Arena<Import>,
@@ -319,6 +347,7 @@ struct ItemTreeData {
319 vis: ItemVisibilities, 347 vis: ItemVisibilities,
320 generics: GenericParamsStorage, 348 generics: GenericParamsStorage,
321 type_refs: TypeRefStorage, 349 type_refs: TypeRefStorage,
350 trait_refs: TraitRefStorage,
322 351
323 inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>, 352 inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>,
324} 353}
@@ -556,6 +585,14 @@ impl Index<Idx<TypeRef>> for ItemTree {
556 } 585 }
557} 586}
558 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
559impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree { 596impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
560 type Output = N; 597 type Output = N;
561 fn index(&self, id: FileItemTreeId<N>) -> &N { 598 fn index(&self, id: FileItemTreeId<N>) -> &N {
@@ -692,8 +729,8 @@ pub struct Trait {
692#[derive(Debug, Clone, Eq, PartialEq)] 729#[derive(Debug, Clone, Eq, PartialEq)]
693pub struct Impl { 730pub struct Impl {
694 pub generic_params: GenericParamsId, 731 pub generic_params: GenericParamsId,
695 pub target_trait: Option<Idx<TypeRef>>, 732 pub target_trait: Option<Idx<TraitRef>>,
696 pub target_type: Idx<TypeRef>, 733 pub self_ty: Idx<TypeRef>,
697 pub is_negative: bool, 734 pub is_negative: bool,
698 pub items: Box<[AssocItem]>, 735 pub items: Box<[AssocItem]>,
699 pub ast_id: FileAstId<ast::Impl>, 736 pub ast_id: FileAstId<ast::Impl>,