aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/traits/chalk
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/traits/chalk')
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/interner.rs15
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/mapping.rs62
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/tls.rs2
3 files changed, 66 insertions, 13 deletions
diff --git a/crates/ra_hir_ty/src/traits/chalk/interner.rs b/crates/ra_hir_ty/src/traits/chalk/interner.rs
index 15426b022..156b691b4 100644
--- a/crates/ra_hir_ty/src/traits/chalk/interner.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/interner.rs
@@ -39,6 +39,7 @@ impl chalk_ir::interner::Interner for Interner {
39 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; 39 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
40 type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>; 40 type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>;
41 type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>; 41 type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>;
42 type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>;
42 type DefId = InternId; 43 type DefId = InternId;
43 type InternedAdtId = crate::TypeCtorId; 44 type InternedAdtId = crate::TypeCtorId;
44 type Identifier = TypeAliasId; 45 type Identifier = TypeAliasId;
@@ -349,6 +350,20 @@ impl chalk_ir::interner::Interner for Interner {
349 ) -> &'a [chalk_ir::CanonicalVarKind<Self>] { 350 ) -> &'a [chalk_ir::CanonicalVarKind<Self>] {
350 &canonical_var_kinds 351 &canonical_var_kinds
351 } 352 }
353
354 fn intern_constraints<E>(
355 &self,
356 data: impl IntoIterator<Item = Result<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>, E>>,
357 ) -> Result<Self::InternedConstraints, E> {
358 data.into_iter().collect()
359 }
360
361 fn constraints_data<'a>(
362 &self,
363 constraints: &'a Self::InternedConstraints,
364 ) -> &'a [chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
365 constraints
366 }
352} 367}
353 368
354impl chalk_ir::interner::HasInterner for Interner { 369impl chalk_ir::interner::HasInterner for Interner {
diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs
index cb354d586..06453ef82 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);
@@ -142,7 +144,7 @@ impl ToChalk for Ty {
142 } 144 }
143} 145}
144 146
145const LIFETIME_PLACEHOLDER: PlaceholderIndex = 147const FAKE_PLACEHOLDER: PlaceholderIndex =
146 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX }; 148 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX };
147 149
148/// We currently don't model lifetimes, but Chalk does. So, we have to insert a 150/// We currently don't model lifetimes, but Chalk does. So, we have to insert a
@@ -153,10 +155,10 @@ fn ref_to_chalk(
153 subst: Substs, 155 subst: Substs,
154) -> chalk_ir::Ty<Interner> { 156) -> chalk_ir::Ty<Interner> {
155 let arg = subst[0].clone().to_chalk(db); 157 let arg = subst[0].clone().to_chalk(db);
156 let lifetime = LIFETIME_PLACEHOLDER.to_lifetime(&Interner); 158 let lifetime = FAKE_PLACEHOLDER.to_lifetime(&Interner);
157 chalk_ir::ApplicationTy { 159 chalk_ir::ApplicationTy {
158 name: TypeName::Ref(mutability.to_chalk(db)), 160 name: TypeName::Ref(mutability.to_chalk(db)),
159 substitution: chalk_ir::Substitution::from( 161 substitution: chalk_ir::Substitution::from_iter(
160 &Interner, 162 &Interner,
161 vec![lifetime.cast(&Interner), arg.cast(&Interner)], 163 vec![lifetime.cast(&Interner), arg.cast(&Interner)],
162 ), 164 ),
@@ -177,11 +179,40 @@ fn ref_from_chalk(
177 Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys)) 179 Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys))
178} 180}
179 181
182/// We currently don't model constants, but Chalk does. So, we have to insert a
183/// fake constant here, because Chalks built-in logic may expect it to be there.
184fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> {
185 let arg = subst[0].clone().to_chalk(db);
186 let usize_ty = chalk_ir::ApplicationTy {
187 name: TypeName::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)),
188 substitution: chalk_ir::Substitution::empty(&Interner),
189 }
190 .intern(&Interner);
191 let const_ = FAKE_PLACEHOLDER.to_const(&Interner, usize_ty);
192 chalk_ir::ApplicationTy {
193 name: TypeName::Array,
194 substitution: chalk_ir::Substitution::from_iter(
195 &Interner,
196 vec![arg.cast(&Interner), const_.cast(&Interner)],
197 ),
198 }
199 .intern(&Interner)
200}
201
202/// Here we remove the const from the type we got from Chalk.
203fn array_from_chalk(db: &dyn HirDatabase, subst: chalk_ir::Substitution<Interner>) -> Ty {
204 let tys = subst
205 .iter(&Interner)
206 .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone())))
207 .collect();
208 Ty::apply(TypeCtor::Array, Substs(tys))
209}
210
180impl ToChalk for Substs { 211impl ToChalk for Substs {
181 type Chalk = chalk_ir::Substitution<Interner>; 212 type Chalk = chalk_ir::Substitution<Interner>;
182 213
183 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> { 214 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
184 chalk_ir::Substitution::from(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db))) 215 chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
185 } 216 }
186 217
187 fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs { 218 fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs {
@@ -267,6 +298,7 @@ impl ToChalk for TypeCtor {
267 TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()), 298 TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()),
268 TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)), 299 TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)),
269 TypeCtor::Slice => TypeName::Slice, 300 TypeCtor::Slice => TypeName::Slice,
301 TypeCtor::Array => TypeName::Array,
270 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)), 302 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
271 TypeCtor::Str => TypeName::Str, 303 TypeCtor::Str => TypeName::Str,
272 TypeCtor::FnDef(callable_def) => { 304 TypeCtor::FnDef(callable_def) => {
@@ -275,10 +307,8 @@ impl ToChalk for TypeCtor {
275 } 307 }
276 TypeCtor::Never => TypeName::Never, 308 TypeCtor::Never => TypeName::Never,
277 309
278 TypeCtor::Adt(_) 310 // FIXME convert these
279 | TypeCtor::Array 311 TypeCtor::Adt(_) | TypeCtor::FnPtr { .. } | TypeCtor::Closure { .. } => {
280 | TypeCtor::FnPtr { .. }
281 | TypeCtor::Closure { .. } => {
282 // other TypeCtors get interned and turned into a chalk StructId 312 // other TypeCtors get interned and turned into a chalk StructId
283 let struct_id = db.intern_type_ctor(self).into(); 313 let struct_id = db.intern_type_ctor(self).into();
284 TypeName::Adt(struct_id) 314 TypeName::Adt(struct_id)
@@ -496,6 +526,11 @@ impl ToChalk for GenericPredicate {
496 // we shouldn't get these from Chalk 526 // we shouldn't get these from Chalk
497 panic!("encountered LifetimeOutlives from Chalk") 527 panic!("encountered LifetimeOutlives from Chalk")
498 } 528 }
529
530 chalk_ir::WhereClause::TypeOutlives(_) => {
531 // we shouldn't get these from Chalk
532 panic!("encountered TypeOutlives from Chalk")
533 }
499 } 534 }
500 } 535 }
501} 536}
@@ -574,7 +609,10 @@ where
574 ) 609 )
575 }); 610 });
576 let value = self.value.to_chalk(db); 611 let value = self.value.to_chalk(db);
577 chalk_ir::Canonical { value, binders: chalk_ir::CanonicalVarKinds::from(&Interner, kinds) } 612 chalk_ir::Canonical {
613 value,
614 binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds),
615 }
578 } 616 }
579 617
580 fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> { 618 fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
@@ -695,7 +733,7 @@ where
695 T: HasInterner<Interner = Interner>, 733 T: HasInterner<Interner = Interner>,
696{ 734{
697 chalk_ir::Binders::new( 735 chalk_ir::Binders::new(
698 chalk_ir::VariableKinds::from( 736 chalk_ir::VariableKinds::from_iter(
699 &Interner, 737 &Interner,
700 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars), 738 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars),
701 ), 739 ),
diff --git a/crates/ra_hir_ty/src/traits/chalk/tls.rs b/crates/ra_hir_ty/src/traits/chalk/tls.rs
index e6a9d3211..1e226baea 100644
--- a/crates/ra_hir_ty/src/traits/chalk/tls.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/tls.rs
@@ -157,7 +157,7 @@ impl DebugContext<'_> {
157 _ => panic!("associated type not in trait"), 157 _ => panic!("associated type not in trait"),
158 }; 158 };
159 let trait_data = self.0.trait_data(trait_); 159 let trait_data = self.0.trait_data(trait_);
160 let params = projection_ty.substitution.parameters(&Interner); 160 let params = projection_ty.substitution.as_slice(&Interner);
161 write!(fmt, "<{:?} as {}", &params[0], trait_data.name,)?; 161 write!(fmt, "<{:?} as {}", &params[0], trait_data.name,)?;
162 if params.len() > 1 { 162 if params.len() > 1 {
163 write!( 163 write!(