aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def')
-rw-r--r--crates/hir_def/src/data.rs4
-rw-r--r--crates/hir_def/src/item_tree.rs41
-rw-r--r--crates/hir_def/src/item_tree/lower.rs10
-rw-r--r--crates/hir_def/src/type_ref.rs19
4 files changed, 68 insertions, 6 deletions
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs
index 0be868ba2..7d35d7083 100644
--- a/crates/hir_def/src/data.rs
+++ b/crates/hir_def/src/data.rs
@@ -10,7 +10,7 @@ use crate::{
10 body::Expander, 10 body::Expander,
11 db::DefDatabase, 11 db::DefDatabase,
12 item_tree::{AssocItem, FunctionQualifier, ItemTreeId, ModItem, Param}, 12 item_tree::{AssocItem, FunctionQualifier, ItemTreeId, ModItem, Param},
13 type_ref::{TypeBound, TypeRef}, 13 type_ref::{TraitRef, TypeBound, TypeRef},
14 visibility::RawVisibility, 14 visibility::RawVisibility,
15 AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, 15 AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
16 Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc, 16 Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc,
@@ -156,7 +156,7 @@ impl TraitData {
156 156
157#[derive(Debug, Clone, PartialEq, Eq)] 157#[derive(Debug, Clone, PartialEq, Eq)]
158pub struct ImplData { 158pub struct ImplData {
159 pub target_trait: Option<TypeRef>, 159 pub target_trait: Option<TraitRef>,
160 pub target_type: TypeRef, 160 pub target_type: TypeRef,
161 pub items: Vec<AssocItemId>, 161 pub items: Vec<AssocItemId>,
162 pub is_negative: bool, 162 pub is_negative: bool,
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index ca0048b16..db94bb1ef 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,7 +729,7 @@ 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 target_type: Idx<TypeRef>,
697 pub is_negative: bool, 734 pub is_negative: bool,
698 pub items: Box<[AssocItem]>, 735 pub items: Box<[AssocItem]>,
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index 3f558edd8..34af5c8d4 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -11,7 +11,7 @@ use syntax::{
11 11
12use crate::{ 12use crate::{
13 generics::{GenericParams, TypeParamData, TypeParamProvenance}, 13 generics::{GenericParams, TypeParamData, TypeParamProvenance},
14 type_ref::LifetimeRef, 14 type_ref::{LifetimeRef, TraitRef},
15}; 15};
16 16
17use super::*; 17use super::*;
@@ -536,7 +536,7 @@ impl Ctx {
536 fn lower_impl(&mut self, impl_def: &ast::Impl) -> Option<FileItemTreeId<Impl>> { 536 fn lower_impl(&mut self, impl_def: &ast::Impl) -> Option<FileItemTreeId<Impl>> {
537 let generic_params = 537 let generic_params =
538 self.lower_generic_params_and_inner_items(GenericsOwner::Impl, impl_def); 538 self.lower_generic_params_and_inner_items(GenericsOwner::Impl, impl_def);
539 let target_trait = impl_def.trait_().map(|tr| self.lower_type_ref(&tr)); 539 let target_trait = impl_def.trait_().map(|tr| self.lower_trait_ref(&tr));
540 let target_type = self.lower_type_ref(&impl_def.self_ty()?); 540 let target_type = self.lower_type_ref(&impl_def.self_ty()?);
541 let is_negative = impl_def.excl_token().is_some(); 541 let is_negative = impl_def.excl_token().is_some();
542 542
@@ -740,10 +740,16 @@ impl Ctx {
740 self.data().vis.alloc(vis) 740 self.data().vis.alloc(vis)
741 } 741 }
742 742
743 fn lower_trait_ref(&mut self, trait_ref: &ast::Type) -> Idx<TraitRef> {
744 let trait_ref = TraitRef::from_ast(&self.body_ctx, trait_ref.clone());
745 self.data().trait_refs.intern(trait_ref)
746 }
747
743 fn lower_type_ref(&mut self, type_ref: &ast::Type) -> Idx<TypeRef> { 748 fn lower_type_ref(&mut self, type_ref: &ast::Type) -> Idx<TypeRef> {
744 let tyref = TypeRef::from_ast(&self.body_ctx, type_ref.clone()); 749 let tyref = TypeRef::from_ast(&self.body_ctx, type_ref.clone());
745 self.data().type_refs.intern(tyref) 750 self.data().type_refs.intern(tyref)
746 } 751 }
752
747 fn lower_type_ref_opt(&mut self, type_ref: Option<ast::Type>) -> Idx<TypeRef> { 753 fn lower_type_ref_opt(&mut self, type_ref: Option<ast::Type>) -> Idx<TypeRef> {
748 match type_ref.map(|ty| self.lower_type_ref(&ty)) { 754 match type_ref.map(|ty| self.lower_type_ref(&ty)) {
749 Some(it) => it, 755 Some(it) => it,
diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs
index 049b2e462..b7484ed0d 100644
--- a/crates/hir_def/src/type_ref.rs
+++ b/crates/hir_def/src/type_ref.rs
@@ -51,6 +51,25 @@ impl Rawness {
51 } 51 }
52} 52}
53 53
54#[derive(Clone, PartialEq, Eq, Hash, Debug)]
55pub enum TraitRef {
56 Path(Path),
57 Error,
58}
59
60impl TraitRef {
61 /// Converts an `ast::PathType` to a `hir::TraitRef`.
62 pub(crate) fn from_ast(ctx: &LowerCtx, node: ast::Type) -> Self {
63 // FIXME: Use `Path::from_src`
64 match node {
65 ast::Type::PathType(path) => path
66 .path()
67 .and_then(|it| ctx.lower_path(it))
68 .map_or(TraitRef::Error, TraitRef::Path),
69 _ => TraitRef::Error,
70 }
71 }
72}
54/// Compare ty::Ty 73/// Compare ty::Ty
55#[derive(Clone, PartialEq, Eq, Hash, Debug)] 74#[derive(Clone, PartialEq, Eq, Hash, Debug)]
56pub enum TypeRef { 75pub enum TypeRef {