diff options
-rw-r--r-- | crates/hir/src/lib.rs | 22 | ||||
-rw-r--r-- | crates/hir_ty/src/autoderef.rs | 15 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 58 | ||||
-rw-r--r-- | crates/hir_ty/src/infer.rs | 18 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 35 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 49 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 10 | ||||
-rw-r--r-- | crates/hir_ty/src/traits.rs | 37 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 16 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 92 |
10 files changed, 221 insertions, 131 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 67ec8e82a..5ebd0a3b8 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -56,9 +56,9 @@ use hir_ty::{ | |||
56 | primitive::UintTy, | 56 | primitive::UintTy, |
57 | to_assoc_type_id, | 57 | to_assoc_type_id, |
58 | traits::{FnTrait, Solution, SolutionVariables}, | 58 | traits::{FnTrait, Solution, SolutionVariables}, |
59 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, | 59 | AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, |
60 | InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substitution, | 60 | GenericPredicate, InEnvironment, Interner, Obligation, ProjectionTy, Scalar, Substitution, Ty, |
61 | Ty, TyDefId, TyKind, TyVariableKind, | 61 | TyDefId, TyKind, TyVariableKind, |
62 | }; | 62 | }; |
63 | use itertools::Itertools; | 63 | use itertools::Itertools; |
64 | use rustc_hash::FxHashSet; | 64 | use rustc_hash::FxHashSet; |
@@ -1786,17 +1786,17 @@ impl Type { | |||
1786 | .push(self.ty.value.clone()) | 1786 | .push(self.ty.value.clone()) |
1787 | .fill(args.iter().map(|t| t.ty.value.clone())) | 1787 | .fill(args.iter().map(|t| t.ty.value.clone())) |
1788 | .build(); | 1788 | .build(); |
1789 | let predicate = ProjectionPredicate { | ||
1790 | projection_ty: ProjectionTy { | ||
1791 | associated_ty_id: to_assoc_type_id(alias.id), | ||
1792 | substitution: subst, | ||
1793 | }, | ||
1794 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner), | ||
1795 | }; | ||
1796 | let goal = Canonical { | 1789 | let goal = Canonical { |
1797 | value: InEnvironment::new( | 1790 | value: InEnvironment::new( |
1798 | self.ty.environment.clone(), | 1791 | self.ty.environment.clone(), |
1799 | Obligation::Projection(predicate), | 1792 | Obligation::AliasEq(AliasEq { |
1793 | alias: AliasTy::Projection(ProjectionTy { | ||
1794 | associated_ty_id: to_assoc_type_id(alias.id), | ||
1795 | substitution: subst, | ||
1796 | }), | ||
1797 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) | ||
1798 | .intern(&Interner), | ||
1799 | }), | ||
1800 | ), | 1800 | ), |
1801 | kinds: Arc::new([TyVariableKind::General]), | 1801 | kinds: Arc::new([TyVariableKind::General]), |
1802 | }; | 1802 | }; |
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs index ad4e6f23b..33b966026 100644 --- a/crates/hir_ty/src/autoderef.rs +++ b/crates/hir_ty/src/autoderef.rs | |||
@@ -15,7 +15,8 @@ use crate::{ | |||
15 | to_assoc_type_id, to_chalk_trait_id, | 15 | to_assoc_type_id, to_chalk_trait_id, |
16 | traits::{InEnvironment, Solution}, | 16 | traits::{InEnvironment, Solution}, |
17 | utils::generics, | 17 | utils::generics, |
18 | BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substitution, TraitRef, Ty, TyKind, | 18 | AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, Obligation, ProjectionTy, |
19 | Substitution, TraitRef, Ty, TyKind, | ||
19 | }; | 20 | }; |
20 | 21 | ||
21 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 22 | const AUTODEREF_RECURSION_LIMIT: usize = 10; |
@@ -82,16 +83,16 @@ fn deref_by_trait( | |||
82 | } | 83 | } |
83 | 84 | ||
84 | // Now do the assoc type projection | 85 | // Now do the assoc type projection |
85 | let projection = super::traits::ProjectionPredicate { | 86 | let projection = AliasEq { |
86 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())) | 87 | alias: AliasTy::Projection(ProjectionTy { |
87 | .intern(&Interner), | ||
88 | projection_ty: super::ProjectionTy { | ||
89 | associated_ty_id: to_assoc_type_id(target), | 88 | associated_ty_id: to_assoc_type_id(target), |
90 | substitution: parameters, | 89 | substitution: parameters, |
91 | }, | 90 | }), |
91 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())) | ||
92 | .intern(&Interner), | ||
92 | }; | 93 | }; |
93 | 94 | ||
94 | let obligation = super::Obligation::Projection(projection); | 95 | let obligation = super::Obligation::AliasEq(projection); |
95 | 96 | ||
96 | let in_env = InEnvironment { value: obligation, environment: ty.environment }; | 97 | let in_env = InEnvironment { value: obligation, environment: ty.environment }; |
97 | 98 | ||
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index c6b4f37e5..59a1bd9b0 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -18,9 +18,9 @@ use hir_expand::name::Name; | |||
18 | 18 | ||
19 | use crate::{ | 19 | use crate::{ |
20 | db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, | 20 | db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, |
21 | to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasTy, CallableDefId, | 21 | to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy, |
22 | CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy, | 22 | CallableDefId, CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation, |
23 | ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind, | 23 | OpaqueTy, ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | pub struct HirFormatter<'a> { | 26 | pub struct HirFormatter<'a> { |
@@ -268,6 +268,16 @@ impl HirDisplay for ProjectionTy { | |||
268 | } | 268 | } |
269 | } | 269 | } |
270 | 270 | ||
271 | impl HirDisplay for OpaqueTy { | ||
272 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
273 | if f.should_truncate() { | ||
274 | return write!(f, "{}", TYPE_HINT_TRUNCATION); | ||
275 | } | ||
276 | |||
277 | self.substitution[0].hir_fmt(f) | ||
278 | } | ||
279 | } | ||
280 | |||
271 | impl HirDisplay for Ty { | 281 | impl HirDisplay for Ty { |
272 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 282 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
273 | if f.should_truncate() { | 283 | if f.should_truncate() { |
@@ -700,12 +710,12 @@ fn write_bounds_like_dyn_trait( | |||
700 | } | 710 | } |
701 | } | 711 | } |
702 | } | 712 | } |
703 | GenericPredicate::Projection(projection_pred) if is_fn_trait => { | 713 | GenericPredicate::AliasEq(alias_eq) if is_fn_trait => { |
704 | is_fn_trait = false; | 714 | is_fn_trait = false; |
705 | write!(f, " -> ")?; | 715 | write!(f, " -> ")?; |
706 | projection_pred.ty.hir_fmt(f)?; | 716 | alias_eq.ty.hir_fmt(f)?; |
707 | } | 717 | } |
708 | GenericPredicate::Projection(projection_pred) => { | 718 | GenericPredicate::AliasEq(AliasEq { ty, alias }) => { |
709 | // in types in actual Rust, these will always come | 719 | // in types in actual Rust, these will always come |
710 | // after the corresponding Implemented predicate | 720 | // after the corresponding Implemented predicate |
711 | if angle_open { | 721 | if angle_open { |
@@ -714,11 +724,12 @@ fn write_bounds_like_dyn_trait( | |||
714 | write!(f, "<")?; | 724 | write!(f, "<")?; |
715 | angle_open = true; | 725 | angle_open = true; |
716 | } | 726 | } |
717 | let type_alias = f.db.type_alias_data(from_assoc_type_id( | 727 | if let AliasTy::Projection(proj) = alias { |
718 | projection_pred.projection_ty.associated_ty_id, | 728 | let type_alias = |
719 | )); | 729 | f.db.type_alias_data(from_assoc_type_id(proj.associated_ty_id)); |
720 | write!(f, "{} = ", type_alias.name)?; | 730 | write!(f, "{} = ", type_alias.name)?; |
721 | projection_pred.ty.hir_fmt(f)?; | 731 | } |
732 | ty.hir_fmt(f)?; | ||
722 | } | 733 | } |
723 | GenericPredicate::Error => { | 734 | GenericPredicate::Error => { |
724 | if angle_open { | 735 | if angle_open { |
@@ -775,20 +786,20 @@ impl HirDisplay for GenericPredicate { | |||
775 | 786 | ||
776 | match self { | 787 | match self { |
777 | GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, | 788 | GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, |
778 | GenericPredicate::Projection(projection_pred) => { | 789 | GenericPredicate::AliasEq(AliasEq { |
790 | alias: AliasTy::Projection(projection_ty), | ||
791 | ty, | ||
792 | }) => { | ||
779 | write!(f, "<")?; | 793 | write!(f, "<")?; |
780 | projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?; | 794 | projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?; |
781 | write!( | 795 | write!( |
782 | f, | 796 | f, |
783 | ">::{} = ", | 797 | ">::{} = ", |
784 | f.db.type_alias_data(from_assoc_type_id( | 798 | f.db.type_alias_data(from_assoc_type_id(projection_ty.associated_ty_id)).name, |
785 | projection_pred.projection_ty.associated_ty_id | ||
786 | )) | ||
787 | .name, | ||
788 | )?; | 799 | )?; |
789 | projection_pred.ty.hir_fmt(f)?; | 800 | ty.hir_fmt(f)?; |
790 | } | 801 | } |
791 | GenericPredicate::Error => write!(f, "{{error}}")?, | 802 | GenericPredicate::AliasEq(_) | GenericPredicate::Error => write!(f, "{{error}}")?, |
792 | } | 803 | } |
793 | Ok(()) | 804 | Ok(()) |
794 | } | 805 | } |
@@ -815,11 +826,14 @@ impl HirDisplay for Obligation { | |||
815 | tr.hir_fmt(f)?; | 826 | tr.hir_fmt(f)?; |
816 | write!(f, ")") | 827 | write!(f, ")") |
817 | } | 828 | } |
818 | Obligation::Projection(proj) => { | 829 | Obligation::AliasEq(AliasEq { alias, ty }) => { |
819 | write!(f, "Normalize(")?; | 830 | write!(f, "Normalize(")?; |
820 | proj.projection_ty.hir_fmt(f)?; | 831 | match alias { |
832 | AliasTy::Projection(projection_ty) => projection_ty.hir_fmt(f)?, | ||
833 | AliasTy::Opaque(opaque) => opaque.hir_fmt(f)?, | ||
834 | } | ||
821 | write!(f, " => ")?; | 835 | write!(f, " => ")?; |
822 | proj.ty.hir_fmt(f)?; | 836 | ty.hir_fmt(f)?; |
823 | write!(f, ")") | 837 | write!(f, ")") |
824 | } | 838 | } |
825 | } | 839 | } |
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index b6ae4fc65..82186979a 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -37,12 +37,12 @@ use stdx::impl_from; | |||
37 | use syntax::SmolStr; | 37 | use syntax::SmolStr; |
38 | 38 | ||
39 | use super::{ | 39 | use super::{ |
40 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, | 40 | traits::{Guidance, Obligation, Solution}, |
41 | InEnvironment, ProjectionTy, Substitution, TraitEnvironment, TraitRef, Ty, TypeWalk, | 41 | InEnvironment, ProjectionTy, Substitution, TraitEnvironment, TraitRef, Ty, TypeWalk, |
42 | }; | 42 | }; |
43 | use crate::{ | 43 | use crate::{ |
44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, | 44 | db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, |
45 | to_assoc_type_id, to_chalk_trait_id, AliasTy, Interner, TyKind, | 45 | to_assoc_type_id, to_chalk_trait_id, AliasEq, AliasTy, Interner, TyKind, |
46 | }; | 46 | }; |
47 | 47 | ||
48 | pub(crate) use unify::unify; | 48 | pub(crate) use unify::unify; |
@@ -396,15 +396,15 @@ impl<'a> InferenceContext<'a> { | |||
396 | .build(); | 396 | .build(); |
397 | let trait_ref = | 397 | let trait_ref = |
398 | TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() }; | 398 | TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() }; |
399 | let projection = ProjectionPredicate { | 399 | let alias_eq = AliasEq { |
400 | ty: ty.clone(), | 400 | alias: AliasTy::Projection(ProjectionTy { |
401 | projection_ty: ProjectionTy { | ||
402 | associated_ty_id: to_assoc_type_id(res_assoc_ty), | 401 | associated_ty_id: to_assoc_type_id(res_assoc_ty), |
403 | substitution: substs, | 402 | substitution: substs, |
404 | }, | 403 | }), |
404 | ty: ty.clone(), | ||
405 | }; | 405 | }; |
406 | self.obligations.push(Obligation::Trait(trait_ref)); | 406 | self.obligations.push(Obligation::Trait(trait_ref)); |
407 | self.obligations.push(Obligation::Projection(projection)); | 407 | self.obligations.push(Obligation::AliasEq(alias_eq)); |
408 | self.resolve_ty_as_possible(ty) | 408 | self.resolve_ty_as_possible(ty) |
409 | } | 409 | } |
410 | None => self.err_ty(), | 410 | None => self.err_ty(), |
@@ -429,8 +429,8 @@ impl<'a> InferenceContext<'a> { | |||
429 | 429 | ||
430 | fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty { | 430 | fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty { |
431 | let var = self.table.new_type_var(); | 431 | let var = self.table.new_type_var(); |
432 | let predicate = ProjectionPredicate { projection_ty: proj_ty, ty: var.clone() }; | 432 | let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() }; |
433 | let obligation = Obligation::Projection(predicate); | 433 | let obligation = Obligation::AliasEq(alias_eq); |
434 | self.obligations.push(obligation); | 434 | self.obligations.push(obligation); |
435 | var | 435 | var |
436 | } | 436 | } |
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index f5ea09698..4738ec08a 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -7,8 +7,8 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | |||
7 | 7 | ||
8 | use super::{InferenceContext, Obligation}; | 8 | use super::{InferenceContext, Obligation}; |
9 | use crate::{ | 9 | use crate::{ |
10 | BoundVar, Canonical, DebruijnIndex, FnPointer, GenericPredicate, InEnvironment, InferenceVar, | 10 | AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, GenericPredicate, |
11 | Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, | 11 | InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | impl<'a> InferenceContext<'a> { | 14 | impl<'a> InferenceContext<'a> { |
@@ -93,8 +93,8 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { | |||
93 | Obligation::Trait(tr) => { | 93 | Obligation::Trait(tr) => { |
94 | Obligation::Trait(self.do_canonicalize(tr, DebruijnIndex::INNERMOST)) | 94 | Obligation::Trait(self.do_canonicalize(tr, DebruijnIndex::INNERMOST)) |
95 | } | 95 | } |
96 | Obligation::Projection(pr) => { | 96 | Obligation::AliasEq(alias_eq) => { |
97 | Obligation::Projection(self.do_canonicalize(pr, DebruijnIndex::INNERMOST)) | 97 | Obligation::AliasEq(self.do_canonicalize(alias_eq, DebruijnIndex::INNERMOST)) |
98 | } | 98 | } |
99 | }; | 99 | }; |
100 | self.into_canonicalized(InEnvironment { | 100 | self.into_canonicalized(InEnvironment { |
@@ -394,14 +394,25 @@ impl InferenceTable { | |||
394 | { | 394 | { |
395 | self.unify_substs(&tr1.substitution, &tr2.substitution, depth + 1) | 395 | self.unify_substs(&tr1.substitution, &tr2.substitution, depth + 1) |
396 | } | 396 | } |
397 | (GenericPredicate::Projection(proj1), GenericPredicate::Projection(proj2)) | 397 | ( |
398 | if proj1.projection_ty.associated_ty_id == proj2.projection_ty.associated_ty_id => | 398 | GenericPredicate::AliasEq(AliasEq { alias: alias1, ty: ty1 }), |
399 | { | 399 | GenericPredicate::AliasEq(AliasEq { alias: alias2, ty: ty2 }), |
400 | self.unify_substs( | 400 | ) => { |
401 | &proj1.projection_ty.substitution, | 401 | let (substitution1, substitution2) = match (alias1, alias2) { |
402 | &proj2.projection_ty.substitution, | 402 | (AliasTy::Projection(projection_ty1), AliasTy::Projection(projection_ty2)) |
403 | depth + 1, | 403 | if projection_ty1.associated_ty_id == projection_ty2.associated_ty_id => |
404 | ) && self.unify_inner(&proj1.ty, &proj2.ty, depth + 1) | 404 | { |
405 | (&projection_ty1.substitution, &projection_ty2.substitution) | ||
406 | } | ||
407 | (AliasTy::Opaque(opaque1), AliasTy::Opaque(opaque2)) | ||
408 | if opaque1.opaque_ty_id == opaque2.opaque_ty_id => | ||
409 | { | ||
410 | (&opaque1.substitution, &opaque2.substitution) | ||
411 | } | ||
412 | _ => return false, | ||
413 | }; | ||
414 | self.unify_substs(&substitution1, &substitution2, depth + 1) | ||
415 | && self.unify_inner(&ty1, &ty2, depth + 1) | ||
405 | } | 416 | } |
406 | _ => false, | 417 | _ => false, |
407 | } | 418 | } |
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 3859dbfa1..2afcb5413 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -45,7 +45,7 @@ pub use lower::{ | |||
45 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, | 45 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, |
46 | TyDefId, TyLoweringContext, ValueTyDefId, | 46 | TyDefId, TyLoweringContext, ValueTyDefId, |
47 | }; | 47 | }; |
48 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; | 48 | pub use traits::{AliasEq, InEnvironment, Obligation, TraitEnvironment}; |
49 | 49 | ||
50 | pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind}; | 50 | pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind}; |
51 | 51 | ||
@@ -72,6 +72,20 @@ pub struct OpaqueTy { | |||
72 | pub substitution: Substitution, | 72 | pub substitution: Substitution, |
73 | } | 73 | } |
74 | 74 | ||
75 | impl TypeWalk for OpaqueTy { | ||
76 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
77 | self.substitution.walk(f); | ||
78 | } | ||
79 | |||
80 | fn walk_mut_binders( | ||
81 | &mut self, | ||
82 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | ||
83 | binders: DebruijnIndex, | ||
84 | ) { | ||
85 | self.substitution.walk_mut_binders(f, binders); | ||
86 | } | ||
87 | } | ||
88 | |||
75 | /// A "projection" type corresponds to an (unnormalized) | 89 | /// A "projection" type corresponds to an (unnormalized) |
76 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the | 90 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the |
77 | /// trait and all its parameters are fully known. | 91 | /// trait and all its parameters are fully known. |
@@ -133,6 +147,25 @@ pub enum AliasTy { | |||
133 | Opaque(OpaqueTy), | 147 | Opaque(OpaqueTy), |
134 | } | 148 | } |
135 | 149 | ||
150 | impl TypeWalk for AliasTy { | ||
151 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
152 | match self { | ||
153 | AliasTy::Projection(it) => it.walk(f), | ||
154 | AliasTy::Opaque(it) => it.walk(f), | ||
155 | } | ||
156 | } | ||
157 | |||
158 | fn walk_mut_binders( | ||
159 | &mut self, | ||
160 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | ||
161 | binders: DebruijnIndex, | ||
162 | ) { | ||
163 | match self { | ||
164 | AliasTy::Projection(it) => it.walk_mut_binders(f, binders), | ||
165 | AliasTy::Opaque(it) => it.walk_mut_binders(f, binders), | ||
166 | } | ||
167 | } | ||
168 | } | ||
136 | /// A type. | 169 | /// A type. |
137 | /// | 170 | /// |
138 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents | 171 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents |
@@ -535,7 +568,7 @@ pub enum GenericPredicate { | |||
535 | /// The given trait needs to be implemented for its type parameters. | 568 | /// The given trait needs to be implemented for its type parameters. |
536 | Implemented(TraitRef), | 569 | Implemented(TraitRef), |
537 | /// An associated type bindings like in `Iterator<Item = T>`. | 570 | /// An associated type bindings like in `Iterator<Item = T>`. |
538 | Projection(ProjectionPredicate), | 571 | AliasEq(AliasEq), |
539 | /// We couldn't resolve the trait reference. (If some type parameters can't | 572 | /// We couldn't resolve the trait reference. (If some type parameters can't |
540 | /// be resolved, they will just be Unknown). | 573 | /// be resolved, they will just be Unknown). |
541 | Error, | 574 | Error, |
@@ -553,8 +586,10 @@ impl GenericPredicate { | |||
553 | pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> { | 586 | pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> { |
554 | match self { | 587 | match self { |
555 | GenericPredicate::Implemented(tr) => Some(tr.clone()), | 588 | GenericPredicate::Implemented(tr) => Some(tr.clone()), |
556 | GenericPredicate::Projection(proj) => Some(proj.projection_ty.trait_ref(db)), | 589 | GenericPredicate::AliasEq(AliasEq { alias: AliasTy::Projection(proj), .. }) => { |
557 | GenericPredicate::Error => None, | 590 | Some(proj.trait_ref(db)) |
591 | } | ||
592 | GenericPredicate::AliasEq(_) | GenericPredicate::Error => None, | ||
558 | } | 593 | } |
559 | } | 594 | } |
560 | } | 595 | } |
@@ -563,7 +598,7 @@ impl TypeWalk for GenericPredicate { | |||
563 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 598 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
564 | match self { | 599 | match self { |
565 | GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f), | 600 | GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f), |
566 | GenericPredicate::Projection(projection_pred) => projection_pred.walk(f), | 601 | GenericPredicate::AliasEq(alias_eq) => alias_eq.walk(f), |
567 | GenericPredicate::Error => {} | 602 | GenericPredicate::Error => {} |
568 | } | 603 | } |
569 | } | 604 | } |
@@ -575,9 +610,7 @@ impl TypeWalk for GenericPredicate { | |||
575 | ) { | 610 | ) { |
576 | match self { | 611 | match self { |
577 | GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders), | 612 | GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders), |
578 | GenericPredicate::Projection(projection_pred) => { | 613 | GenericPredicate::AliasEq(alias_eq) => alias_eq.walk_mut_binders(f, binders), |
579 | projection_pred.walk_mut_binders(f, binders) | ||
580 | } | ||
581 | GenericPredicate::Error => {} | 614 | GenericPredicate::Error => {} |
582 | } | 615 | } |
583 | } | 616 | } |
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 5d950a017..7d22c3df5 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs | |||
@@ -33,8 +33,8 @@ use crate::{ | |||
33 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, | 33 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, |
34 | variant_data, | 34 | variant_data, |
35 | }, | 35 | }, |
36 | AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, | 36 | AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, |
37 | ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, | 37 | GenericPredicate, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, ReturnTypeImplTrait, |
38 | ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, | 38 | ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, |
39 | }; | 39 | }; |
40 | 40 | ||
@@ -750,9 +750,9 @@ impl<'a> TyLoweringContext<'a> { | |||
750 | ); | 750 | ); |
751 | if let Some(type_ref) = &binding.type_ref { | 751 | if let Some(type_ref) = &binding.type_ref { |
752 | let ty = self.lower_ty(type_ref); | 752 | let ty = self.lower_ty(type_ref); |
753 | let projection_predicate = | 753 | let alias_eq = |
754 | ProjectionPredicate { projection_ty: projection_ty.clone(), ty }; | 754 | AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty }; |
755 | preds.push(GenericPredicate::Projection(projection_predicate)); | 755 | preds.push(GenericPredicate::AliasEq(alias_eq)); |
756 | } | 756 | } |
757 | for bound in &binding.bounds { | 757 | for bound in &binding.bounds { |
758 | preds.extend(self.lower_type_bound( | 758 | preds.extend(self.lower_type_bound( |
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs index a7287dea1..ac7de7605 100644 --- a/crates/hir_ty/src/traits.rs +++ b/crates/hir_ty/src/traits.rs | |||
@@ -8,10 +8,9 @@ use chalk_solve::{logging_db::LoggingRustIrDatabase, Solver}; | |||
8 | use hir_def::{lang_item::LangItemTarget, TraitId}; | 8 | use hir_def::{lang_item::LangItemTarget, TraitId}; |
9 | use stdx::panic_context; | 9 | use stdx::panic_context; |
10 | 10 | ||
11 | use crate::{db::HirDatabase, DebruijnIndex, Substitution}; | 11 | use crate::{ |
12 | 12 | db::HirDatabase, AliasTy, Canonical, DebruijnIndex, GenericPredicate, HirDisplay, Substitution, | |
13 | use super::{ | 13 | TraitRef, Ty, TyKind, TypeWalk, |
14 | Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TyKind, TypeWalk, | ||
15 | }; | 14 | }; |
16 | 15 | ||
17 | use self::chalk::{from_chalk, Interner, ToChalk}; | 16 | use self::chalk::{from_chalk, Interner, ToChalk}; |
@@ -93,31 +92,32 @@ pub enum Obligation { | |||
93 | /// Prove that a certain type implements a trait (the type is the `Self` type | 92 | /// Prove that a certain type implements a trait (the type is the `Self` type |
94 | /// parameter to the `TraitRef`). | 93 | /// parameter to the `TraitRef`). |
95 | Trait(TraitRef), | 94 | Trait(TraitRef), |
96 | Projection(ProjectionPredicate), | 95 | AliasEq(AliasEq), |
97 | } | 96 | } |
98 | 97 | ||
99 | impl Obligation { | 98 | impl Obligation { |
100 | pub fn from_predicate(predicate: GenericPredicate) -> Option<Obligation> { | 99 | pub fn from_predicate(predicate: GenericPredicate) -> Option<Obligation> { |
101 | match predicate { | 100 | match predicate { |
102 | GenericPredicate::Implemented(trait_ref) => Some(Obligation::Trait(trait_ref)), | 101 | GenericPredicate::Implemented(trait_ref) => Some(Obligation::Trait(trait_ref)), |
103 | GenericPredicate::Projection(projection_pred) => { | 102 | GenericPredicate::AliasEq(alias_eq) => Some(Obligation::AliasEq(alias_eq)), |
104 | Some(Obligation::Projection(projection_pred)) | ||
105 | } | ||
106 | GenericPredicate::Error => None, | 103 | GenericPredicate::Error => None, |
107 | } | 104 | } |
108 | } | 105 | } |
109 | } | 106 | } |
110 | 107 | ||
111 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | 108 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] |
112 | pub struct ProjectionPredicate { | 109 | pub struct AliasEq { |
113 | pub projection_ty: ProjectionTy, | 110 | pub alias: AliasTy, |
114 | pub ty: Ty, | 111 | pub ty: Ty, |
115 | } | 112 | } |
116 | 113 | ||
117 | impl TypeWalk for ProjectionPredicate { | 114 | impl TypeWalk for AliasEq { |
118 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 115 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
119 | self.projection_ty.walk(f); | ||
120 | self.ty.walk(f); | 116 | self.ty.walk(f); |
117 | match &self.alias { | ||
118 | AliasTy::Projection(projection_ty) => projection_ty.walk(f), | ||
119 | AliasTy::Opaque(opaque) => opaque.walk(f), | ||
120 | } | ||
121 | } | 121 | } |
122 | 122 | ||
123 | fn walk_mut_binders( | 123 | fn walk_mut_binders( |
@@ -125,8 +125,11 @@ impl TypeWalk for ProjectionPredicate { | |||
125 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | 125 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), |
126 | binders: DebruijnIndex, | 126 | binders: DebruijnIndex, |
127 | ) { | 127 | ) { |
128 | self.projection_ty.walk_mut_binders(f, binders); | ||
129 | self.ty.walk_mut_binders(f, binders); | 128 | self.ty.walk_mut_binders(f, binders); |
129 | match &mut self.alias { | ||
130 | AliasTy::Projection(projection_ty) => projection_ty.walk_mut_binders(f, binders), | ||
131 | AliasTy::Opaque(opaque) => opaque.walk_mut_binders(f, binders), | ||
132 | } | ||
130 | } | 133 | } |
131 | } | 134 | } |
132 | 135 | ||
@@ -138,12 +141,14 @@ pub(crate) fn trait_solve_query( | |||
138 | ) -> Option<Solution> { | 141 | ) -> Option<Solution> { |
139 | let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value { | 142 | let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value { |
140 | Obligation::Trait(it) => db.trait_data(it.hir_trait_id()).name.to_string(), | 143 | Obligation::Trait(it) => db.trait_data(it.hir_trait_id()).name.to_string(), |
141 | Obligation::Projection(_) => "projection".to_string(), | 144 | Obligation::AliasEq(_) => "alias_eq".to_string(), |
142 | }); | 145 | }); |
143 | log::info!("trait_solve_query({})", goal.value.value.display(db)); | 146 | log::info!("trait_solve_query({})", goal.value.value.display(db)); |
144 | 147 | ||
145 | if let Obligation::Projection(pred) = &goal.value.value { | 148 | if let Obligation::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), .. }) = |
146 | if let TyKind::BoundVar(_) = &pred.projection_ty.substitution[0].interned(&Interner) { | 149 | &goal.value.value |
150 | { | ||
151 | if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) { | ||
147 | // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible | 152 | // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible |
148 | return Some(Solution::Ambig(Guidance::Unknown)); | 153 | return Some(Solution::Ambig(Guidance::Unknown)); |
149 | } | 154 | } |
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 | } |