aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/traits
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/traits')
-rw-r--r--crates/hir_ty/src/traits/chalk.rs16
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs92
2 files changed, 67 insertions, 41 deletions
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index bac70f5aa..080764e76 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -21,8 +21,8 @@ use crate::{
21 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, 21 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
22 to_assoc_type_id, to_chalk_trait_id, 22 to_assoc_type_id, to_chalk_trait_id,
23 utils::generics, 23 utils::generics,
24 BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, GenericPredicate, 24 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId,
25 ProjectionPredicate, ProjectionTy, Substitution, TraitRef, Ty, TyKind, 25 GenericPredicate, ProjectionTy, Substitution, TraitRef, Ty, TyKind,
26}; 26};
27use mapping::{ 27use mapping::{
28 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, 28 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
@@ -229,18 +229,18 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
229 .intern(&Interner), 229 .intern(&Interner),
230 ), 230 ),
231 }); 231 });
232 let proj_bound = GenericPredicate::Projection(ProjectionPredicate { 232 let proj_bound = GenericPredicate::AliasEq(AliasEq {
233 // The parameter of the opaque type. 233 alias: AliasTy::Projection(ProjectionTy {
234 ty: TyKind::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 })
235 .intern(&Interner),
236 projection_ty: ProjectionTy {
237 associated_ty_id: to_assoc_type_id(future_output), 234 associated_ty_id: to_assoc_type_id(future_output),
238 // Self type as the first parameter. 235 // Self type as the first parameter.
239 substitution: Substitution::single( 236 substitution: Substitution::single(
240 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) 237 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
241 .intern(&Interner), 238 .intern(&Interner),
242 ), 239 ),
243 }, 240 }),
241 // The parameter of the opaque type.
242 ty: TyKind::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 })
243 .intern(&Interner),
244 }); 244 });
245 let bound = OpaqueTyDatumBound { 245 let bound = OpaqueTyDatumBound {
246 bounds: make_binders( 246 bounds: make_binders(
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index 0086ce1e9..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::*;
@@ -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
@@ -527,29 +553,29 @@ pub(super) fn generic_predicate_to_inline_bound(
527 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; 553 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
528 Some(rust_ir::InlineBound::TraitBound(trait_bound)) 554 Some(rust_ir::InlineBound::TraitBound(trait_bound))
529 } 555 }
530 GenericPredicate::Projection(proj) => { 556 GenericPredicate::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
531 if &proj.projection_ty.substitution[0] != self_ty { 557 if &projection_ty.substitution[0] != self_ty {
532 return None; 558 return None;
533 } 559 }
534 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)
535 .lookup(db.upcast()) 561 .lookup(db.upcast())
536 .container 562 .container
537 { 563 {
538 AssocContainerId::TraitId(t) => t, 564 AssocContainerId::TraitId(t) => t,
539 _ => panic!("associated type not in trait"), 565 _ => panic!("associated type not in trait"),
540 }; 566 };
541 let args_no_self = proj.projection_ty.substitution[1..] 567 let args_no_self = projection_ty.substitution[1..]
542 .iter() 568 .iter()
543 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 569 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
544 .collect(); 570 .collect();
545 let alias_eq_bound = rust_ir::AliasEqBound { 571 let alias_eq_bound = rust_ir::AliasEqBound {
546 value: proj.ty.clone().to_chalk(db), 572 value: ty.clone().to_chalk(db),
547 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 },
548 associated_ty_id: proj.projection_ty.associated_ty_id, 574 associated_ty_id: projection_ty.associated_ty_id,
549 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
550 }; 576 };
551 Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) 577 Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound))
552 } 578 }
553 GenericPredicate::Error => None, 579 _ => None,
554 } 580 }
555} 581}