diff options
Diffstat (limited to 'crates/hir_ty/src/mapping.rs')
-rw-r--r-- | crates/hir_ty/src/mapping.rs | 92 |
1 files changed, 32 insertions, 60 deletions
diff --git a/crates/hir_ty/src/mapping.rs b/crates/hir_ty/src/mapping.rs index f57115de6..37c935194 100644 --- a/crates/hir_ty/src/mapping.rs +++ b/crates/hir_ty/src/mapping.rs | |||
@@ -3,16 +3,12 @@ | |||
3 | //! Chalk (in both directions); plus some helper functions for more specialized | 3 | //! Chalk (in both directions); plus some helper functions for more specialized |
4 | //! conversions. | 4 | //! conversions. |
5 | 5 | ||
6 | use chalk_ir::{cast::Cast, fold::Shift, DebruijnIndex}; | ||
7 | use chalk_solve::rust_ir; | 6 | use chalk_solve::rust_ir; |
8 | 7 | ||
9 | use base_db::salsa::InternKey; | 8 | use base_db::salsa::InternKey; |
10 | use hir_def::{GenericDefId, TypeAliasId}; | 9 | use hir_def::TypeAliasId; |
11 | 10 | ||
12 | use crate::{ | 11 | use crate::{chalk_db, db::HirDatabase, CallableDefId, FnDefId, Interner, OpaqueTyId}; |
13 | chalk_db, db::HirDatabase, AliasEq, AliasTy, CallableDefId, FnDefId, Interner, ProjectionTyExt, | ||
14 | QuantifiedWhereClause, Substitution, Ty, WhereClause, | ||
15 | }; | ||
16 | 12 | ||
17 | pub(crate) trait ToChalk { | 13 | pub(crate) trait ToChalk { |
18 | type Chalk; | 14 | type Chalk; |
@@ -80,62 +76,38 @@ impl ToChalk for TypeAliasAsValue { | |||
80 | } | 76 | } |
81 | } | 77 | } |
82 | 78 | ||
83 | pub(super) fn convert_where_clauses( | 79 | impl From<FnDefId> for crate::db::InternedCallableDefId { |
84 | db: &dyn HirDatabase, | 80 | fn from(fn_def_id: FnDefId) -> Self { |
85 | def: GenericDefId, | 81 | InternKey::from_intern_id(fn_def_id.0) |
86 | substs: &Substitution, | ||
87 | ) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> { | ||
88 | let generic_predicates = db.generic_predicates(def); | ||
89 | let mut result = Vec::with_capacity(generic_predicates.len()); | ||
90 | for pred in generic_predicates.iter() { | ||
91 | result.push(pred.clone().substitute(&Interner, substs)); | ||
92 | } | 82 | } |
93 | result | ||
94 | } | 83 | } |
95 | 84 | ||
96 | pub(super) fn generic_predicate_to_inline_bound( | 85 | impl From<crate::db::InternedCallableDefId> for FnDefId { |
97 | db: &dyn HirDatabase, | 86 | fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self { |
98 | pred: &QuantifiedWhereClause, | 87 | chalk_ir::FnDefId(callable_def_id.as_intern_id()) |
99 | self_ty: &Ty, | 88 | } |
100 | ) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> { | 89 | } |
101 | // An InlineBound is like a GenericPredicate, except the self type is left out. | 90 | |
102 | // We don't have a special type for this, but Chalk does. | 91 | impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId { |
103 | let self_ty_shifted_in = self_ty.clone().shifted_in_from(&Interner, DebruijnIndex::ONE); | 92 | fn from(id: OpaqueTyId) -> Self { |
104 | let (pred, binders) = pred.as_ref().into_value_and_skipped_binders(); | 93 | InternKey::from_intern_id(id.0) |
105 | match pred { | 94 | } |
106 | WhereClause::Implemented(trait_ref) => { | 95 | } |
107 | if trait_ref.self_type_parameter(&Interner) != self_ty_shifted_in { | 96 | |
108 | // we can only convert predicates back to type bounds if they | 97 | impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId { |
109 | // have the expected self type | 98 | fn from(id: crate::db::InternedOpaqueTyId) -> Self { |
110 | return None; | 99 | chalk_ir::OpaqueTyId(id.as_intern_id()) |
111 | } | 100 | } |
112 | let args_no_self = trait_ref.substitution.as_slice(&Interner)[1..] | 101 | } |
113 | .iter() | 102 | |
114 | .map(|ty| ty.clone().cast(&Interner)) | 103 | impl From<chalk_ir::ClosureId<Interner>> for crate::db::InternedClosureId { |
115 | .collect(); | 104 | fn from(id: chalk_ir::ClosureId<Interner>) -> Self { |
116 | let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; | 105 | Self::from_intern_id(id.0) |
117 | Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound))) | 106 | } |
118 | } | 107 | } |
119 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { | 108 | |
120 | if projection_ty.self_type_parameter(&Interner) != self_ty_shifted_in { | 109 | impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> { |
121 | return None; | 110 | fn from(id: crate::db::InternedClosureId) -> Self { |
122 | } | 111 | chalk_ir::ClosureId(id.as_intern_id()) |
123 | let trait_ = projection_ty.trait_(db); | ||
124 | let args_no_self = projection_ty.substitution.as_slice(&Interner)[1..] | ||
125 | .iter() | ||
126 | .map(|ty| ty.clone().cast(&Interner)) | ||
127 | .collect(); | ||
128 | let alias_eq_bound = rust_ir::AliasEqBound { | ||
129 | value: ty.clone(), | ||
130 | trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, | ||
131 | associated_ty_id: projection_ty.associated_ty_id, | ||
132 | parameters: Vec::new(), // FIXME we don't support generic associated types yet | ||
133 | }; | ||
134 | Some(chalk_ir::Binders::new( | ||
135 | binders, | ||
136 | rust_ir::InlineBound::AliasEqBound(alias_eq_bound), | ||
137 | )) | ||
138 | } | ||
139 | _ => None, | ||
140 | } | 112 | } |
141 | } | 113 | } |