diff options
Diffstat (limited to 'crates/hir_ty/src/traits/chalk/mapping.rs')
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 575 |
1 files changed, 0 insertions, 575 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 452b357e8..000000000 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ /dev/null | |||
@@ -1,575 +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, fold::shift::Shift, interner::HasInterner, LifetimeData}; | ||
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, | ||
14 | primitive::UintTy, | ||
15 | traits::{Canonical, DomainGoal}, | ||
16 | AliasTy, CallableDefId, FnPointer, GenericArg, InEnvironment, OpaqueTy, ProjectionTy, | ||
17 | QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause, | ||
18 | }; | ||
19 | |||
20 | use super::interner::*; | ||
21 | use super::*; | ||
22 | |||
23 | impl ToChalk for Ty { | ||
24 | type Chalk = chalk_ir::Ty<Interner>; | ||
25 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { | ||
26 | match self.into_inner() { | ||
27 | TyKind::Ref(m, ty) => ref_to_chalk(db, m, ty), | ||
28 | TyKind::Array(ty) => array_to_chalk(db, ty), | ||
29 | TyKind::Function(FnPointer { sig, substs, .. }) => { | ||
30 | let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner)); | ||
31 | chalk_ir::TyKind::Function(chalk_ir::FnPointer { | ||
32 | num_binders: 0, | ||
33 | sig, | ||
34 | substitution, | ||
35 | }) | ||
36 | .intern(&Interner) | ||
37 | } | ||
38 | TyKind::AssociatedType(assoc_type_id, substs) => { | ||
39 | let substitution = substs.to_chalk(db); | ||
40 | chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner) | ||
41 | } | ||
42 | |||
43 | TyKind::OpaqueType(id, substs) => { | ||
44 | let substitution = substs.to_chalk(db); | ||
45 | chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner) | ||
46 | } | ||
47 | |||
48 | TyKind::ForeignType(id) => chalk_ir::TyKind::Foreign(id).intern(&Interner), | ||
49 | |||
50 | TyKind::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner), | ||
51 | |||
52 | TyKind::Tuple(cardinality, substs) => { | ||
53 | let substitution = substs.to_chalk(db); | ||
54 | chalk_ir::TyKind::Tuple(cardinality, substitution).intern(&Interner) | ||
55 | } | ||
56 | TyKind::Raw(mutability, ty) => { | ||
57 | let ty = ty.to_chalk(db); | ||
58 | chalk_ir::TyKind::Raw(mutability, ty).intern(&Interner) | ||
59 | } | ||
60 | TyKind::Slice(ty) => chalk_ir::TyKind::Slice(ty.to_chalk(db)).intern(&Interner), | ||
61 | TyKind::Str => chalk_ir::TyKind::Str.intern(&Interner), | ||
62 | TyKind::FnDef(id, substs) => { | ||
63 | let substitution = substs.to_chalk(db); | ||
64 | chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner) | ||
65 | } | ||
66 | TyKind::Never => chalk_ir::TyKind::Never.intern(&Interner), | ||
67 | |||
68 | TyKind::Closure(closure_id, substs) => { | ||
69 | let substitution = substs.to_chalk(db); | ||
70 | chalk_ir::TyKind::Closure(closure_id, substitution).intern(&Interner) | ||
71 | } | ||
72 | |||
73 | TyKind::Adt(adt_id, substs) => { | ||
74 | let substitution = substs.to_chalk(db); | ||
75 | chalk_ir::TyKind::Adt(adt_id, substitution).intern(&Interner) | ||
76 | } | ||
77 | TyKind::Alias(AliasTy::Projection(proj_ty)) => { | ||
78 | let associated_ty_id = proj_ty.associated_ty_id; | ||
79 | let substitution = proj_ty.substitution.to_chalk(db); | ||
80 | chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { | ||
81 | associated_ty_id, | ||
82 | substitution, | ||
83 | }) | ||
84 | .cast(&Interner) | ||
85 | .intern(&Interner) | ||
86 | } | ||
87 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { | ||
88 | let opaque_ty_id = opaque_ty.opaque_ty_id; | ||
89 | let substitution = opaque_ty.substitution.to_chalk(db); | ||
90 | chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { opaque_ty_id, substitution }) | ||
91 | .cast(&Interner) | ||
92 | .intern(&Interner) | ||
93 | } | ||
94 | TyKind::Placeholder(idx) => idx.to_ty::<Interner>(&Interner), | ||
95 | TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner), | ||
96 | TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"), | ||
97 | TyKind::Dyn(dyn_ty) => { | ||
98 | let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( | ||
99 | &Interner, | ||
100 | dyn_ty.bounds.value.interned().iter().cloned().map(|p| p.to_chalk(db)), | ||
101 | ); | ||
102 | let bounded_ty = chalk_ir::DynTy { | ||
103 | bounds: make_binders(where_clauses, 1), | ||
104 | lifetime: LifetimeData::Static.intern(&Interner), | ||
105 | }; | ||
106 | chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner) | ||
107 | } | ||
108 | TyKind::Unknown => chalk_ir::TyKind::Error.intern(&Interner), | ||
109 | } | ||
110 | } | ||
111 | fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { | ||
112 | match chalk.data(&Interner).kind.clone() { | ||
113 | chalk_ir::TyKind::Error => TyKind::Unknown, | ||
114 | chalk_ir::TyKind::Array(ty, _size) => TyKind::Array(from_chalk(db, ty)), | ||
115 | chalk_ir::TyKind::Placeholder(idx) => TyKind::Placeholder(idx), | ||
116 | chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => { | ||
117 | let associated_ty = proj.associated_ty_id; | ||
118 | let parameters = from_chalk(db, proj.substitution); | ||
119 | TyKind::Alias(AliasTy::Projection(ProjectionTy { | ||
120 | associated_ty_id: associated_ty, | ||
121 | substitution: parameters, | ||
122 | })) | ||
123 | } | ||
124 | chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => { | ||
125 | let opaque_ty_id = opaque_ty.opaque_ty_id; | ||
126 | let parameters = from_chalk(db, opaque_ty.substitution); | ||
127 | TyKind::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id, substitution: parameters })) | ||
128 | } | ||
129 | chalk_ir::TyKind::Function(chalk_ir::FnPointer { | ||
130 | num_binders, | ||
131 | sig, | ||
132 | substitution, | ||
133 | .. | ||
134 | }) => { | ||
135 | assert_eq!(num_binders, 0); | ||
136 | let substs: Substitution = from_chalk( | ||
137 | db, | ||
138 | substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), | ||
139 | ); | ||
140 | TyKind::Function(FnPointer { num_args: (substs.len(&Interner) - 1), sig, substs }) | ||
141 | } | ||
142 | chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx), | ||
143 | chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown, | ||
144 | chalk_ir::TyKind::Dyn(where_clauses) => { | ||
145 | assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); | ||
146 | let bounds = where_clauses | ||
147 | .bounds | ||
148 | .skip_binders() | ||
149 | .iter(&Interner) | ||
150 | .map(|c| from_chalk(db, c.clone())); | ||
151 | TyKind::Dyn(crate::DynTy { | ||
152 | bounds: crate::Binders::new( | ||
153 | 1, | ||
154 | crate::QuantifiedWhereClauses::from_iter(&Interner, bounds), | ||
155 | ), | ||
156 | }) | ||
157 | } | ||
158 | |||
159 | chalk_ir::TyKind::Adt(adt_id, subst) => TyKind::Adt(adt_id, from_chalk(db, subst)), | ||
160 | chalk_ir::TyKind::AssociatedType(type_id, subst) => { | ||
161 | TyKind::AssociatedType(type_id, from_chalk(db, subst)) | ||
162 | } | ||
163 | |||
164 | chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => { | ||
165 | TyKind::OpaqueType(opaque_type_id, from_chalk(db, subst)) | ||
166 | } | ||
167 | |||
168 | chalk_ir::TyKind::Scalar(scalar) => TyKind::Scalar(scalar), | ||
169 | chalk_ir::TyKind::Tuple(cardinality, subst) => { | ||
170 | TyKind::Tuple(cardinality, from_chalk(db, subst)) | ||
171 | } | ||
172 | chalk_ir::TyKind::Raw(mutability, ty) => TyKind::Raw(mutability, from_chalk(db, ty)), | ||
173 | chalk_ir::TyKind::Slice(ty) => TyKind::Slice(from_chalk(db, ty)), | ||
174 | chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { | ||
175 | TyKind::Ref(mutability, from_chalk(db, ty)) | ||
176 | } | ||
177 | chalk_ir::TyKind::Str => TyKind::Str, | ||
178 | chalk_ir::TyKind::Never => TyKind::Never, | ||
179 | |||
180 | chalk_ir::TyKind::FnDef(fn_def_id, subst) => { | ||
181 | TyKind::FnDef(fn_def_id, from_chalk(db, subst)) | ||
182 | } | ||
183 | |||
184 | chalk_ir::TyKind::Closure(id, subst) => TyKind::Closure(id, from_chalk(db, subst)), | ||
185 | |||
186 | chalk_ir::TyKind::Foreign(foreign_def_id) => TyKind::ForeignType(foreign_def_id), | ||
187 | chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME | ||
188 | chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME | ||
189 | } | ||
190 | .intern(&Interner) | ||
191 | } | ||
192 | } | ||
193 | |||
194 | /// We currently don't model lifetimes, but Chalk does. So, we have to insert a | ||
195 | /// fake lifetime here, because Chalks built-in logic may expect it to be there. | ||
196 | fn ref_to_chalk( | ||
197 | db: &dyn HirDatabase, | ||
198 | mutability: chalk_ir::Mutability, | ||
199 | ty: Ty, | ||
200 | ) -> chalk_ir::Ty<Interner> { | ||
201 | let arg = ty.to_chalk(db); | ||
202 | let lifetime = LifetimeData::Static.intern(&Interner); | ||
203 | chalk_ir::TyKind::Ref(mutability, lifetime, arg).intern(&Interner) | ||
204 | } | ||
205 | |||
206 | /// We currently don't model constants, but Chalk does. So, we have to insert a | ||
207 | /// fake constant here, because Chalks built-in logic may expect it to be there. | ||
208 | fn array_to_chalk(db: &dyn HirDatabase, ty: Ty) -> chalk_ir::Ty<Interner> { | ||
209 | let arg = ty.to_chalk(db); | ||
210 | let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner); | ||
211 | let const_ = chalk_ir::ConstData { | ||
212 | ty: usize_ty, | ||
213 | value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }), | ||
214 | } | ||
215 | .intern(&Interner); | ||
216 | chalk_ir::TyKind::Array(arg, const_).intern(&Interner) | ||
217 | } | ||
218 | |||
219 | impl ToChalk for GenericArg { | ||
220 | type Chalk = chalk_ir::GenericArg<Interner>; | ||
221 | |||
222 | fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk { | ||
223 | match self.interned { | ||
224 | crate::GenericArgData::Ty(ty) => ty.to_chalk(db).cast(&Interner), | ||
225 | } | ||
226 | } | ||
227 | |||
228 | fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self { | ||
229 | match chalk.interned() { | ||
230 | chalk_ir::GenericArgData::Ty(ty) => Ty::from_chalk(db, ty.clone()).cast(&Interner), | ||
231 | chalk_ir::GenericArgData::Lifetime(_) => unimplemented!(), | ||
232 | chalk_ir::GenericArgData::Const(_) => unimplemented!(), | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | |||
237 | impl ToChalk for Substitution { | ||
238 | type Chalk = chalk_ir::Substitution<Interner>; | ||
239 | |||
240 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> { | ||
241 | chalk_ir::Substitution::from_iter( | ||
242 | &Interner, | ||
243 | self.iter(&Interner).map(|ty| ty.clone().to_chalk(db)), | ||
244 | ) | ||
245 | } | ||
246 | |||
247 | fn from_chalk( | ||
248 | db: &dyn HirDatabase, | ||
249 | parameters: chalk_ir::Substitution<Interner>, | ||
250 | ) -> Substitution { | ||
251 | let tys = parameters.iter(&Interner).map(|p| from_chalk(db, p.clone())).collect(); | ||
252 | Substitution(tys) | ||
253 | } | ||
254 | } | ||
255 | |||
256 | impl ToChalk for TraitRef { | ||
257 | type Chalk = chalk_ir::TraitRef<Interner>; | ||
258 | |||
259 | fn to_chalk(self: TraitRef, db: &dyn HirDatabase) -> chalk_ir::TraitRef<Interner> { | ||
260 | let trait_id = self.trait_id; | ||
261 | let substitution = self.substitution.to_chalk(db); | ||
262 | chalk_ir::TraitRef { trait_id, substitution } | ||
263 | } | ||
264 | |||
265 | fn from_chalk(db: &dyn HirDatabase, trait_ref: chalk_ir::TraitRef<Interner>) -> Self { | ||
266 | let trait_id = trait_ref.trait_id; | ||
267 | let substs = from_chalk(db, trait_ref.substitution); | ||
268 | TraitRef { trait_id, substitution: substs } | ||
269 | } | ||
270 | } | ||
271 | |||
272 | impl ToChalk for hir_def::TraitId { | ||
273 | type Chalk = TraitId; | ||
274 | |||
275 | fn to_chalk(self, _db: &dyn HirDatabase) -> TraitId { | ||
276 | chalk_ir::TraitId(self.as_intern_id()) | ||
277 | } | ||
278 | |||
279 | fn from_chalk(_db: &dyn HirDatabase, trait_id: TraitId) -> hir_def::TraitId { | ||
280 | InternKey::from_intern_id(trait_id.0) | ||
281 | } | ||
282 | } | ||
283 | |||
284 | impl ToChalk for hir_def::ImplId { | ||
285 | type Chalk = ImplId; | ||
286 | |||
287 | fn to_chalk(self, _db: &dyn HirDatabase) -> ImplId { | ||
288 | chalk_ir::ImplId(self.as_intern_id()) | ||
289 | } | ||
290 | |||
291 | fn from_chalk(_db: &dyn HirDatabase, impl_id: ImplId) -> hir_def::ImplId { | ||
292 | InternKey::from_intern_id(impl_id.0) | ||
293 | } | ||
294 | } | ||
295 | |||
296 | impl ToChalk for CallableDefId { | ||
297 | type Chalk = FnDefId; | ||
298 | |||
299 | fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId { | ||
300 | db.intern_callable_def(self).into() | ||
301 | } | ||
302 | |||
303 | fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId { | ||
304 | db.lookup_intern_callable_def(fn_def_id.into()) | ||
305 | } | ||
306 | } | ||
307 | |||
308 | pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId); | ||
309 | |||
310 | impl ToChalk for TypeAliasAsValue { | ||
311 | type Chalk = AssociatedTyValueId; | ||
312 | |||
313 | fn to_chalk(self, _db: &dyn HirDatabase) -> AssociatedTyValueId { | ||
314 | rust_ir::AssociatedTyValueId(self.0.as_intern_id()) | ||
315 | } | ||
316 | |||
317 | fn from_chalk( | ||
318 | _db: &dyn HirDatabase, | ||
319 | assoc_ty_value_id: AssociatedTyValueId, | ||
320 | ) -> TypeAliasAsValue { | ||
321 | TypeAliasAsValue(TypeAliasId::from_intern_id(assoc_ty_value_id.0)) | ||
322 | } | ||
323 | } | ||
324 | |||
325 | impl ToChalk for WhereClause { | ||
326 | type Chalk = chalk_ir::WhereClause<Interner>; | ||
327 | |||
328 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::WhereClause<Interner> { | ||
329 | match self { | ||
330 | WhereClause::Implemented(trait_ref) => { | ||
331 | chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)) | ||
332 | } | ||
333 | WhereClause::AliasEq(alias_eq) => chalk_ir::WhereClause::AliasEq(alias_eq.to_chalk(db)), | ||
334 | } | ||
335 | } | ||
336 | |||
337 | fn from_chalk( | ||
338 | db: &dyn HirDatabase, | ||
339 | where_clause: chalk_ir::WhereClause<Interner>, | ||
340 | ) -> WhereClause { | ||
341 | match where_clause { | ||
342 | chalk_ir::WhereClause::Implemented(tr) => WhereClause::Implemented(from_chalk(db, tr)), | ||
343 | chalk_ir::WhereClause::AliasEq(alias_eq) => { | ||
344 | WhereClause::AliasEq(from_chalk(db, alias_eq)) | ||
345 | } | ||
346 | |||
347 | chalk_ir::WhereClause::LifetimeOutlives(_) => { | ||
348 | // we shouldn't get these from Chalk | ||
349 | panic!("encountered LifetimeOutlives from Chalk") | ||
350 | } | ||
351 | |||
352 | chalk_ir::WhereClause::TypeOutlives(_) => { | ||
353 | // we shouldn't get these from Chalk | ||
354 | panic!("encountered TypeOutlives from Chalk") | ||
355 | } | ||
356 | } | ||
357 | } | ||
358 | } | ||
359 | |||
360 | impl ToChalk for ProjectionTy { | ||
361 | type Chalk = chalk_ir::ProjectionTy<Interner>; | ||
362 | |||
363 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> { | ||
364 | chalk_ir::ProjectionTy { | ||
365 | associated_ty_id: self.associated_ty_id, | ||
366 | substitution: self.substitution.to_chalk(db), | ||
367 | } | ||
368 | } | ||
369 | |||
370 | fn from_chalk( | ||
371 | db: &dyn HirDatabase, | ||
372 | projection_ty: chalk_ir::ProjectionTy<Interner>, | ||
373 | ) -> ProjectionTy { | ||
374 | ProjectionTy { | ||
375 | associated_ty_id: projection_ty.associated_ty_id, | ||
376 | substitution: from_chalk(db, projection_ty.substitution), | ||
377 | } | ||
378 | } | ||
379 | } | ||
380 | impl ToChalk for OpaqueTy { | ||
381 | type Chalk = chalk_ir::OpaqueTy<Interner>; | ||
382 | |||
383 | fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk { | ||
384 | chalk_ir::OpaqueTy { | ||
385 | opaque_ty_id: self.opaque_ty_id, | ||
386 | substitution: self.substitution.to_chalk(db), | ||
387 | } | ||
388 | } | ||
389 | |||
390 | fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self { | ||
391 | OpaqueTy { | ||
392 | opaque_ty_id: chalk.opaque_ty_id, | ||
393 | substitution: from_chalk(db, chalk.substitution), | ||
394 | } | ||
395 | } | ||
396 | } | ||
397 | |||
398 | impl ToChalk for AliasTy { | ||
399 | type Chalk = chalk_ir::AliasTy<Interner>; | ||
400 | |||
401 | fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk { | ||
402 | match self { | ||
403 | AliasTy::Projection(projection_ty) => { | ||
404 | chalk_ir::AliasTy::Projection(projection_ty.to_chalk(db)) | ||
405 | } | ||
406 | AliasTy::Opaque(opaque_ty) => chalk_ir::AliasTy::Opaque(opaque_ty.to_chalk(db)), | ||
407 | } | ||
408 | } | ||
409 | |||
410 | fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self { | ||
411 | match chalk { | ||
412 | chalk_ir::AliasTy::Projection(projection_ty) => { | ||
413 | AliasTy::Projection(from_chalk(db, projection_ty)) | ||
414 | } | ||
415 | chalk_ir::AliasTy::Opaque(opaque_ty) => AliasTy::Opaque(from_chalk(db, opaque_ty)), | ||
416 | } | ||
417 | } | ||
418 | } | ||
419 | |||
420 | impl ToChalk for AliasEq { | ||
421 | type Chalk = chalk_ir::AliasEq<Interner>; | ||
422 | |||
423 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> { | ||
424 | chalk_ir::AliasEq { alias: self.alias.to_chalk(db), ty: self.ty.to_chalk(db) } | ||
425 | } | ||
426 | |||
427 | fn from_chalk(db: &dyn HirDatabase, alias_eq: chalk_ir::AliasEq<Interner>) -> Self { | ||
428 | AliasEq { alias: from_chalk(db, alias_eq.alias), ty: from_chalk(db, alias_eq.ty) } | ||
429 | } | ||
430 | } | ||
431 | |||
432 | impl ToChalk for DomainGoal { | ||
433 | type Chalk = chalk_ir::DomainGoal<Interner>; | ||
434 | |||
435 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> { | ||
436 | match self { | ||
437 | DomainGoal::Holds(WhereClause::Implemented(tr)) => tr.to_chalk(db).cast(&Interner), | ||
438 | DomainGoal::Holds(WhereClause::AliasEq(alias_eq)) => { | ||
439 | alias_eq.to_chalk(db).cast(&Interner) | ||
440 | } | ||
441 | } | ||
442 | } | ||
443 | |||
444 | fn from_chalk(_db: &dyn HirDatabase, _goal: chalk_ir::DomainGoal<Interner>) -> Self { | ||
445 | unimplemented!() | ||
446 | } | ||
447 | } | ||
448 | |||
449 | impl<T> ToChalk for Canonical<T> | ||
450 | where | ||
451 | T: ToChalk, | ||
452 | T::Chalk: HasInterner<Interner = Interner>, | ||
453 | { | ||
454 | type Chalk = chalk_ir::Canonical<T::Chalk>; | ||
455 | |||
456 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> { | ||
457 | let value = self.value.to_chalk(db); | ||
458 | chalk_ir::Canonical { value, binders: self.binders } | ||
459 | } | ||
460 | |||
461 | fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> { | ||
462 | Canonical { binders: canonical.binders, value: from_chalk(db, canonical.value) } | ||
463 | } | ||
464 | } | ||
465 | |||
466 | impl<T: ToChalk> ToChalk for InEnvironment<T> | ||
467 | where | ||
468 | T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>, | ||
469 | { | ||
470 | type Chalk = chalk_ir::InEnvironment<T::Chalk>; | ||
471 | |||
472 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> { | ||
473 | chalk_ir::InEnvironment { environment: self.environment, goal: self.goal.to_chalk(db) } | ||
474 | } | ||
475 | |||
476 | fn from_chalk( | ||
477 | _db: &dyn HirDatabase, | ||
478 | _in_env: chalk_ir::InEnvironment<T::Chalk>, | ||
479 | ) -> InEnvironment<T> { | ||
480 | unimplemented!() | ||
481 | } | ||
482 | } | ||
483 | |||
484 | impl<T: ToChalk> ToChalk for crate::Binders<T> | ||
485 | where | ||
486 | T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>, | ||
487 | { | ||
488 | type Chalk = chalk_ir::Binders<T::Chalk>; | ||
489 | |||
490 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> { | ||
491 | chalk_ir::Binders::new( | ||
492 | chalk_ir::VariableKinds::from_iter( | ||
493 | &Interner, | ||
494 | std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)) | ||
495 | .take(self.num_binders), | ||
496 | ), | ||
497 | self.value.to_chalk(db), | ||
498 | ) | ||
499 | } | ||
500 | |||
501 | fn from_chalk(db: &dyn HirDatabase, binders: chalk_ir::Binders<T::Chalk>) -> crate::Binders<T> { | ||
502 | let (v, b) = binders.into_value_and_skipped_binders(); | ||
503 | crate::Binders::new(b.len(&Interner), from_chalk(db, v)) | ||
504 | } | ||
505 | } | ||
506 | |||
507 | pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> | ||
508 | where | ||
509 | T: HasInterner<Interner = Interner>, | ||
510 | { | ||
511 | chalk_ir::Binders::new( | ||
512 | chalk_ir::VariableKinds::from_iter( | ||
513 | &Interner, | ||
514 | std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)) | ||
515 | .take(num_vars), | ||
516 | ), | ||
517 | value, | ||
518 | ) | ||
519 | } | ||
520 | |||
521 | pub(super) fn convert_where_clauses( | ||
522 | db: &dyn HirDatabase, | ||
523 | def: GenericDefId, | ||
524 | substs: &Substitution, | ||
525 | ) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> { | ||
526 | let generic_predicates = db.generic_predicates(def); | ||
527 | let mut result = Vec::with_capacity(generic_predicates.len()); | ||
528 | for pred in generic_predicates.iter() { | ||
529 | result.push(pred.clone().subst(substs).to_chalk(db)); | ||
530 | } | ||
531 | result | ||
532 | } | ||
533 | |||
534 | pub(super) fn generic_predicate_to_inline_bound( | ||
535 | db: &dyn HirDatabase, | ||
536 | pred: &QuantifiedWhereClause, | ||
537 | self_ty: &Ty, | ||
538 | ) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> { | ||
539 | // An InlineBound is like a GenericPredicate, except the self type is left out. | ||
540 | // We don't have a special type for this, but Chalk does. | ||
541 | let self_ty_shifted_in = self_ty.clone().shift_bound_vars(DebruijnIndex::ONE); | ||
542 | match &pred.value { | ||
543 | WhereClause::Implemented(trait_ref) => { | ||
544 | if trait_ref.self_type_parameter() != &self_ty_shifted_in { | ||
545 | // we can only convert predicates back to type bounds if they | ||
546 | // have the expected self type | ||
547 | return None; | ||
548 | } | ||
549 | let args_no_self = trait_ref.substitution.interned(&Interner)[1..] | ||
550 | .iter() | ||
551 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) | ||
552 | .collect(); | ||
553 | let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; | ||
554 | Some(make_binders(rust_ir::InlineBound::TraitBound(trait_bound), pred.num_binders)) | ||
555 | } | ||
556 | WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { | ||
557 | if projection_ty.self_type_parameter() != &self_ty_shifted_in { | ||
558 | return None; | ||
559 | } | ||
560 | let trait_ = projection_ty.trait_(db); | ||
561 | let args_no_self = projection_ty.substitution.interned(&Interner)[1..] | ||
562 | .iter() | ||
563 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) | ||
564 | .collect(); | ||
565 | let alias_eq_bound = rust_ir::AliasEqBound { | ||
566 | value: ty.clone().to_chalk(db), | ||
567 | trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, | ||
568 | associated_ty_id: projection_ty.associated_ty_id, | ||
569 | parameters: Vec::new(), // FIXME we don't support generic associated types yet | ||
570 | }; | ||
571 | Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), pred.num_binders)) | ||
572 | } | ||
573 | _ => None, | ||
574 | } | ||
575 | } | ||