diff options
author | Aleksey Kladov <[email protected]> | 2019-11-27 14:46:02 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-11-27 18:16:00 +0000 |
commit | a87579500a2c35597071efd0ad6983927f0c1815 (patch) | |
tree | 9805b3dcbf8d767b2fc0623f42794068f3660d44 /crates/ra_hir/src/ty/utils.rs | |
parent | 368653081558ab389c6543d6b5027859e26beb3b (diff) |
Move Ty
Diffstat (limited to 'crates/ra_hir/src/ty/utils.rs')
-rw-r--r-- | crates/ra_hir/src/ty/utils.rs | 75 |
1 files changed, 0 insertions, 75 deletions
diff --git a/crates/ra_hir/src/ty/utils.rs b/crates/ra_hir/src/ty/utils.rs deleted file mode 100644 index f82e6ac9b..000000000 --- a/crates/ra_hir/src/ty/utils.rs +++ /dev/null | |||
@@ -1,75 +0,0 @@ | |||
1 | //! Helper functions for working with def, which don't need to be a separate | ||
2 | //! query, but can't be computed directly from `*Data` (ie, which need a `db`). | ||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_def::{ | ||
6 | adt::VariantData, | ||
7 | db::DefDatabase, | ||
8 | resolver::{HasResolver, TypeNs}, | ||
9 | type_ref::TypeRef, | ||
10 | TraitId, TypeAliasId, VariantId, | ||
11 | }; | ||
12 | use hir_expand::name::{self, Name}; | ||
13 | |||
14 | // FIXME: this is wrong, b/c it can't express `trait T: PartialEq<()>`. | ||
15 | // We should return a `TraitREf` here. | ||
16 | fn direct_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec<TraitId> { | ||
17 | let resolver = trait_.resolver(db); | ||
18 | // returning the iterator directly doesn't easily work because of | ||
19 | // lifetime problems, but since there usually shouldn't be more than a | ||
20 | // few direct traits this should be fine (we could even use some kind of | ||
21 | // SmallVec if performance is a concern) | ||
22 | db.generic_params(trait_.into()) | ||
23 | .where_predicates | ||
24 | .iter() | ||
25 | .filter_map(|pred| match &pred.type_ref { | ||
26 | TypeRef::Path(p) if p.as_ident() == Some(&name::SELF_TYPE) => pred.bound.as_path(), | ||
27 | _ => None, | ||
28 | }) | ||
29 | .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { | ||
30 | Some(TypeNs::TraitId(t)) => Some(t), | ||
31 | _ => None, | ||
32 | }) | ||
33 | .collect() | ||
34 | } | ||
35 | |||
36 | /// Returns an iterator over the whole super trait hierarchy (including the | ||
37 | /// trait itself). | ||
38 | pub(super) fn all_super_traits(db: &impl DefDatabase, trait_: TraitId) -> Vec<TraitId> { | ||
39 | // we need to take care a bit here to avoid infinite loops in case of cycles | ||
40 | // (i.e. if we have `trait A: B; trait B: A;`) | ||
41 | let mut result = vec![trait_]; | ||
42 | let mut i = 0; | ||
43 | while i < result.len() { | ||
44 | let t = result[i]; | ||
45 | // yeah this is quadratic, but trait hierarchies should be flat | ||
46 | // enough that this doesn't matter | ||
47 | for tt in direct_super_traits(db, t) { | ||
48 | if !result.contains(&tt) { | ||
49 | result.push(tt); | ||
50 | } | ||
51 | } | ||
52 | i += 1; | ||
53 | } | ||
54 | result | ||
55 | } | ||
56 | |||
57 | pub(super) fn associated_type_by_name_including_super_traits( | ||
58 | db: &impl DefDatabase, | ||
59 | trait_: TraitId, | ||
60 | name: &Name, | ||
61 | ) -> Option<TypeAliasId> { | ||
62 | all_super_traits(db, trait_) | ||
63 | .into_iter() | ||
64 | .find_map(|t| db.trait_data(t).associated_type_by_name(name)) | ||
65 | } | ||
66 | |||
67 | pub(super) fn variant_data(db: &impl DefDatabase, var: VariantId) -> Arc<VariantData> { | ||
68 | match var { | ||
69 | VariantId::StructId(it) => db.struct_data(it).variant_data.clone(), | ||
70 | VariantId::UnionId(it) => db.union_data(it).variant_data.clone(), | ||
71 | VariantId::EnumVariantId(it) => { | ||
72 | db.enum_data(it.parent).variants[it.local_id].variant_data.clone() | ||
73 | } | ||
74 | } | ||
75 | } | ||