diff options
Diffstat (limited to 'crates/hir_def')
-rw-r--r-- | crates/hir_def/src/data.rs | 4 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 41 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 10 | ||||
-rw-r--r-- | crates/hir_def/src/type_ref.rs | 19 |
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)] |
158 | pub struct ImplData { | 158 | pub 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)] | ||
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 | |||
298 | #[derive(Default, Debug, Eq, PartialEq)] | 326 | #[derive(Default, Debug, Eq, PartialEq)] |
299 | struct ItemTreeData { | 327 | struct 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 | ||
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 | |||
559 | impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree { | 596 | impl<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)] |
693 | pub struct Impl { | 730 | pub 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 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | generics::{GenericParams, TypeParamData, TypeParamProvenance}, | 13 | generics::{GenericParams, TypeParamData, TypeParamProvenance}, |
14 | type_ref::LifetimeRef, | 14 | type_ref::{LifetimeRef, TraitRef}, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | use super::*; | 17 | use 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)] | ||
55 | pub enum TraitRef { | ||
56 | Path(Path), | ||
57 | Error, | ||
58 | } | ||
59 | |||
60 | impl 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)] |
56 | pub enum TypeRef { | 75 | pub enum TypeRef { |