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.rs32
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/mapping.rs286
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/tls.rs33
3 files changed, 231 insertions, 120 deletions
diff --git a/crates/ra_hir_ty/src/traits/chalk/interner.rs b/crates/ra_hir_ty/src/traits/chalk/interner.rs
index e27074ba6..8d4c51a8f 100644
--- a/crates/ra_hir_ty/src/traits/chalk/interner.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/interner.rs
@@ -22,6 +22,8 @@ pub type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interne
22pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; 22pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>;
23pub type FnDefId = chalk_ir::FnDefId<Interner>; 23pub type FnDefId = chalk_ir::FnDefId<Interner>;
24pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; 24pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>;
25pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
26pub type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>;
25 27
26impl chalk_ir::interner::Interner for Interner { 28impl chalk_ir::interner::Interner for Interner {
27 type InternedType = Box<chalk_ir::TyData<Self>>; // FIXME use Arc? 29 type InternedType = Box<chalk_ir::TyData<Self>>; // FIXME use Arc?
@@ -37,9 +39,11 @@ impl chalk_ir::interner::Interner for Interner {
37 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; 39 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
38 type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>; 40 type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>;
39 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>>>;
40 type DefId = InternId; 43 type DefId = InternId;
41 type InternedAdtId = crate::TypeCtorId; 44 type InternedAdtId = hir_def::AdtId;
42 type Identifier = TypeAliasId; 45 type Identifier = TypeAliasId;
46 type FnAbi = ();
43 47
44 fn debug_adt_id(type_kind_id: AdtId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> { 48 fn debug_adt_id(type_kind_id: AdtId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
45 tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt))) 49 tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt)))
@@ -346,6 +350,32 @@ impl chalk_ir::interner::Interner for Interner {
346 ) -> &'a [chalk_ir::CanonicalVarKind<Self>] { 350 ) -> &'a [chalk_ir::CanonicalVarKind<Self>] {
347 &canonical_var_kinds 351 &canonical_var_kinds
348 } 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 }
367 fn debug_closure_id(
368 _fn_def_id: chalk_ir::ClosureId<Self>,
369 _fmt: &mut fmt::Formatter<'_>,
370 ) -> Option<fmt::Result> {
371 None
372 }
373 fn debug_constraints(
374 _clauses: &chalk_ir::Constraints<Self>,
375 _fmt: &mut fmt::Formatter<'_>,
376 ) -> Option<fmt::Result> {
377 None
378 }
349} 379}
350 380
351impl chalk_ir::interner::HasInterner for Interner { 381impl 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 5f6daf842..09d8347ca 100644
--- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs
@@ -14,10 +14,10 @@ use ra_db::salsa::InternKey;
14 14
15use crate::{ 15use crate::{
16 db::HirDatabase, 16 db::HirDatabase,
17 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}, 17 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness},
18 traits::{builtin, AssocTyValue, Canonical, Impl, Obligation}, 18 traits::{Canonical, Obligation},
19 ApplicationTy, CallableDef, GenericPredicate, InEnvironment, ProjectionPredicate, ProjectionTy, 19 ApplicationTy, CallableDefId, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId,
20 Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, 20 ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor,
21}; 21};
22 22
23use super::interner::*; 23use super::interner::*;
@@ -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,14 +63,26 @@ 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 { bounds: make_binders(where_clauses, 1) }; 70 let bounded_ty = chalk_ir::DynTy {
71 bounds: make_binders(where_clauses, 1),
72 lifetime: FAKE_PLACEHOLDER.to_lifetime(&Interner),
73 };
69 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner) 74 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner)
70 } 75 }
71 Ty::Opaque(_) | Ty::Unknown => { 76 Ty::Opaque(opaque_ty) => {
77 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db);
78 let substitution = opaque_ty.parameters.to_chalk(db);
79 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
80 opaque_ty_id,
81 substitution,
82 }))
83 .intern(&Interner)
84 }
85 Ty::Unknown => {
72 let substitution = chalk_ir::Substitution::empty(&Interner); 86 let substitution = chalk_ir::Substitution::empty(&Interner);
73 let name = TypeName::Error; 87 let name = TypeName::Error;
74 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) 88 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
@@ -80,6 +94,7 @@ impl ToChalk for Ty {
80 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { 94 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name {
81 TypeName::Error => Ty::Unknown, 95 TypeName::Error => Ty::Unknown,
82 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),
83 _ => { 98 _ => {
84 let ctor = from_chalk(db, apply_ty.name); 99 let ctor = from_chalk(db, apply_ty.name);
85 let parameters = from_chalk(db, apply_ty.substitution); 100 let parameters = from_chalk(db, apply_ty.substitution);
@@ -98,11 +113,22 @@ impl ToChalk for Ty {
98 let parameters = from_chalk(db, proj.substitution); 113 let parameters = from_chalk(db, proj.substitution);
99 Ty::Projection(ProjectionTy { associated_ty, parameters }) 114 Ty::Projection(ProjectionTy { associated_ty, parameters })
100 } 115 }
101 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(_)) => unimplemented!(), 116 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => {
102 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => { 117 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id);
103 let parameters: Substs = from_chalk(db, substitution); 118 let parameters = from_chalk(db, opaque_ty.substitution);
119 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })
120 }
121 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders, 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 );
104 Ty::Apply(ApplicationTy { 127 Ty::Apply(ApplicationTy {
105 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 },
106 parameters, 132 parameters,
107 }) 133 })
108 } 134 }
@@ -122,7 +148,7 @@ impl ToChalk for Ty {
122 } 148 }
123} 149}
124 150
125const LIFETIME_PLACEHOLDER: PlaceholderIndex = 151const FAKE_PLACEHOLDER: PlaceholderIndex =
126 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX }; 152 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX };
127 153
128/// 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
@@ -133,10 +159,10 @@ fn ref_to_chalk(
133 subst: Substs, 159 subst: Substs,
134) -> chalk_ir::Ty<Interner> { 160) -> chalk_ir::Ty<Interner> {
135 let arg = subst[0].clone().to_chalk(db); 161 let arg = subst[0].clone().to_chalk(db);
136 let lifetime = LIFETIME_PLACEHOLDER.to_lifetime(&Interner); 162 let lifetime = FAKE_PLACEHOLDER.to_lifetime(&Interner);
137 chalk_ir::ApplicationTy { 163 chalk_ir::ApplicationTy {
138 name: TypeName::Ref(mutability.to_chalk(db)), 164 name: TypeName::Ref(mutability.to_chalk(db)),
139 substitution: chalk_ir::Substitution::from( 165 substitution: chalk_ir::Substitution::from_iter(
140 &Interner, 166 &Interner,
141 vec![lifetime.cast(&Interner), arg.cast(&Interner)], 167 vec![lifetime.cast(&Interner), arg.cast(&Interner)],
142 ), 168 ),
@@ -157,11 +183,40 @@ fn ref_from_chalk(
157 Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys)) 183 Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys))
158} 184}
159 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
160impl ToChalk for Substs { 215impl ToChalk for Substs {
161 type Chalk = chalk_ir::Substitution<Interner>; 216 type Chalk = chalk_ir::Substitution<Interner>;
162 217
163 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> { 218 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
164 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)))
165 } 220 }
166 221
167 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 {
@@ -204,6 +259,21 @@ impl ToChalk for hir_def::TraitId {
204 } 259 }
205} 260}
206 261
262impl ToChalk for OpaqueTyId {
263 type Chalk = chalk_ir::OpaqueTyId<Interner>;
264
265 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::OpaqueTyId<Interner> {
266 db.intern_impl_trait_id(self).into()
267 }
268
269 fn from_chalk(
270 db: &dyn HirDatabase,
271 opaque_ty_id: chalk_ir::OpaqueTyId<Interner>,
272 ) -> OpaqueTyId {
273 db.lookup_intern_impl_trait_id(opaque_ty_id.into())
274 }
275}
276
207impl ToChalk for TypeCtor { 277impl ToChalk for TypeCtor {
208 type Chalk = TypeName<Interner>; 278 type Chalk = TypeName<Interner>;
209 279
@@ -214,19 +284,25 @@ impl ToChalk for TypeCtor {
214 TypeName::AssociatedType(type_id) 284 TypeName::AssociatedType(type_id)
215 } 285 }
216 286
287 TypeCtor::OpaqueType(impl_trait_id) => {
288 let id = impl_trait_id.to_chalk(db);
289 TypeName::OpaqueType(id)
290 }
291
217 TypeCtor::Bool => TypeName::Scalar(Scalar::Bool), 292 TypeCtor::Bool => TypeName::Scalar(Scalar::Bool),
218 TypeCtor::Char => TypeName::Scalar(Scalar::Char), 293 TypeCtor::Char => TypeName::Scalar(Scalar::Char),
219 TypeCtor::Int(Uncertain::Known(int_ty)) => TypeName::Scalar(int_ty_to_chalk(int_ty)), 294 TypeCtor::Int(int_ty) => TypeName::Scalar(int_ty_to_chalk(int_ty)),
220 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X32 })) => { 295 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => {
221 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) 296 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32))
222 } 297 }
223 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X64 })) => { 298 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => {
224 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) 299 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64))
225 } 300 }
226 301
227 TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()), 302 TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()),
228 TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)), 303 TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)),
229 TypeCtor::Slice => TypeName::Slice, 304 TypeCtor::Slice => TypeName::Slice,
305 TypeCtor::Array => TypeName::Array,
230 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)), 306 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
231 TypeCtor::Str => TypeName::Str, 307 TypeCtor::Str => TypeName::Str,
232 TypeCtor::FnDef(callable_def) => { 308 TypeCtor::FnDef(callable_def) => {
@@ -235,40 +311,44 @@ impl ToChalk for TypeCtor {
235 } 311 }
236 TypeCtor::Never => TypeName::Never, 312 TypeCtor::Never => TypeName::Never,
237 313
238 TypeCtor::Int(Uncertain::Unknown) 314 TypeCtor::Closure { def, expr } => {
239 | TypeCtor::Float(Uncertain::Unknown) 315 let closure_id = db.intern_closure((def, expr));
240 | TypeCtor::Adt(_) 316 TypeName::Closure(closure_id.into())
241 | TypeCtor::Array 317 }
242 | TypeCtor::FnPtr { .. } 318
243 | TypeCtor::Closure { .. } => { 319 TypeCtor::Adt(adt_id) => TypeName::Adt(chalk_ir::AdtId(adt_id)),
244 // other TypeCtors get interned and turned into a chalk StructId 320
245 let struct_id = db.intern_type_ctor(self).into(); 321 TypeCtor::FnPtr { .. } => {
246 TypeName::Adt(struct_id) 322 // This should not be reached, since Chalk doesn't represent
323 // function pointers with TypeName
324 unreachable!()
247 } 325 }
248 } 326 }
249 } 327 }
250 328
251 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor { 329 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor {
252 match type_name { 330 match type_name {
253 TypeName::Adt(struct_id) => db.lookup_intern_type_ctor(struct_id.into()), 331 TypeName::Adt(struct_id) => TypeCtor::Adt(struct_id.0),
254 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), 332 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
255 TypeName::OpaqueType(_) => unreachable!(), 333 TypeName::OpaqueType(opaque_type_id) => {
334 TypeCtor::OpaqueType(from_chalk(db, opaque_type_id))
335 }
256 336
257 TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool, 337 TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool,
258 TypeName::Scalar(Scalar::Char) => TypeCtor::Char, 338 TypeName::Scalar(Scalar::Char) => TypeCtor::Char,
259 TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(Uncertain::Known(IntTy { 339 TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(IntTy {
260 signedness: Signedness::Signed, 340 signedness: Signedness::Signed,
261 bitness: bitness_from_chalk_int(int_ty), 341 bitness: bitness_from_chalk_int(int_ty),
262 })), 342 }),
263 TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(Uncertain::Known(IntTy { 343 TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(IntTy {
264 signedness: Signedness::Unsigned, 344 signedness: Signedness::Unsigned,
265 bitness: bitness_from_chalk_uint(uint_ty), 345 bitness: bitness_from_chalk_uint(uint_ty),
266 })), 346 }),
267 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => { 347 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => {
268 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X32 })) 348 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })
269 } 349 }
270 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => { 350 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => {
271 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X64 })) 351 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })
272 } 352 }
273 TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 }, 353 TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 },
274 TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)), 354 TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)),
@@ -281,8 +361,15 @@ impl ToChalk for TypeCtor {
281 let callable_def = from_chalk(db, fn_def_id); 361 let callable_def = from_chalk(db, fn_def_id);
282 TypeCtor::FnDef(callable_def) 362 TypeCtor::FnDef(callable_def)
283 } 363 }
364 TypeName::Array => TypeCtor::Array,
284 365
285 TypeName::Array | TypeName::Error => { 366 TypeName::Closure(id) => {
367 let id: crate::db::ClosureId = id.into();
368 let (def, expr) = db.lookup_intern_closure(id);
369 TypeCtor::Closure { def, expr }
370 }
371
372 TypeName::Error => {
286 // this should not be reached, since we don't represent TypeName::Error with TypeCtor 373 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
287 unreachable!() 374 unreachable!()
288 } 375 }
@@ -355,26 +442,26 @@ impl ToChalk for Mutability {
355 } 442 }
356} 443}
357 444
358impl ToChalk for Impl { 445impl ToChalk for hir_def::ImplId {
359 type Chalk = ImplId; 446 type Chalk = ImplId;
360 447
361 fn to_chalk(self, db: &dyn HirDatabase) -> ImplId { 448 fn to_chalk(self, _db: &dyn HirDatabase) -> ImplId {
362 db.intern_chalk_impl(self).into() 449 chalk_ir::ImplId(self.as_intern_id())
363 } 450 }
364 451
365 fn from_chalk(db: &dyn HirDatabase, impl_id: ImplId) -> Impl { 452 fn from_chalk(_db: &dyn HirDatabase, impl_id: ImplId) -> hir_def::ImplId {
366 db.lookup_intern_chalk_impl(impl_id.into()) 453 InternKey::from_intern_id(impl_id.0)
367 } 454 }
368} 455}
369 456
370impl ToChalk for CallableDef { 457impl ToChalk for CallableDefId {
371 type Chalk = FnDefId; 458 type Chalk = FnDefId;
372 459
373 fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId { 460 fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId {
374 db.intern_callable_def(self).into() 461 db.intern_callable_def(self).into()
375 } 462 }
376 463
377 fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDef { 464 fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId {
378 db.lookup_intern_callable_def(fn_def_id.into()) 465 db.lookup_intern_callable_def(fn_def_id.into())
379 } 466 }
380} 467}
@@ -391,15 +478,20 @@ impl ToChalk for TypeAliasId {
391 } 478 }
392} 479}
393 480
394impl ToChalk for AssocTyValue { 481pub struct TypeAliasAsValue(pub TypeAliasId);
482
483impl ToChalk for TypeAliasAsValue {
395 type Chalk = AssociatedTyValueId; 484 type Chalk = AssociatedTyValueId;
396 485
397 fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValueId { 486 fn to_chalk(self, _db: &dyn HirDatabase) -> AssociatedTyValueId {
398 db.intern_assoc_ty_value(self).into() 487 rust_ir::AssociatedTyValueId(self.0.as_intern_id())
399 } 488 }
400 489
401 fn from_chalk(db: &dyn HirDatabase, assoc_ty_value_id: AssociatedTyValueId) -> AssocTyValue { 490 fn from_chalk(
402 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))
403 } 495 }
404} 496}
405 497
@@ -447,6 +539,16 @@ impl ToChalk for GenericPredicate {
447 let ty = from_chalk(db, projection_eq.ty); 539 let ty = from_chalk(db, projection_eq.ty);
448 GenericPredicate::Projection(ProjectionPredicate { projection_ty, ty }) 540 GenericPredicate::Projection(ProjectionPredicate { projection_ty, ty })
449 } 541 }
542
543 chalk_ir::WhereClause::LifetimeOutlives(_) => {
544 // we shouldn't get these from Chalk
545 panic!("encountered LifetimeOutlives from Chalk")
546 }
547
548 chalk_ir::WhereClause::TypeOutlives(_) => {
549 // we shouldn't get these from Chalk
550 panic!("encountered TypeOutlives from Chalk")
551 }
450 } 552 }
451 } 553 }
452} 554}
@@ -510,22 +612,42 @@ where
510 type Chalk = chalk_ir::Canonical<T::Chalk>; 612 type Chalk = chalk_ir::Canonical<T::Chalk>;
511 613
512 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> { 614 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> {
513 let parameter = chalk_ir::CanonicalVarKind::new( 615 let kinds = self
514 chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General), 616 .kinds
515 chalk_ir::UniverseIndex::ROOT, 617 .iter()
516 ); 618 .map(|k| match k {
619 TyKind::General => chalk_ir::TyKind::General,
620 TyKind::Integer => chalk_ir::TyKind::Integer,
621 TyKind::Float => chalk_ir::TyKind::Float,
622 })
623 .map(|tk| {
624 chalk_ir::CanonicalVarKind::new(
625 chalk_ir::VariableKind::Ty(tk),
626 chalk_ir::UniverseIndex::ROOT,
627 )
628 });
517 let value = self.value.to_chalk(db); 629 let value = self.value.to_chalk(db);
518 chalk_ir::Canonical { 630 chalk_ir::Canonical {
519 value, 631 value,
520 binders: chalk_ir::CanonicalVarKinds::from(&Interner, vec![parameter; self.num_vars]), 632 binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds),
521 } 633 }
522 } 634 }
523 635
524 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> {
525 Canonical { 637 let kinds = canonical
526 num_vars: canonical.binders.len(&Interner), 638 .binders
527 value: from_chalk(db, canonical.value), 639 .iter(&Interner)
528 } 640 .map(|k| match k.kind {
641 chalk_ir::VariableKind::Ty(tk) => match tk {
642 chalk_ir::TyKind::General => TyKind::General,
643 chalk_ir::TyKind::Integer => TyKind::Integer,
644 chalk_ir::TyKind::Float => TyKind::Float,
645 },
646 chalk_ir::VariableKind::Lifetime => panic!("unexpected lifetime from Chalk"),
647 chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"),
648 })
649 .collect();
650 Canonical { kinds, value: from_chalk(db, canonical.value) }
529 } 651 }
530} 652}
531 653
@@ -578,58 +700,12 @@ where
578 } 700 }
579} 701}
580 702
581impl ToChalk for builtin::BuiltinImplData {
582 type Chalk = ImplDatum;
583
584 fn to_chalk(self, db: &dyn HirDatabase) -> ImplDatum {
585 let impl_type = rust_ir::ImplType::External;
586 let where_clauses = self.where_clauses.into_iter().map(|w| w.to_chalk(db)).collect();
587
588 let impl_datum_bound =
589 rust_ir::ImplDatumBound { trait_ref: self.trait_ref.to_chalk(db), where_clauses };
590 let associated_ty_value_ids =
591 self.assoc_ty_values.into_iter().map(|v| v.to_chalk(db)).collect();
592 rust_ir::ImplDatum {
593 binders: make_binders(impl_datum_bound, self.num_vars),
594 impl_type,
595 polarity: rust_ir::Polarity::Positive,
596 associated_ty_value_ids,
597 }
598 }
599
600 fn from_chalk(_db: &dyn HirDatabase, _data: ImplDatum) -> Self {
601 unimplemented!()
602 }
603}
604
605impl ToChalk for builtin::BuiltinImplAssocTyValueData {
606 type Chalk = AssociatedTyValue;
607
608 fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValue {
609 let ty = self.value.to_chalk(db);
610 let value_bound = rust_ir::AssociatedTyValueBound { ty };
611
612 rust_ir::AssociatedTyValue {
613 associated_ty_id: self.assoc_ty_id.to_chalk(db),
614 impl_id: self.impl_.to_chalk(db),
615 value: make_binders(value_bound, self.num_vars),
616 }
617 }
618
619 fn from_chalk(
620 _db: &dyn HirDatabase,
621 _data: AssociatedTyValue,
622 ) -> builtin::BuiltinImplAssocTyValueData {
623 unimplemented!()
624 }
625}
626
627pub(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>
628where 704where
629 T: HasInterner<Interner = Interner>, 705 T: HasInterner<Interner = Interner>,
630{ 706{
631 chalk_ir::Binders::new( 707 chalk_ir::Binders::new(
632 chalk_ir::VariableKinds::from( 708 chalk_ir::VariableKinds::from_iter(
633 &Interner, 709 &Interner,
634 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),
635 ), 711 ),
diff --git a/crates/ra_hir_ty/src/traits/chalk/tls.rs b/crates/ra_hir_ty/src/traits/chalk/tls.rs
index d88828c7c..db915625c 100644
--- a/crates/ra_hir_ty/src/traits/chalk/tls.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/tls.rs
@@ -5,12 +5,12 @@ use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplicat
5use itertools::Itertools; 5use itertools::Itertools;
6 6
7use super::{from_chalk, Interner}; 7use super::{from_chalk, Interner};
8use crate::{db::HirDatabase, CallableDef, TypeCtor}; 8use crate::{db::HirDatabase, CallableDefId, TypeCtor};
9use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId}; 9use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId};
10 10
11pub use unsafe_tls::{set_current_program, with_current_program}; 11pub use unsafe_tls::{set_current_program, with_current_program};
12 12
13pub struct DebugContext<'a>(&'a (dyn HirDatabase + 'a)); 13pub struct DebugContext<'a>(&'a dyn HirDatabase);
14 14
15impl DebugContext<'_> { 15impl DebugContext<'_> {
16 pub fn debug_struct_id( 16 pub fn debug_struct_id(
@@ -38,16 +38,16 @@ impl DebugContext<'_> {
38 } 38 }
39 TypeCtor::FnDef(def) => { 39 TypeCtor::FnDef(def) => {
40 let name = match def { 40 let name = match def {
41 CallableDef::FunctionId(ff) => self.0.function_data(ff).name.clone(), 41 CallableDefId::FunctionId(ff) => self.0.function_data(ff).name.clone(),
42 CallableDef::StructId(s) => self.0.struct_data(s).name.clone(), 42 CallableDefId::StructId(s) => self.0.struct_data(s).name.clone(),
43 CallableDef::EnumVariantId(e) => { 43 CallableDefId::EnumVariantId(e) => {
44 let enum_data = self.0.enum_data(e.parent); 44 let enum_data = self.0.enum_data(e.parent);
45 enum_data.variants[e.local_id].name.clone() 45 enum_data.variants[e.local_id].name.clone()
46 } 46 }
47 }; 47 };
48 match def { 48 match def {
49 CallableDef::FunctionId(_) => write!(f, "{{fn {}}}", name)?, 49 CallableDefId::FunctionId(_) => write!(f, "{{fn {}}}", name)?,
50 CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => { 50 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {
51 write!(f, "{{ctor {}}}", name)? 51 write!(f, "{{ctor {}}}", name)?
52 } 52 }
53 } 53 }
@@ -69,6 +69,11 @@ impl DebugContext<'_> {
69 let name = self.0.type_alias_data(type_alias).name.clone(); 69 let name = self.0.type_alias_data(type_alias).name.clone();
70 write!(f, "{}::{}", trait_name, name)?; 70 write!(f, "{}::{}", trait_name, name)?;
71 } 71 }
72 TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id {
73 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
74 write!(f, "{{impl trait {} of {:?}}}", idx, func)?;
75 }
76 },
72 TypeCtor::Closure { def, expr } => { 77 TypeCtor::Closure { def, expr } => {
73 write!(f, "{{closure {:?} in ", expr.into_raw())?; 78 write!(f, "{{closure {:?} in ", expr.into_raw())?;
74 match def { 79 match def {
@@ -152,7 +157,7 @@ impl DebugContext<'_> {
152 _ => panic!("associated type not in trait"), 157 _ => panic!("associated type not in trait"),
153 }; 158 };
154 let trait_data = self.0.trait_data(trait_); 159 let trait_data = self.0.trait_data(trait_);
155 let params = projection_ty.substitution.parameters(&Interner); 160 let params = projection_ty.substitution.as_slice(&Interner);
156 write!(fmt, "<{:?} as {}", &params[0], trait_data.name,)?; 161 write!(fmt, "<{:?} as {}", &params[0], trait_data.name,)?;
157 if params.len() > 1 { 162 if params.len() > 1 {
158 write!( 163 write!(
@@ -250,18 +255,18 @@ impl DebugContext<'_> {
250 fn_def_id: chalk_ir::FnDefId<Interner>, 255 fn_def_id: chalk_ir::FnDefId<Interner>,
251 fmt: &mut fmt::Formatter<'_>, 256 fmt: &mut fmt::Formatter<'_>,
252 ) -> Result<(), fmt::Error> { 257 ) -> Result<(), fmt::Error> {
253 let def: CallableDef = from_chalk(self.0, fn_def_id); 258 let def: CallableDefId = from_chalk(self.0, fn_def_id);
254 let name = match def { 259 let name = match def {
255 CallableDef::FunctionId(ff) => self.0.function_data(ff).name.clone(), 260 CallableDefId::FunctionId(ff) => self.0.function_data(ff).name.clone(),
256 CallableDef::StructId(s) => self.0.struct_data(s).name.clone(), 261 CallableDefId::StructId(s) => self.0.struct_data(s).name.clone(),
257 CallableDef::EnumVariantId(e) => { 262 CallableDefId::EnumVariantId(e) => {
258 let enum_data = self.0.enum_data(e.parent); 263 let enum_data = self.0.enum_data(e.parent);
259 enum_data.variants[e.local_id].name.clone() 264 enum_data.variants[e.local_id].name.clone()
260 } 265 }
261 }; 266 };
262 match def { 267 match def {
263 CallableDef::FunctionId(_) => write!(fmt, "{{fn {}}}", name), 268 CallableDefId::FunctionId(_) => write!(fmt, "{{fn {}}}", name),
264 CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => { 269 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {
265 write!(fmt, "{{ctor {}}}", name) 270 write!(fmt, "{{ctor {}}}", name)
266 } 271 }
267 } 272 }