diff options
Diffstat (limited to 'crates/ra_hir_ty/src/traits/chalk')
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/interner.rs | 32 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/mapping.rs | 286 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/tls.rs | 33 |
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 | |||
22 | pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; | 22 | pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; |
23 | pub type FnDefId = chalk_ir::FnDefId<Interner>; | 23 | pub type FnDefId = chalk_ir::FnDefId<Interner>; |
24 | pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; | 24 | pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; |
25 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | ||
26 | pub type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; | ||
25 | 27 | ||
26 | impl chalk_ir::interner::Interner for Interner { | 28 | impl 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 | ||
351 | impl chalk_ir::interner::HasInterner for Interner { | 381 | 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 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 | ||
15 | use crate::{ | 15 | use 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 | ||
23 | use super::interner::*; | 23 | use 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 | ||
125 | const LIFETIME_PLACEHOLDER: PlaceholderIndex = | 151 | const 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. | ||
188 | fn 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. | ||
207 | fn 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 | |||
160 | impl ToChalk for Substs { | 215 | impl 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 | ||
262 | impl 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 | |||
207 | impl ToChalk for TypeCtor { | 277 | impl 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 | ||
358 | impl ToChalk for Impl { | 445 | impl 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 | ||
370 | impl ToChalk for CallableDef { | 457 | impl 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 | ||
394 | impl ToChalk for AssocTyValue { | 481 | pub struct TypeAliasAsValue(pub TypeAliasId); |
482 | |||
483 | impl 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 | ||
581 | impl 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 | |||
605 | impl 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 | |||
627 | pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> | 703 | pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> |
628 | where | 704 | where |
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 | |||
5 | use itertools::Itertools; | 5 | use itertools::Itertools; |
6 | 6 | ||
7 | use super::{from_chalk, Interner}; | 7 | use super::{from_chalk, Interner}; |
8 | use crate::{db::HirDatabase, CallableDef, TypeCtor}; | 8 | use crate::{db::HirDatabase, CallableDefId, TypeCtor}; |
9 | use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId}; | 9 | use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId}; |
10 | 10 | ||
11 | pub use unsafe_tls::{set_current_program, with_current_program}; | 11 | pub use unsafe_tls::{set_current_program, with_current_program}; |
12 | 12 | ||
13 | pub struct DebugContext<'a>(&'a (dyn HirDatabase + 'a)); | 13 | pub struct DebugContext<'a>(&'a dyn HirDatabase); |
14 | 14 | ||
15 | impl DebugContext<'_> { | 15 | impl 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 {}", ¶ms[0], trait_data.name,)?; | 161 | write!(fmt, "<{:?} as {}", ¶ms[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 | } |