aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/traits/chalk/mapping.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/traits/chalk/mapping.rs')
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/mapping.rs184
1 files changed, 99 insertions, 85 deletions
diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs
index 433d6aa03..09d8347ca 100644
--- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs
@@ -15,8 +15,8 @@ use ra_db::salsa::InternKey;
15use crate::{ 15use crate::{
16 db::HirDatabase, 16 db::HirDatabase,
17 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness}, 17 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness},
18 traits::{builtin, AssocTyValue, Canonical, Impl, Obligation}, 18 traits::{Canonical, Obligation},
19 ApplicationTy, CallableDef, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, 19 ApplicationTy, CallableDefId, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId,
20 ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor, 20 ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor,
21}; 21};
22 22
@@ -29,7 +29,9 @@ impl ToChalk for Ty {
29 match self { 29 match self {
30 Ty::Apply(apply_ty) => match apply_ty.ctor { 30 Ty::Apply(apply_ty) => match apply_ty.ctor {
31 TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), 31 TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters),
32 TypeCtor::FnPtr { num_args: _ } => { 32 TypeCtor::Array => array_to_chalk(db, apply_ty.parameters),
33 TypeCtor::FnPtr { num_args: _, is_varargs: _ } => {
34 // FIXME: handle is_varargs
33 let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); 35 let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner);
34 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution }) 36 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution })
35 .intern(&Interner) 37 .intern(&Interner)
@@ -61,13 +63,13 @@ impl ToChalk for Ty {
61 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner), 63 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner),
62 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 64 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
63 Ty::Dyn(predicates) => { 65 Ty::Dyn(predicates) => {
64 let where_clauses = chalk_ir::QuantifiedWhereClauses::from( 66 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
65 &Interner, 67 &Interner,
66 predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)), 68 predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)),
67 ); 69 );
68 let bounded_ty = chalk_ir::DynTy { 70 let bounded_ty = chalk_ir::DynTy {
69 bounds: make_binders(where_clauses, 1), 71 bounds: make_binders(where_clauses, 1),
70 lifetime: LIFETIME_PLACEHOLDER.to_lifetime(&Interner), 72 lifetime: FAKE_PLACEHOLDER.to_lifetime(&Interner),
71 }; 73 };
72 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner) 74 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner)
73 } 75 }
@@ -92,6 +94,7 @@ impl ToChalk for Ty {
92 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { 94 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name {
93 TypeName::Error => Ty::Unknown, 95 TypeName::Error => Ty::Unknown,
94 TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution), 96 TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution),
97 TypeName::Array => array_from_chalk(db, apply_ty.substitution),
95 _ => { 98 _ => {
96 let ctor = from_chalk(db, apply_ty.name); 99 let ctor = from_chalk(db, apply_ty.name);
97 let parameters = from_chalk(db, apply_ty.substitution); 100 let parameters = from_chalk(db, apply_ty.substitution);
@@ -115,10 +118,17 @@ impl ToChalk for Ty {
115 let parameters = from_chalk(db, opaque_ty.substitution); 118 let parameters = from_chalk(db, opaque_ty.substitution);
116 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) 119 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })
117 } 120 }
118 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => { 121 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders, substitution }) => {
119 let parameters: Substs = from_chalk(db, substitution); 122 assert_eq!(num_binders, 0);
123 let parameters: Substs = from_chalk(
124 db,
125 substitution.shifted_out(&Interner).expect("fn ptr should have no binders"),
126 );
120 Ty::Apply(ApplicationTy { 127 Ty::Apply(ApplicationTy {
121 ctor: TypeCtor::FnPtr { num_args: (parameters.len() - 1) as u16 }, 128 ctor: TypeCtor::FnPtr {
129 num_args: (parameters.len() - 1) as u16,
130 is_varargs: false,
131 },
122 parameters, 132 parameters,
123 }) 133 })
124 } 134 }
@@ -138,7 +148,7 @@ impl ToChalk for Ty {
138 } 148 }
139} 149}
140 150
141const LIFETIME_PLACEHOLDER: PlaceholderIndex = 151const FAKE_PLACEHOLDER: PlaceholderIndex =
142 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX }; 152 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX };
143 153
144/// We currently don't model lifetimes, but Chalk does. So, we have to insert a 154/// We currently don't model lifetimes, but Chalk does. So, we have to insert a
@@ -149,10 +159,10 @@ fn ref_to_chalk(
149 subst: Substs, 159 subst: Substs,
150) -> chalk_ir::Ty<Interner> { 160) -> chalk_ir::Ty<Interner> {
151 let arg = subst[0].clone().to_chalk(db); 161 let arg = subst[0].clone().to_chalk(db);
152 let lifetime = LIFETIME_PLACEHOLDER.to_lifetime(&Interner); 162 let lifetime = FAKE_PLACEHOLDER.to_lifetime(&Interner);
153 chalk_ir::ApplicationTy { 163 chalk_ir::ApplicationTy {
154 name: TypeName::Ref(mutability.to_chalk(db)), 164 name: TypeName::Ref(mutability.to_chalk(db)),
155 substitution: chalk_ir::Substitution::from( 165 substitution: chalk_ir::Substitution::from_iter(
156 &Interner, 166 &Interner,
157 vec![lifetime.cast(&Interner), arg.cast(&Interner)], 167 vec![lifetime.cast(&Interner), arg.cast(&Interner)],
158 ), 168 ),
@@ -173,11 +183,40 @@ fn ref_from_chalk(
173 Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys)) 183 Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys))
174} 184}
175 185
186/// We currently don't model constants, but Chalk does. So, we have to insert a
187/// fake constant here, because Chalks built-in logic may expect it to be there.
188fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> {
189 let arg = subst[0].clone().to_chalk(db);
190 let usize_ty = chalk_ir::ApplicationTy {
191 name: TypeName::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)),
192 substitution: chalk_ir::Substitution::empty(&Interner),
193 }
194 .intern(&Interner);
195 let const_ = FAKE_PLACEHOLDER.to_const(&Interner, usize_ty);
196 chalk_ir::ApplicationTy {
197 name: TypeName::Array,
198 substitution: chalk_ir::Substitution::from_iter(
199 &Interner,
200 vec![arg.cast(&Interner), const_.cast(&Interner)],
201 ),
202 }
203 .intern(&Interner)
204}
205
206/// Here we remove the const from the type we got from Chalk.
207fn array_from_chalk(db: &dyn HirDatabase, subst: chalk_ir::Substitution<Interner>) -> Ty {
208 let tys = subst
209 .iter(&Interner)
210 .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone())))
211 .collect();
212 Ty::apply(TypeCtor::Array, Substs(tys))
213}
214
176impl ToChalk for Substs { 215impl ToChalk for Substs {
177 type Chalk = chalk_ir::Substitution<Interner>; 216 type Chalk = chalk_ir::Substitution<Interner>;
178 217
179 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> { 218 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
180 chalk_ir::Substitution::from(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db))) 219 chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
181 } 220 }
182 221
183 fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs { 222 fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs {
@@ -263,6 +302,7 @@ impl ToChalk for TypeCtor {
263 TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()), 302 TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()),
264 TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)), 303 TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)),
265 TypeCtor::Slice => TypeName::Slice, 304 TypeCtor::Slice => TypeName::Slice,
305 TypeCtor::Array => TypeName::Array,
266 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)), 306 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
267 TypeCtor::Str => TypeName::Str, 307 TypeCtor::Str => TypeName::Str,
268 TypeCtor::FnDef(callable_def) => { 308 TypeCtor::FnDef(callable_def) => {
@@ -271,20 +311,24 @@ impl ToChalk for TypeCtor {
271 } 311 }
272 TypeCtor::Never => TypeName::Never, 312 TypeCtor::Never => TypeName::Never,
273 313
274 TypeCtor::Adt(_) 314 TypeCtor::Closure { def, expr } => {
275 | TypeCtor::Array 315 let closure_id = db.intern_closure((def, expr));
276 | TypeCtor::FnPtr { .. } 316 TypeName::Closure(closure_id.into())
277 | TypeCtor::Closure { .. } => { 317 }
278 // other TypeCtors get interned and turned into a chalk StructId 318
279 let struct_id = db.intern_type_ctor(self).into(); 319 TypeCtor::Adt(adt_id) => TypeName::Adt(chalk_ir::AdtId(adt_id)),
280 TypeName::Adt(struct_id) 320
321 TypeCtor::FnPtr { .. } => {
322 // This should not be reached, since Chalk doesn't represent
323 // function pointers with TypeName
324 unreachable!()
281 } 325 }
282 } 326 }
283 } 327 }
284 328
285 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor { 329 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor {
286 match type_name { 330 match type_name {
287 TypeName::Adt(struct_id) => db.lookup_intern_type_ctor(struct_id.into()), 331 TypeName::Adt(struct_id) => TypeCtor::Adt(struct_id.0),
288 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), 332 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
289 TypeName::OpaqueType(opaque_type_id) => { 333 TypeName::OpaqueType(opaque_type_id) => {
290 TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)) 334 TypeCtor::OpaqueType(from_chalk(db, opaque_type_id))
@@ -317,13 +361,16 @@ impl ToChalk for TypeCtor {
317 let callable_def = from_chalk(db, fn_def_id); 361 let callable_def = from_chalk(db, fn_def_id);
318 TypeCtor::FnDef(callable_def) 362 TypeCtor::FnDef(callable_def)
319 } 363 }
364 TypeName::Array => TypeCtor::Array,
320 365
321 TypeName::Array | TypeName::Error => { 366 TypeName::Closure(id) => {
322 // this should not be reached, since we don't represent TypeName::Error with TypeCtor 367 let id: crate::db::ClosureId = id.into();
323 unreachable!() 368 let (def, expr) = db.lookup_intern_closure(id);
369 TypeCtor::Closure { def, expr }
324 } 370 }
325 TypeName::Closure(_) => { 371
326 // FIXME: implement closure support 372 TypeName::Error => {
373 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
327 unreachable!() 374 unreachable!()
328 } 375 }
329 } 376 }
@@ -395,26 +442,26 @@ impl ToChalk for Mutability {
395 } 442 }
396} 443}
397 444
398impl ToChalk for Impl { 445impl ToChalk for hir_def::ImplId {
399 type Chalk = ImplId; 446 type Chalk = ImplId;
400 447
401 fn to_chalk(self, db: &dyn HirDatabase) -> ImplId { 448 fn to_chalk(self, _db: &dyn HirDatabase) -> ImplId {
402 db.intern_chalk_impl(self).into() 449 chalk_ir::ImplId(self.as_intern_id())
403 } 450 }
404 451
405 fn from_chalk(db: &dyn HirDatabase, impl_id: ImplId) -> Impl { 452 fn from_chalk(_db: &dyn HirDatabase, impl_id: ImplId) -> hir_def::ImplId {
406 db.lookup_intern_chalk_impl(impl_id.into()) 453 InternKey::from_intern_id(impl_id.0)
407 } 454 }
408} 455}
409 456
410impl ToChalk for CallableDef { 457impl ToChalk for CallableDefId {
411 type Chalk = FnDefId; 458 type Chalk = FnDefId;
412 459
413 fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId { 460 fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId {
414 db.intern_callable_def(self).into() 461 db.intern_callable_def(self).into()
415 } 462 }
416 463
417 fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDef { 464 fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId {
418 db.lookup_intern_callable_def(fn_def_id.into()) 465 db.lookup_intern_callable_def(fn_def_id.into())
419 } 466 }
420} 467}
@@ -431,15 +478,20 @@ impl ToChalk for TypeAliasId {
431 } 478 }
432} 479}
433 480
434impl ToChalk for AssocTyValue { 481pub struct TypeAliasAsValue(pub TypeAliasId);
482
483impl ToChalk for TypeAliasAsValue {
435 type Chalk = AssociatedTyValueId; 484 type Chalk = AssociatedTyValueId;
436 485
437 fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValueId { 486 fn to_chalk(self, _db: &dyn HirDatabase) -> AssociatedTyValueId {
438 db.intern_assoc_ty_value(self).into() 487 rust_ir::AssociatedTyValueId(self.0.as_intern_id())
439 } 488 }
440 489
441 fn from_chalk(db: &dyn HirDatabase, assoc_ty_value_id: AssociatedTyValueId) -> AssocTyValue { 490 fn from_chalk(
442 db.lookup_intern_assoc_ty_value(assoc_ty_value_id.into()) 491 _db: &dyn HirDatabase,
492 assoc_ty_value_id: AssociatedTyValueId,
493 ) -> TypeAliasAsValue {
494 TypeAliasAsValue(TypeAliasId::from_intern_id(assoc_ty_value_id.0))
443 } 495 }
444} 496}
445 497
@@ -492,6 +544,11 @@ impl ToChalk for GenericPredicate {
492 // we shouldn't get these from Chalk 544 // we shouldn't get these from Chalk
493 panic!("encountered LifetimeOutlives from Chalk") 545 panic!("encountered LifetimeOutlives from Chalk")
494 } 546 }
547
548 chalk_ir::WhereClause::TypeOutlives(_) => {
549 // we shouldn't get these from Chalk
550 panic!("encountered TypeOutlives from Chalk")
551 }
495 } 552 }
496 } 553 }
497} 554}
@@ -570,7 +627,10 @@ where
570 ) 627 )
571 }); 628 });
572 let value = self.value.to_chalk(db); 629 let value = self.value.to_chalk(db);
573 chalk_ir::Canonical { value, binders: chalk_ir::CanonicalVarKinds::from(&Interner, kinds) } 630 chalk_ir::Canonical {
631 value,
632 binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds),
633 }
574 } 634 }
575 635
576 fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> { 636 fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
@@ -640,58 +700,12 @@ where
640 } 700 }
641} 701}
642 702
643impl ToChalk for builtin::BuiltinImplData {
644 type Chalk = ImplDatum;
645
646 fn to_chalk(self, db: &dyn HirDatabase) -> ImplDatum {
647 let impl_type = rust_ir::ImplType::External;
648 let where_clauses = self.where_clauses.into_iter().map(|w| w.to_chalk(db)).collect();
649
650 let impl_datum_bound =
651 rust_ir::ImplDatumBound { trait_ref: self.trait_ref.to_chalk(db), where_clauses };
652 let associated_ty_value_ids =
653 self.assoc_ty_values.into_iter().map(|v| v.to_chalk(db)).collect();
654 rust_ir::ImplDatum {
655 binders: make_binders(impl_datum_bound, self.num_vars),
656 impl_type,
657 polarity: rust_ir::Polarity::Positive,
658 associated_ty_value_ids,
659 }
660 }
661
662 fn from_chalk(_db: &dyn HirDatabase, _data: ImplDatum) -> Self {
663 unimplemented!()
664 }
665}
666
667impl ToChalk for builtin::BuiltinImplAssocTyValueData {
668 type Chalk = AssociatedTyValue;
669
670 fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValue {
671 let ty = self.value.to_chalk(db);
672 let value_bound = rust_ir::AssociatedTyValueBound { ty };
673
674 rust_ir::AssociatedTyValue {
675 associated_ty_id: self.assoc_ty_id.to_chalk(db),
676 impl_id: self.impl_.to_chalk(db),
677 value: make_binders(value_bound, self.num_vars),
678 }
679 }
680
681 fn from_chalk(
682 _db: &dyn HirDatabase,
683 _data: AssociatedTyValue,
684 ) -> builtin::BuiltinImplAssocTyValueData {
685 unimplemented!()
686 }
687}
688
689pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> 703pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T>
690where 704where
691 T: HasInterner<Interner = Interner>, 705 T: HasInterner<Interner = Interner>,
692{ 706{
693 chalk_ir::Binders::new( 707 chalk_ir::Binders::new(
694 chalk_ir::VariableKinds::from( 708 chalk_ir::VariableKinds::from_iter(
695 &Interner, 709 &Interner,
696 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars), 710 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars),
697 ), 711 ),