diff options
author | Florian Diebold <[email protected]> | 2019-03-31 19:02:16 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-04-14 10:28:53 +0100 |
commit | a1ed53a4f183b5826162eb9e998207b92be9c57f (patch) | |
tree | 7c139a7dc38483188653c6d40583cddac9d23192 /crates/ra_hir/src/traits.rs | |
parent | 413c87f155ab6b389b1cc122b5739716acccb476 (diff) |
More trait infrastructure
- make it possible to get parent trait from method
- add 'obligation' machinery for checking that a type implements a
trait (and inferring facts about type variables from that)
- handle type parameters of traits (to a certain degree)
- improve the hacky implements check to cover enough cases to exercise the
handling of traits with type parameters
- basic canonicalization (will probably also be done by Chalk)
Diffstat (limited to 'crates/ra_hir/src/traits.rs')
-rw-r--r-- | crates/ra_hir/src/traits.rs | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/crates/ra_hir/src/traits.rs b/crates/ra_hir/src/traits.rs index 725bdd5cb..15f0977b7 100644 --- a/crates/ra_hir/src/traits.rs +++ b/crates/ra_hir/src/traits.rs | |||
@@ -1,10 +1,11 @@ | |||
1 | //! HIR for trait definitions. | 1 | //! HIR for trait definitions. |
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | use rustc_hash::FxHashMap; | ||
4 | 5 | ||
5 | use ra_syntax::ast::{self, NameOwner}; | 6 | use ra_syntax::ast::{self, NameOwner}; |
6 | 7 | ||
7 | use crate::{Function, Const, TypeAlias, Name, DefDatabase, Trait, ids::LocationCtx, name::AsName}; | 8 | use crate::{Function, Const, TypeAlias, Name, DefDatabase, Trait, ids::LocationCtx, name::AsName, Module}; |
8 | 9 | ||
9 | #[derive(Debug, Clone, PartialEq, Eq)] | 10 | #[derive(Debug, Clone, PartialEq, Eq)] |
10 | pub struct TraitData { | 11 | pub struct TraitData { |
@@ -49,4 +50,34 @@ pub enum TraitItem { | |||
49 | TypeAlias(TypeAlias), | 50 | TypeAlias(TypeAlias), |
50 | // Existential | 51 | // Existential |
51 | } | 52 | } |
53 | // FIXME: not every function, ... is actually a trait item. maybe we should make | ||
54 | // sure that you can only turn actual trait items into TraitItems. This would | ||
55 | // require not implementing From, and instead having some checked way of | ||
56 | // casting them. | ||
52 | impl_froms!(TraitItem: Function, Const, TypeAlias); | 57 | impl_froms!(TraitItem: Function, Const, TypeAlias); |
58 | |||
59 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
60 | pub struct TraitItemsIndex { | ||
61 | traits_by_def: FxHashMap<TraitItem, Trait>, | ||
62 | } | ||
63 | |||
64 | impl TraitItemsIndex { | ||
65 | pub(crate) fn trait_items_index(db: &impl DefDatabase, module: Module) -> TraitItemsIndex { | ||
66 | let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() }; | ||
67 | for decl in module.declarations(db) { | ||
68 | match decl { | ||
69 | crate::ModuleDef::Trait(tr) => { | ||
70 | for item in tr.trait_data(db).items() { | ||
71 | index.traits_by_def.insert(*item, tr); | ||
72 | } | ||
73 | } | ||
74 | _ => {} | ||
75 | } | ||
76 | } | ||
77 | index | ||
78 | } | ||
79 | |||
80 | pub(crate) fn get_parent_trait(&self, item: TraitItem) -> Option<Trait> { | ||
81 | self.traits_by_def.get(&item).cloned() | ||
82 | } | ||
83 | } | ||