diff options
Diffstat (limited to 'crates/ra_hir/src/ty/traits')
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 110 |
1 files changed, 70 insertions, 40 deletions
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 00aaf65d9..ad7c11a5a 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -4,8 +4,8 @@ use std::sync::Arc; | |||
4 | use log::debug; | 4 | use log::debug; |
5 | 5 | ||
6 | use chalk_ir::{ | 6 | use chalk_ir::{ |
7 | cast::Cast, Identifier, ImplId, Parameter, PlaceholderIndex, TypeId, TypeKindId, TypeName, | 7 | cast::Cast, family::ChalkIr, Identifier, ImplId, Parameter, PlaceholderIndex, TypeId, |
8 | UniverseIndex, | 8 | TypeKindId, TypeName, UniverseIndex, |
9 | }; | 9 | }; |
10 | use chalk_rust_ir::{AssociatedTyDatum, ImplDatum, StructDatum, TraitDatum}; | 10 | use chalk_rust_ir::{AssociatedTyDatum, ImplDatum, StructDatum, TraitDatum}; |
11 | 11 | ||
@@ -38,8 +38,8 @@ where | |||
38 | } | 38 | } |
39 | 39 | ||
40 | impl ToChalk for Ty { | 40 | impl ToChalk for Ty { |
41 | type Chalk = chalk_ir::Ty; | 41 | type Chalk = chalk_ir::Ty<ChalkIr>; |
42 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty { | 42 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty<ChalkIr> { |
43 | match self { | 43 | match self { |
44 | Ty::Apply(apply_ty) => { | 44 | Ty::Apply(apply_ty) => { |
45 | let name = match apply_ty.ctor { | 45 | let name = match apply_ty.ctor { |
@@ -62,21 +62,21 @@ impl ToChalk for Ty { | |||
62 | chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast() | 62 | chalk_ir::ProjectionTy { associated_ty_id, parameters }.cast() |
63 | } | 63 | } |
64 | Ty::Param { idx, .. } => { | 64 | Ty::Param { idx, .. } => { |
65 | PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }.to_ty() | 65 | PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize }.to_ty::<ChalkIr>() |
66 | } | 66 | } |
67 | Ty::Bound(idx) => chalk_ir::Ty::BoundVar(idx as usize), | 67 | Ty::Bound(idx) => chalk_ir::Ty::BoundVar(idx as usize), |
68 | Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), | 68 | Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), |
69 | // FIXME this is clearly incorrect, but probably not too incorrect | 69 | // FIXME this is clearly incorrect, but probably not too incorrect |
70 | // and I'm not sure what to actually do with Ty::Unknown | 70 | // and I'm not sure what to actually do with Ty::Unknown |
71 | // maybe an alternative would be `for<T> T`? (meaningless in rust, but expressible in chalk's Ty) | 71 | // maybe an alternative would be `for<T> T`? (meaningless in rust, but expressible in chalk's Ty) |
72 | // | 72 | // FIXME use Chalk's Dyn/Opaque once the bugs with that are fixed |
73 | // FIXME also dyn and impl Trait are currently handled like Unknown because Chalk doesn't have them yet | ||
74 | Ty::Unknown | Ty::Dyn(_) | Ty::Opaque(_) => { | 73 | Ty::Unknown | Ty::Dyn(_) | Ty::Opaque(_) => { |
75 | PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::max_value() }.to_ty() | 74 | PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::max_value() } |
75 | .to_ty::<ChalkIr>() | ||
76 | } | 76 | } |
77 | } | 77 | } |
78 | } | 78 | } |
79 | fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty) -> Self { | 79 | fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty<ChalkIr>) -> Self { |
80 | match chalk { | 80 | match chalk { |
81 | chalk_ir::Ty::Apply(apply_ty) => { | 81 | chalk_ir::Ty::Apply(apply_ty) => { |
82 | // FIXME this is kind of hacky due to the fact that | 82 | // FIXME this is kind of hacky due to the fact that |
@@ -108,18 +108,30 @@ impl ToChalk for Ty { | |||
108 | chalk_ir::Ty::ForAll(_) => unimplemented!(), | 108 | chalk_ir::Ty::ForAll(_) => unimplemented!(), |
109 | chalk_ir::Ty::BoundVar(idx) => Ty::Bound(idx as u32), | 109 | chalk_ir::Ty::BoundVar(idx) => Ty::Bound(idx as u32), |
110 | chalk_ir::Ty::InferenceVar(_iv) => Ty::Unknown, | 110 | chalk_ir::Ty::InferenceVar(_iv) => Ty::Unknown, |
111 | chalk_ir::Ty::Dyn(where_clauses) => { | ||
112 | assert_eq!(where_clauses.binders.len(), 1); | ||
113 | let predicates = | ||
114 | where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect(); | ||
115 | Ty::Dyn(predicates) | ||
116 | } | ||
117 | chalk_ir::Ty::Opaque(where_clauses) => { | ||
118 | assert_eq!(where_clauses.binders.len(), 1); | ||
119 | let predicates = | ||
120 | where_clauses.value.into_iter().map(|c| from_chalk(db, c)).collect(); | ||
121 | Ty::Opaque(predicates) | ||
122 | } | ||
111 | } | 123 | } |
112 | } | 124 | } |
113 | } | 125 | } |
114 | 126 | ||
115 | impl ToChalk for Substs { | 127 | impl ToChalk for Substs { |
116 | type Chalk = Vec<chalk_ir::Parameter>; | 128 | type Chalk = Vec<chalk_ir::Parameter<ChalkIr>>; |
117 | 129 | ||
118 | fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter> { | 130 | fn to_chalk(self, db: &impl HirDatabase) -> Vec<Parameter<ChalkIr>> { |
119 | self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect() | 131 | self.iter().map(|ty| ty.clone().to_chalk(db).cast()).collect() |
120 | } | 132 | } |
121 | 133 | ||
122 | fn from_chalk(db: &impl HirDatabase, parameters: Vec<chalk_ir::Parameter>) -> Substs { | 134 | fn from_chalk(db: &impl HirDatabase, parameters: Vec<chalk_ir::Parameter<ChalkIr>>) -> Substs { |
123 | let tys = parameters | 135 | let tys = parameters |
124 | .into_iter() | 136 | .into_iter() |
125 | .map(|p| match p { | 137 | .map(|p| match p { |
@@ -132,15 +144,15 @@ impl ToChalk for Substs { | |||
132 | } | 144 | } |
133 | 145 | ||
134 | impl ToChalk for TraitRef { | 146 | impl ToChalk for TraitRef { |
135 | type Chalk = chalk_ir::TraitRef; | 147 | type Chalk = chalk_ir::TraitRef<ChalkIr>; |
136 | 148 | ||
137 | fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef { | 149 | fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef<ChalkIr> { |
138 | let trait_id = self.trait_.to_chalk(db); | 150 | let trait_id = self.trait_.to_chalk(db); |
139 | let parameters = self.substs.to_chalk(db); | 151 | let parameters = self.substs.to_chalk(db); |
140 | chalk_ir::TraitRef { trait_id, parameters } | 152 | chalk_ir::TraitRef { trait_id, parameters } |
141 | } | 153 | } |
142 | 154 | ||
143 | fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef) -> Self { | 155 | fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef<ChalkIr>) -> Self { |
144 | let trait_ = from_chalk(db, trait_ref.trait_id); | 156 | let trait_ = from_chalk(db, trait_ref.trait_id); |
145 | let substs = from_chalk(db, trait_ref.parameters); | 157 | let substs = from_chalk(db, trait_ref.parameters); |
146 | TraitRef { trait_, substs } | 158 | TraitRef { trait_, substs } |
@@ -196,9 +208,9 @@ impl ToChalk for TypeAlias { | |||
196 | } | 208 | } |
197 | 209 | ||
198 | impl ToChalk for GenericPredicate { | 210 | impl ToChalk for GenericPredicate { |
199 | type Chalk = chalk_ir::QuantifiedWhereClause; | 211 | type Chalk = chalk_ir::QuantifiedWhereClause<ChalkIr>; |
200 | 212 | ||
201 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause { | 213 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause<ChalkIr> { |
202 | match self { | 214 | match self { |
203 | GenericPredicate::Implemented(trait_ref) => { | 215 | GenericPredicate::Implemented(trait_ref) => { |
204 | make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) | 216 | make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) |
@@ -221,25 +233,40 @@ impl ToChalk for GenericPredicate { | |||
221 | } | 233 | } |
222 | 234 | ||
223 | fn from_chalk( | 235 | fn from_chalk( |
224 | _db: &impl HirDatabase, | 236 | db: &impl HirDatabase, |
225 | _where_clause: chalk_ir::QuantifiedWhereClause, | 237 | where_clause: chalk_ir::QuantifiedWhereClause<ChalkIr>, |
226 | ) -> GenericPredicate { | 238 | ) -> GenericPredicate { |
227 | // This should never need to be called | 239 | match where_clause.value { |
228 | unimplemented!() | 240 | chalk_ir::WhereClause::Implemented(tr) => { |
241 | if tr.trait_id == UNKNOWN_TRAIT { | ||
242 | // FIXME we need an Error enum on the Chalk side to avoid this | ||
243 | return GenericPredicate::Error; | ||
244 | } | ||
245 | GenericPredicate::Implemented(from_chalk(db, tr)) | ||
246 | } | ||
247 | chalk_ir::WhereClause::ProjectionEq(projection_eq) => { | ||
248 | let projection_ty = from_chalk(db, projection_eq.projection); | ||
249 | let ty = from_chalk(db, projection_eq.ty); | ||
250 | GenericPredicate::Projection(super::ProjectionPredicate { projection_ty, ty }) | ||
251 | } | ||
252 | } | ||
229 | } | 253 | } |
230 | } | 254 | } |
231 | 255 | ||
232 | impl ToChalk for ProjectionTy { | 256 | impl ToChalk for ProjectionTy { |
233 | type Chalk = chalk_ir::ProjectionTy; | 257 | type Chalk = chalk_ir::ProjectionTy<ChalkIr>; |
234 | 258 | ||
235 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy { | 259 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ProjectionTy<ChalkIr> { |
236 | chalk_ir::ProjectionTy { | 260 | chalk_ir::ProjectionTy { |
237 | associated_ty_id: self.associated_ty.to_chalk(db), | 261 | associated_ty_id: self.associated_ty.to_chalk(db), |
238 | parameters: self.parameters.to_chalk(db), | 262 | parameters: self.parameters.to_chalk(db), |
239 | } | 263 | } |
240 | } | 264 | } |
241 | 265 | ||
242 | fn from_chalk(db: &impl HirDatabase, projection_ty: chalk_ir::ProjectionTy) -> ProjectionTy { | 266 | fn from_chalk( |
267 | db: &impl HirDatabase, | ||
268 | projection_ty: chalk_ir::ProjectionTy<ChalkIr>, | ||
269 | ) -> ProjectionTy { | ||
243 | ProjectionTy { | 270 | ProjectionTy { |
244 | associated_ty: from_chalk(db, projection_ty.associated_ty_id), | 271 | associated_ty: from_chalk(db, projection_ty.associated_ty_id), |
245 | parameters: from_chalk(db, projection_ty.parameters), | 272 | parameters: from_chalk(db, projection_ty.parameters), |
@@ -248,31 +275,31 @@ impl ToChalk for ProjectionTy { | |||
248 | } | 275 | } |
249 | 276 | ||
250 | impl ToChalk for super::ProjectionPredicate { | 277 | impl ToChalk for super::ProjectionPredicate { |
251 | type Chalk = chalk_ir::Normalize; | 278 | type Chalk = chalk_ir::Normalize<ChalkIr>; |
252 | 279 | ||
253 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize { | 280 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize<ChalkIr> { |
254 | chalk_ir::Normalize { | 281 | chalk_ir::Normalize { |
255 | projection: self.projection_ty.to_chalk(db), | 282 | projection: self.projection_ty.to_chalk(db), |
256 | ty: self.ty.to_chalk(db), | 283 | ty: self.ty.to_chalk(db), |
257 | } | 284 | } |
258 | } | 285 | } |
259 | 286 | ||
260 | fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize) -> Self { | 287 | fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize<ChalkIr>) -> Self { |
261 | unimplemented!() | 288 | unimplemented!() |
262 | } | 289 | } |
263 | } | 290 | } |
264 | 291 | ||
265 | impl ToChalk for Obligation { | 292 | impl ToChalk for Obligation { |
266 | type Chalk = chalk_ir::DomainGoal; | 293 | type Chalk = chalk_ir::DomainGoal<ChalkIr>; |
267 | 294 | ||
268 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal { | 295 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal<ChalkIr> { |
269 | match self { | 296 | match self { |
270 | Obligation::Trait(tr) => tr.to_chalk(db).cast(), | 297 | Obligation::Trait(tr) => tr.to_chalk(db).cast(), |
271 | Obligation::Projection(pr) => pr.to_chalk(db).cast(), | 298 | Obligation::Projection(pr) => pr.to_chalk(db).cast(), |
272 | } | 299 | } |
273 | } | 300 | } |
274 | 301 | ||
275 | fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal) -> Self { | 302 | fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal<ChalkIr>) -> Self { |
276 | unimplemented!() | 303 | unimplemented!() |
277 | } | 304 | } |
278 | } | 305 | } |
@@ -296,16 +323,16 @@ where | |||
296 | } | 323 | } |
297 | 324 | ||
298 | impl ToChalk for Arc<super::TraitEnvironment> { | 325 | impl ToChalk for Arc<super::TraitEnvironment> { |
299 | type Chalk = Arc<chalk_ir::Environment>; | 326 | type Chalk = Arc<chalk_ir::Environment<ChalkIr>>; |
300 | 327 | ||
301 | fn to_chalk(self, db: &impl HirDatabase) -> Arc<chalk_ir::Environment> { | 328 | fn to_chalk(self, db: &impl HirDatabase) -> Arc<chalk_ir::Environment<ChalkIr>> { |
302 | let mut clauses = Vec::new(); | 329 | let mut clauses = Vec::new(); |
303 | for pred in &self.predicates { | 330 | for pred in &self.predicates { |
304 | if pred.is_error() { | 331 | if pred.is_error() { |
305 | // for env, we just ignore errors | 332 | // for env, we just ignore errors |
306 | continue; | 333 | continue; |
307 | } | 334 | } |
308 | let program_clause: chalk_ir::ProgramClause = pred.clone().to_chalk(db).cast(); | 335 | let program_clause: chalk_ir::ProgramClause<ChalkIr> = pred.clone().to_chalk(db).cast(); |
309 | clauses.push(program_clause.into_from_env_clause()); | 336 | clauses.push(program_clause.into_from_env_clause()); |
310 | } | 337 | } |
311 | chalk_ir::Environment::new().add_clauses(clauses) | 338 | chalk_ir::Environment::new().add_clauses(clauses) |
@@ -313,13 +340,16 @@ impl ToChalk for Arc<super::TraitEnvironment> { | |||
313 | 340 | ||
314 | fn from_chalk( | 341 | fn from_chalk( |
315 | _db: &impl HirDatabase, | 342 | _db: &impl HirDatabase, |
316 | _env: Arc<chalk_ir::Environment>, | 343 | _env: Arc<chalk_ir::Environment<ChalkIr>>, |
317 | ) -> Arc<super::TraitEnvironment> { | 344 | ) -> Arc<super::TraitEnvironment> { |
318 | unimplemented!() | 345 | unimplemented!() |
319 | } | 346 | } |
320 | } | 347 | } |
321 | 348 | ||
322 | impl<T: ToChalk> ToChalk for super::InEnvironment<T> { | 349 | impl<T: ToChalk> ToChalk for super::InEnvironment<T> |
350 | where | ||
351 | T::Chalk: chalk_ir::family::HasTypeFamily<TypeFamily = ChalkIr>, | ||
352 | { | ||
323 | type Chalk = chalk_ir::InEnvironment<T::Chalk>; | 353 | type Chalk = chalk_ir::InEnvironment<T::Chalk>; |
324 | 354 | ||
325 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> { | 355 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> { |
@@ -351,7 +381,7 @@ fn convert_where_clauses( | |||
351 | db: &impl HirDatabase, | 381 | db: &impl HirDatabase, |
352 | def: GenericDef, | 382 | def: GenericDef, |
353 | substs: &Substs, | 383 | substs: &Substs, |
354 | ) -> Vec<chalk_ir::QuantifiedWhereClause> { | 384 | ) -> Vec<chalk_ir::QuantifiedWhereClause<ChalkIr>> { |
355 | let generic_predicates = db.generic_predicates(def); | 385 | let generic_predicates = db.generic_predicates(def); |
356 | let mut result = Vec::with_capacity(generic_predicates.len()); | 386 | let mut result = Vec::with_capacity(generic_predicates.len()); |
357 | for pred in generic_predicates.iter() { | 387 | for pred in generic_predicates.iter() { |
@@ -384,7 +414,7 @@ where | |||
384 | fn impls_for_trait( | 414 | fn impls_for_trait( |
385 | &self, | 415 | &self, |
386 | trait_id: chalk_ir::TraitId, | 416 | trait_id: chalk_ir::TraitId, |
387 | parameters: &[Parameter], | 417 | parameters: &[Parameter<ChalkIr>], |
388 | ) -> Vec<ImplId> { | 418 | ) -> Vec<ImplId> { |
389 | debug!("impls_for_trait {:?}", trait_id); | 419 | debug!("impls_for_trait {:?}", trait_id); |
390 | if trait_id == UNKNOWN_TRAIT { | 420 | if trait_id == UNKNOWN_TRAIT { |
@@ -430,13 +460,13 @@ where | |||
430 | } | 460 | } |
431 | fn split_projection<'p>( | 461 | fn split_projection<'p>( |
432 | &self, | 462 | &self, |
433 | projection: &'p chalk_ir::ProjectionTy, | 463 | projection: &'p chalk_ir::ProjectionTy<ChalkIr>, |
434 | ) -> (Arc<AssociatedTyDatum>, &'p [Parameter], &'p [Parameter]) { | 464 | ) -> (Arc<AssociatedTyDatum>, &'p [Parameter<ChalkIr>], &'p [Parameter<ChalkIr>]) { |
435 | debug!("split_projection {:?}", projection); | 465 | debug!("split_projection {:?}", projection); |
436 | // we don't support GATs, so I think this should always be correct currently | 466 | // we don't support GATs, so I think this should always be correct currently |
437 | (self.db.associated_ty_data(projection.associated_ty_id), &projection.parameters, &[]) | 467 | (self.db.associated_ty_data(projection.associated_ty_id), &projection.parameters, &[]) |
438 | } | 468 | } |
439 | fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause> { | 469 | fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<ChalkIr>> { |
440 | vec![] | 470 | vec![] |
441 | } | 471 | } |
442 | fn local_impls_to_coherence_check( | 472 | fn local_impls_to_coherence_check( |