diff options
Diffstat (limited to 'crates/hir_ty/src/traits/chalk/mapping.rs')
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 131 |
1 files changed, 0 insertions, 131 deletions
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs deleted file mode 100644 index e78581ea5..000000000 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | //! This module contains the implementations of the `ToChalk` trait, which | ||
2 | //! handles conversion between our data types and their corresponding types in | ||
3 | //! Chalk (in both directions); plus some helper functions for more specialized | ||
4 | //! conversions. | ||
5 | |||
6 | use chalk_ir::cast::Cast; | ||
7 | use chalk_solve::rust_ir; | ||
8 | |||
9 | use base_db::salsa::InternKey; | ||
10 | use hir_def::{GenericDefId, TypeAliasId}; | ||
11 | |||
12 | use crate::{ | ||
13 | db::HirDatabase, AliasTy, CallableDefId, ProjectionTyExt, QuantifiedWhereClause, Substitution, | ||
14 | Ty, WhereClause, | ||
15 | }; | ||
16 | |||
17 | use super::interner::*; | ||
18 | use super::*; | ||
19 | |||
20 | impl ToChalk for hir_def::TraitId { | ||
21 | type Chalk = TraitId; | ||
22 | |||
23 | fn to_chalk(self, _db: &dyn HirDatabase) -> TraitId { | ||
24 | chalk_ir::TraitId(self.as_intern_id()) | ||
25 | } | ||
26 | |||
27 | fn from_chalk(_db: &dyn HirDatabase, trait_id: TraitId) -> hir_def::TraitId { | ||
28 | InternKey::from_intern_id(trait_id.0) | ||
29 | } | ||
30 | } | ||
31 | |||
32 | impl ToChalk for hir_def::ImplId { | ||
33 | type Chalk = ImplId; | ||
34 | |||
35 | fn to_chalk(self, _db: &dyn HirDatabase) -> ImplId { | ||
36 | chalk_ir::ImplId(self.as_intern_id()) | ||
37 | } | ||
38 | |||
39 | fn from_chalk(_db: &dyn HirDatabase, impl_id: ImplId) -> hir_def::ImplId { | ||
40 | InternKey::from_intern_id(impl_id.0) | ||
41 | } | ||
42 | } | ||
43 | |||
44 | impl ToChalk for CallableDefId { | ||
45 | type Chalk = FnDefId; | ||
46 | |||
47 | fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId { | ||
48 | db.intern_callable_def(self).into() | ||
49 | } | ||
50 | |||
51 | fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId { | ||
52 | db.lookup_intern_callable_def(fn_def_id.into()) | ||
53 | } | ||
54 | } | ||
55 | |||
56 | pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId); | ||
57 | |||
58 | impl ToChalk for TypeAliasAsValue { | ||
59 | type Chalk = AssociatedTyValueId; | ||
60 | |||
61 | fn to_chalk(self, _db: &dyn HirDatabase) -> AssociatedTyValueId { | ||
62 | rust_ir::AssociatedTyValueId(self.0.as_intern_id()) | ||
63 | } | ||
64 | |||
65 | fn from_chalk( | ||
66 | _db: &dyn HirDatabase, | ||
67 | assoc_ty_value_id: AssociatedTyValueId, | ||
68 | ) -> TypeAliasAsValue { | ||
69 | TypeAliasAsValue(TypeAliasId::from_intern_id(assoc_ty_value_id.0)) | ||
70 | } | ||
71 | } | ||
72 | |||
73 | pub(super) fn convert_where_clauses( | ||
74 | db: &dyn HirDatabase, | ||
75 | def: GenericDefId, | ||
76 | substs: &Substitution, | ||
77 | ) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> { | ||
78 | let generic_predicates = db.generic_predicates(def); | ||
79 | let mut result = Vec::with_capacity(generic_predicates.len()); | ||
80 | for pred in generic_predicates.iter() { | ||
81 | result.push(pred.clone().substitute(&Interner, substs)); | ||
82 | } | ||
83 | result | ||
84 | } | ||
85 | |||
86 | pub(super) fn generic_predicate_to_inline_bound( | ||
87 | db: &dyn HirDatabase, | ||
88 | pred: &QuantifiedWhereClause, | ||
89 | self_ty: &Ty, | ||
90 | ) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> { | ||
91 | // An InlineBound is like a GenericPredicate, except the self type is left out. | ||
92 | // We don't have a special type for this, but Chalk does. | ||
93 | let self_ty_shifted_in = self_ty.clone().shifted_in_from(&Interner, DebruijnIndex::ONE); | ||
94 | let (pred, binders) = pred.as_ref().into_value_and_skipped_binders(); | ||
95 | match pred { | ||
96 | WhereClause::Implemented(trait_ref) => { | ||
97 | if trait_ref.self_type_parameter(&Interner) != self_ty_shifted_in { | ||
98 | // we can only convert predicates back to type bounds if they | ||
99 | // have the expected self type | ||
100 | return None; | ||
101 | } | ||
102 | let args_no_self = trait_ref.substitution.as_slice(&Interner)[1..] | ||
103 | .iter() | ||
104 | .map(|ty| ty.clone().cast(&Interner)) | ||
105 | .collect(); | ||
106 | let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; | ||
107 | Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound))) | ||
108 | } | ||
109 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { | ||
110 | if projection_ty.self_type_parameter(&Interner) != self_ty_shifted_in { | ||
111 | return None; | ||
112 | } | ||
113 | let trait_ = projection_ty.trait_(db); | ||
114 | let args_no_self = projection_ty.substitution.as_slice(&Interner)[1..] | ||
115 | .iter() | ||
116 | .map(|ty| ty.clone().cast(&Interner)) | ||
117 | .collect(); | ||
118 | let alias_eq_bound = rust_ir::AliasEqBound { | ||
119 | value: ty.clone(), | ||
120 | trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, | ||
121 | associated_ty_id: projection_ty.associated_ty_id, | ||
122 | parameters: Vec::new(), // FIXME we don't support generic associated types yet | ||
123 | }; | ||
124 | Some(chalk_ir::Binders::new( | ||
125 | binders, | ||
126 | rust_ir::InlineBound::AliasEqBound(alias_eq_bound), | ||
127 | )) | ||
128 | } | ||
129 | _ => None, | ||
130 | } | ||
131 | } | ||