diff options
Diffstat (limited to 'crates/hir_ty/src/traits')
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 16 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 92 |
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 | }; |
27 | use mapping::{ | 27 | use 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 | ||
21 | use super::interner::*; | 21 | use 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 | } |
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 | ||
@@ -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 | } |