aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/traits/chalk/mapping.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/traits/chalk/mapping.rs')
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs107
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
21use super::interner::*; 21use 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}
376impl 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
394impl 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
387impl ToChalk for ProjectionPredicate { 416impl 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}