diff options
Diffstat (limited to 'crates/hir_ty/src/traits/chalk/mapping.rs')
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 107 |
1 files changed, 66 insertions, 41 deletions
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index d969527dc..62b779008 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -14,8 +14,8 @@ use crate::{ | |||
14 | from_assoc_type_id, | 14 | from_assoc_type_id, |
15 | primitive::UintTy, | 15 | primitive::UintTy, |
16 | traits::{Canonical, Obligation}, | 16 | traits::{Canonical, Obligation}, |
17 | AliasTy, CallableDefId, FnPointer, GenericPredicate, InEnvironment, OpaqueTy, | 17 | AliasTy, CallableDefId, FnPointer, GenericPredicate, InEnvironment, OpaqueTy, ProjectionTy, |
18 | ProjectionPredicate, ProjectionTy, Scalar, Substitution, TraitRef, Ty, | 18 | Scalar, Substitution, TraitRef, Ty, |
19 | }; | 19 | }; |
20 | 20 | ||
21 | use super::interner::*; | 21 | use super::interner::*; |
@@ -239,15 +239,15 @@ impl ToChalk for TraitRef { | |||
239 | type Chalk = chalk_ir::TraitRef<Interner>; | 239 | type Chalk = chalk_ir::TraitRef<Interner>; |
240 | 240 | ||
241 | fn to_chalk(self: TraitRef, db: &dyn HirDatabase) -> chalk_ir::TraitRef<Interner> { | 241 | fn to_chalk(self: TraitRef, db: &dyn HirDatabase) -> chalk_ir::TraitRef<Interner> { |
242 | let trait_id = self.trait_.to_chalk(db); | 242 | let trait_id = self.trait_id; |
243 | let substitution = self.substs.to_chalk(db); | 243 | let substitution = self.substitution.to_chalk(db); |
244 | chalk_ir::TraitRef { trait_id, substitution } | 244 | chalk_ir::TraitRef { trait_id, substitution } |
245 | } | 245 | } |
246 | 246 | ||
247 | fn from_chalk(db: &dyn HirDatabase, trait_ref: chalk_ir::TraitRef<Interner>) -> Self { | 247 | fn from_chalk(db: &dyn HirDatabase, trait_ref: chalk_ir::TraitRef<Interner>) -> Self { |
248 | let trait_ = from_chalk(db, trait_ref.trait_id); | 248 | let trait_id = trait_ref.trait_id; |
249 | let substs = from_chalk(db, trait_ref.substitution); | 249 | let substs = from_chalk(db, trait_ref.substitution); |
250 | TraitRef { trait_, substs } | 250 | TraitRef { trait_id, substitution: substs } |
251 | } | 251 | } |
252 | } | 252 | } |
253 | 253 | ||
@@ -314,12 +314,10 @@ impl ToChalk for GenericPredicate { | |||
314 | let chalk_trait_ref = chalk_trait_ref.shifted_in(&Interner); | 314 | let chalk_trait_ref = chalk_trait_ref.shifted_in(&Interner); |
315 | make_binders(chalk_ir::WhereClause::Implemented(chalk_trait_ref), 0) | 315 | make_binders(chalk_ir::WhereClause::Implemented(chalk_trait_ref), 0) |
316 | } | 316 | } |
317 | GenericPredicate::Projection(projection_pred) => { | 317 | GenericPredicate::AliasEq(alias_eq) => make_binders( |
318 | let ty = projection_pred.ty.to_chalk(db).shifted_in(&Interner); | 318 | chalk_ir::WhereClause::AliasEq(alias_eq.to_chalk(db).shifted_in(&Interner)), |
319 | let projection = projection_pred.projection_ty.to_chalk(db).shifted_in(&Interner); | 319 | 0, |
320 | let alias = chalk_ir::AliasTy::Projection(projection); | 320 | ), |
321 | make_binders(chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { alias, ty }), 0) | ||
322 | } | ||
323 | GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"), | 321 | GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"), |
324 | } | 322 | } |
325 | } | 323 | } |
@@ -338,16 +336,8 @@ impl ToChalk for GenericPredicate { | |||
338 | chalk_ir::WhereClause::Implemented(tr) => { | 336 | chalk_ir::WhereClause::Implemented(tr) => { |
339 | GenericPredicate::Implemented(from_chalk(db, tr)) | 337 | GenericPredicate::Implemented(from_chalk(db, tr)) |
340 | } | 338 | } |
341 | chalk_ir::WhereClause::AliasEq(projection_eq) => { | 339 | chalk_ir::WhereClause::AliasEq(alias_eq) => { |
342 | let projection_ty = from_chalk( | 340 | GenericPredicate::AliasEq(from_chalk(db, alias_eq)) |
343 | db, | ||
344 | match projection_eq.alias { | ||
345 | chalk_ir::AliasTy::Projection(p) => p, | ||
346 | _ => unimplemented!(), | ||
347 | }, | ||
348 | ); | ||
349 | let ty = from_chalk(db, projection_eq.ty); | ||
350 | GenericPredicate::Projection(ProjectionPredicate { projection_ty, ty }) | ||
351 | } | 341 | } |
352 | 342 | ||
353 | chalk_ir::WhereClause::LifetimeOutlives(_) => { | 343 | chalk_ir::WhereClause::LifetimeOutlives(_) => { |
@@ -383,19 +373,55 @@ impl ToChalk for ProjectionTy { | |||
383 | } | 373 | } |
384 | } | 374 | } |
385 | } | 375 | } |
376 | impl ToChalk for OpaqueTy { | ||
377 | type Chalk = chalk_ir::OpaqueTy<Interner>; | ||
378 | |||
379 | fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk { | ||
380 | chalk_ir::OpaqueTy { | ||
381 | opaque_ty_id: self.opaque_ty_id, | ||
382 | substitution: self.substitution.to_chalk(db), | ||
383 | } | ||
384 | } | ||
385 | |||
386 | fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self { | ||
387 | OpaqueTy { | ||
388 | opaque_ty_id: chalk.opaque_ty_id, | ||
389 | substitution: from_chalk(db, chalk.substitution), | ||
390 | } | ||
391 | } | ||
392 | } | ||
393 | |||
394 | impl ToChalk for AliasTy { | ||
395 | type Chalk = chalk_ir::AliasTy<Interner>; | ||
396 | |||
397 | fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk { | ||
398 | match self { | ||
399 | AliasTy::Projection(projection_ty) => { | ||
400 | chalk_ir::AliasTy::Projection(projection_ty.to_chalk(db)) | ||
401 | } | ||
402 | AliasTy::Opaque(opaque_ty) => chalk_ir::AliasTy::Opaque(opaque_ty.to_chalk(db)), | ||
403 | } | ||
404 | } | ||
405 | |||
406 | fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self { | ||
407 | match chalk { | ||
408 | chalk_ir::AliasTy::Projection(projection_ty) => { | ||
409 | AliasTy::Projection(from_chalk(db, projection_ty)) | ||
410 | } | ||
411 | chalk_ir::AliasTy::Opaque(opaque_ty) => AliasTy::Opaque(from_chalk(db, opaque_ty)), | ||
412 | } | ||
413 | } | ||
414 | } | ||
386 | 415 | ||
387 | impl ToChalk for ProjectionPredicate { | 416 | impl ToChalk for AliasEq { |
388 | type Chalk = chalk_ir::AliasEq<Interner>; | 417 | type Chalk = chalk_ir::AliasEq<Interner>; |
389 | 418 | ||
390 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> { | 419 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> { |
391 | chalk_ir::AliasEq { | 420 | chalk_ir::AliasEq { alias: self.alias.to_chalk(db), ty: self.ty.to_chalk(db) } |
392 | alias: chalk_ir::AliasTy::Projection(self.projection_ty.to_chalk(db)), | ||
393 | ty: self.ty.to_chalk(db), | ||
394 | } | ||
395 | } | 421 | } |
396 | 422 | ||
397 | fn from_chalk(_db: &dyn HirDatabase, _normalize: chalk_ir::AliasEq<Interner>) -> Self { | 423 | fn from_chalk(db: &dyn HirDatabase, alias_eq: chalk_ir::AliasEq<Interner>) -> Self { |
398 | unimplemented!() | 424 | AliasEq { alias: from_chalk(db, alias_eq.alias), ty: from_chalk(db, alias_eq.ty) } |
399 | } | 425 | } |
400 | } | 426 | } |
401 | 427 | ||
@@ -405,7 +431,7 @@ impl ToChalk for Obligation { | |||
405 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> { | 431 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> { |
406 | match self { | 432 | match self { |
407 | Obligation::Trait(tr) => tr.to_chalk(db).cast(&Interner), | 433 | Obligation::Trait(tr) => tr.to_chalk(db).cast(&Interner), |
408 | Obligation::Projection(pr) => pr.to_chalk(db).cast(&Interner), | 434 | Obligation::AliasEq(alias_eq) => alias_eq.to_chalk(db).cast(&Interner), |
409 | } | 435 | } |
410 | } | 436 | } |
411 | 437 | ||
@@ -515,42 +541,41 @@ pub(super) fn generic_predicate_to_inline_bound( | |||
515 | // We don't have a special type for this, but Chalk does. | 541 | // We don't have a special type for this, but Chalk does. |
516 | match pred { | 542 | match pred { |
517 | GenericPredicate::Implemented(trait_ref) => { | 543 | GenericPredicate::Implemented(trait_ref) => { |
518 | if &trait_ref.substs[0] != self_ty { | 544 | if &trait_ref.substitution[0] != self_ty { |
519 | // we can only convert predicates back to type bounds if they | 545 | // we can only convert predicates back to type bounds if they |
520 | // have the expected self type | 546 | // have the expected self type |
521 | return None; | 547 | return None; |
522 | } | 548 | } |
523 | let args_no_self = trait_ref.substs[1..] | 549 | let args_no_self = trait_ref.substitution[1..] |
524 | .iter() | 550 | .iter() |
525 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) | 551 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) |
526 | .collect(); | 552 | .collect(); |
527 | let trait_bound = | 553 | let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; |
528 | rust_ir::TraitBound { trait_id: trait_ref.trait_.to_chalk(db), args_no_self }; | ||
529 | Some(rust_ir::InlineBound::TraitBound(trait_bound)) | 554 | Some(rust_ir::InlineBound::TraitBound(trait_bound)) |
530 | } | 555 | } |
531 | GenericPredicate::Projection(proj) => { | 556 | GenericPredicate::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { |
532 | if &proj.projection_ty.substitution[0] != self_ty { | 557 | if &projection_ty.substitution[0] != self_ty { |
533 | return None; | 558 | return None; |
534 | } | 559 | } |
535 | let trait_ = match from_assoc_type_id(proj.projection_ty.associated_ty_id) | 560 | let trait_ = match from_assoc_type_id(projection_ty.associated_ty_id) |
536 | .lookup(db.upcast()) | 561 | .lookup(db.upcast()) |
537 | .container | 562 | .container |
538 | { | 563 | { |
539 | AssocContainerId::TraitId(t) => t, | 564 | AssocContainerId::TraitId(t) => t, |
540 | _ => panic!("associated type not in trait"), | 565 | _ => panic!("associated type not in trait"), |
541 | }; | 566 | }; |
542 | let args_no_self = proj.projection_ty.substitution[1..] | 567 | let args_no_self = projection_ty.substitution[1..] |
543 | .iter() | 568 | .iter() |
544 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) | 569 | .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) |
545 | .collect(); | 570 | .collect(); |
546 | let alias_eq_bound = rust_ir::AliasEqBound { | 571 | let alias_eq_bound = rust_ir::AliasEqBound { |
547 | value: proj.ty.clone().to_chalk(db), | 572 | value: ty.clone().to_chalk(db), |
548 | trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, | 573 | trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, |
549 | associated_ty_id: proj.projection_ty.associated_ty_id, | 574 | associated_ty_id: projection_ty.associated_ty_id, |
550 | parameters: Vec::new(), // FIXME we don't support generic associated types yet | 575 | parameters: Vec::new(), // FIXME we don't support generic associated types yet |
551 | }; | 576 | }; |
552 | Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) | 577 | Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) |
553 | } | 578 | } |
554 | GenericPredicate::Error => None, | 579 | _ => None, |
555 | } | 580 | } |
556 | } | 581 | } |