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.rs62
1 files changed, 50 insertions, 12 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..7dc9ee759 100644
--- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs
@@ -29,6 +29,7 @@ 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::Array => array_to_chalk(db, apply_ty.parameters),
32 TypeCtor::FnPtr { num_args: _ } => { 33 TypeCtor::FnPtr { num_args: _ } => {
33 let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); 34 let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner);
34 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution }) 35 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution })
@@ -61,13 +62,13 @@ impl ToChalk for Ty {
61 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner), 62 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner),
62 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 63 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
63 Ty::Dyn(predicates) => { 64 Ty::Dyn(predicates) => {
64 let where_clauses = chalk_ir::QuantifiedWhereClauses::from( 65 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
65 &Interner, 66 &Interner,
66 predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)), 67 predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)),
67 ); 68 );
68 let bounded_ty = chalk_ir::DynTy { 69 let bounded_ty = chalk_ir::DynTy {
69 bounds: make_binders(where_clauses, 1), 70 bounds: make_binders(where_clauses, 1),
70 lifetime: LIFETIME_PLACEHOLDER.to_lifetime(&Interner), 71 lifetime: FAKE_PLACEHOLDER.to_lifetime(&Interner),
71 }; 72 };
72 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner) 73 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner)
73 } 74 }
@@ -92,6 +93,7 @@ impl ToChalk for Ty {
92 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { 93 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name {
93 TypeName::Error => Ty::Unknown, 94 TypeName::Error => Ty::Unknown,
94 TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution), 95 TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution),
96 TypeName::Array => array_from_chalk(db, apply_ty.substitution),
95 _ => { 97 _ => {
96 let ctor = from_chalk(db, apply_ty.name); 98 let ctor = from_chalk(db, apply_ty.name);
97 let parameters = from_chalk(db, apply_ty.substitution); 99 let parameters = from_chalk(db, apply_ty.substitution);
@@ -138,7 +140,7 @@ impl ToChalk for Ty {
138 } 140 }
139} 141}
140 142
141const LIFETIME_PLACEHOLDER: PlaceholderIndex = 143const FAKE_PLACEHOLDER: PlaceholderIndex =
142 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX }; 144 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX };
143 145
144/// We currently don't model lifetimes, but Chalk does. So, we have to insert a 146/// We currently don't model lifetimes, but Chalk does. So, we have to insert a
@@ -149,10 +151,10 @@ fn ref_to_chalk(
149 subst: Substs, 151 subst: Substs,
150) -> chalk_ir::Ty<Interner> { 152) -> chalk_ir::Ty<Interner> {
151 let arg = subst[0].clone().to_chalk(db); 153 let arg = subst[0].clone().to_chalk(db);
152 let lifetime = LIFETIME_PLACEHOLDER.to_lifetime(&Interner); 154 let lifetime = FAKE_PLACEHOLDER.to_lifetime(&Interner);
153 chalk_ir::ApplicationTy { 155 chalk_ir::ApplicationTy {
154 name: TypeName::Ref(mutability.to_chalk(db)), 156 name: TypeName::Ref(mutability.to_chalk(db)),
155 substitution: chalk_ir::Substitution::from( 157 substitution: chalk_ir::Substitution::from_iter(
156 &Interner, 158 &Interner,
157 vec![lifetime.cast(&Interner), arg.cast(&Interner)], 159 vec![lifetime.cast(&Interner), arg.cast(&Interner)],
158 ), 160 ),
@@ -173,11 +175,40 @@ fn ref_from_chalk(
173 Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys)) 175 Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys))
174} 176}
175 177
178/// We currently don't model constants, but Chalk does. So, we have to insert a
179/// fake constant here, because Chalks built-in logic may expect it to be there.
180fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> {
181 let arg = subst[0].clone().to_chalk(db);
182 let usize_ty = chalk_ir::ApplicationTy {
183 name: TypeName::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)),
184 substitution: chalk_ir::Substitution::empty(&Interner),
185 }
186 .intern(&Interner);
187 let const_ = FAKE_PLACEHOLDER.to_const(&Interner, usize_ty);
188 chalk_ir::ApplicationTy {
189 name: TypeName::Array,
190 substitution: chalk_ir::Substitution::from_iter(
191 &Interner,
192 vec![arg.cast(&Interner), const_.cast(&Interner)],
193 ),
194 }
195 .intern(&Interner)
196}
197
198/// Here we remove the const from the type we got from Chalk.
199fn array_from_chalk(db: &dyn HirDatabase, subst: chalk_ir::Substitution<Interner>) -> Ty {
200 let tys = subst
201 .iter(&Interner)
202 .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone())))
203 .collect();
204 Ty::apply(TypeCtor::Array, Substs(tys))
205}
206
176impl ToChalk for Substs { 207impl ToChalk for Substs {
177 type Chalk = chalk_ir::Substitution<Interner>; 208 type Chalk = chalk_ir::Substitution<Interner>;
178 209
179 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> { 210 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))) 211 chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
181 } 212 }
182 213
183 fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs { 214 fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs {
@@ -263,6 +294,7 @@ impl ToChalk for TypeCtor {
263 TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()), 294 TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()),
264 TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)), 295 TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)),
265 TypeCtor::Slice => TypeName::Slice, 296 TypeCtor::Slice => TypeName::Slice,
297 TypeCtor::Array => TypeName::Array,
266 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)), 298 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
267 TypeCtor::Str => TypeName::Str, 299 TypeCtor::Str => TypeName::Str,
268 TypeCtor::FnDef(callable_def) => { 300 TypeCtor::FnDef(callable_def) => {
@@ -271,10 +303,8 @@ impl ToChalk for TypeCtor {
271 } 303 }
272 TypeCtor::Never => TypeName::Never, 304 TypeCtor::Never => TypeName::Never,
273 305
274 TypeCtor::Adt(_) 306 // FIXME convert these
275 | TypeCtor::Array 307 TypeCtor::Adt(_) | TypeCtor::FnPtr { .. } | TypeCtor::Closure { .. } => {
276 | TypeCtor::FnPtr { .. }
277 | TypeCtor::Closure { .. } => {
278 // other TypeCtors get interned and turned into a chalk StructId 308 // other TypeCtors get interned and turned into a chalk StructId
279 let struct_id = db.intern_type_ctor(self).into(); 309 let struct_id = db.intern_type_ctor(self).into();
280 TypeName::Adt(struct_id) 310 TypeName::Adt(struct_id)
@@ -492,6 +522,11 @@ impl ToChalk for GenericPredicate {
492 // we shouldn't get these from Chalk 522 // we shouldn't get these from Chalk
493 panic!("encountered LifetimeOutlives from Chalk") 523 panic!("encountered LifetimeOutlives from Chalk")
494 } 524 }
525
526 chalk_ir::WhereClause::TypeOutlives(_) => {
527 // we shouldn't get these from Chalk
528 panic!("encountered TypeOutlives from Chalk")
529 }
495 } 530 }
496 } 531 }
497} 532}
@@ -570,7 +605,10 @@ where
570 ) 605 )
571 }); 606 });
572 let value = self.value.to_chalk(db); 607 let value = self.value.to_chalk(db);
573 chalk_ir::Canonical { value, binders: chalk_ir::CanonicalVarKinds::from(&Interner, kinds) } 608 chalk_ir::Canonical {
609 value,
610 binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds),
611 }
574 } 612 }
575 613
576 fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> { 614 fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
@@ -691,7 +729,7 @@ where
691 T: HasInterner<Interner = Interner>, 729 T: HasInterner<Interner = Interner>,
692{ 730{
693 chalk_ir::Binders::new( 731 chalk_ir::Binders::new(
694 chalk_ir::VariableKinds::from( 732 chalk_ir::VariableKinds::from_iter(
695 &Interner, 733 &Interner,
696 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars), 734 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars),
697 ), 735 ),