diff options
Diffstat (limited to 'crates/ra_hir_ty/src/traits/chalk')
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/interner.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/mapping.rs | 62 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/tls.rs | 2 |
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 | ||
354 | impl chalk_ir::interner::HasInterner for Interner { | 369 | impl 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 | ||
145 | const LIFETIME_PLACEHOLDER: PlaceholderIndex = | 147 | const 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. | ||
184 | fn 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. | ||
203 | fn 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 | |||
180 | impl ToChalk for Substs { | 211 | impl 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 {}", ¶ms[0], trait_data.name,)?; | 161 | write!(fmt, "<{:?} as {}", ¶ms[0], trait_data.name,)?; |
162 | if params.len() > 1 { | 162 | if params.len() > 1 { |
163 | write!( | 163 | write!( |