aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r--crates/hir_ty/src/autoderef.rs20
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs15
-rw-r--r--crates/hir_ty/src/display.rs72
-rw-r--r--crates/hir_ty/src/infer.rs21
-rw-r--r--crates/hir_ty/src/infer/coerce.rs6
-rw-r--r--crates/hir_ty/src/infer/expr.rs13
-rw-r--r--crates/hir_ty/src/infer/path.rs12
-rw-r--r--crates/hir_ty/src/infer/unify.rs39
-rw-r--r--crates/hir_ty/src/lib.rs88
-rw-r--r--crates/hir_ty/src/lower.rs32
-rw-r--r--crates/hir_ty/src/method_resolution.rs5
-rw-r--r--crates/hir_ty/src/traits.rs39
-rw-r--r--crates/hir_ty/src/traits/chalk.rs26
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs107
-rw-r--r--crates/hir_ty/src/utils.rs10
15 files changed, 317 insertions, 188 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index bd2ff5d38..33b966026 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -12,10 +12,11 @@ use log::{info, warn};
12 12
13use crate::{ 13use crate::{
14 db::HirDatabase, 14 db::HirDatabase,
15 to_assoc_type_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
21const AUTODEREF_RECURSION_LIMIT: usize = 10; 22const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -68,7 +69,8 @@ fn deref_by_trait(
68 Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build(); 69 Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build();
69 70
70 // Check that the type implements Deref at all 71 // Check that the type implements Deref at all
71 let trait_ref = TraitRef { trait_: deref_trait, substs: parameters.clone() }; 72 let trait_ref =
73 TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() };
72 let implements_goal = Canonical { 74 let implements_goal = Canonical {
73 kinds: ty.value.kinds.clone(), 75 kinds: ty.value.kinds.clone(),
74 value: InEnvironment { 76 value: InEnvironment {
@@ -81,16 +83,16 @@ fn deref_by_trait(
81 } 83 }
82 84
83 // Now do the assoc type projection 85 // Now do the assoc type projection
84 let projection = super::traits::ProjectionPredicate { 86 let projection = AliasEq {
85 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())) 87 alias: AliasTy::Projection(ProjectionTy {
86 .intern(&Interner),
87 projection_ty: super::ProjectionTy {
88 associated_ty_id: to_assoc_type_id(target), 88 associated_ty_id: to_assoc_type_id(target),
89 substitution: parameters, 89 substitution: parameters,
90 }, 90 }),
91 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len()))
92 .intern(&Interner),
91 }; 93 };
92 94
93 let obligation = super::Obligation::Projection(projection); 95 let obligation = super::Obligation::AliasEq(projection);
94 96
95 let in_env = InEnvironment { value: obligation, environment: ty.environment }; 97 let in_env = InEnvironment { value: obligation, environment: ty.environment };
96 98
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs
index bfe239793..33a0f4d7d 100644
--- a/crates/hir_ty/src/diagnostics/decl_check.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check.rs
@@ -102,7 +102,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
102 let db = self.db; 102 let db = self.db;
103 for block_def_map in body.block_scopes.iter().filter_map(|block| db.block_def_map(*block)) { 103 for block_def_map in body.block_scopes.iter().filter_map(|block| db.block_def_map(*block)) {
104 for (_, module) in block_def_map.modules() { 104 for (_, module) in block_def_map.modules() {
105 for (def_id, _) in module.scope.values() { 105 for def_id in module.scope.declarations() {
106 let mut validator = DeclValidator::new(self.db, self.krate, self.sink); 106 let mut validator = DeclValidator::new(self.db, self.krate, self.sink);
107 validator.validate_item(def_id); 107 validator.validate_item(def_id);
108 } 108 }
@@ -902,4 +902,17 @@ extern {
902 "#, 902 "#,
903 ); 903 );
904 } 904 }
905
906 #[test]
907 fn infinite_loop_inner_items() {
908 check_diagnostics(
909 r#"
910fn qualify() {
911 mod foo {
912 use super::*;
913 }
914}
915 "#,
916 )
917 }
905} 918}
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 7ce0f864c..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
19use crate::{ 19use 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
26pub struct HirFormatter<'a> { 26pub struct HirFormatter<'a> {
@@ -268,6 +268,16 @@ impl HirDisplay for ProjectionTy {
268 } 268 }
269} 269}
270 270
271impl 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
271impl HirDisplay for Ty { 281impl 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() {
@@ -344,7 +354,7 @@ impl HirDisplay for Ty {
344 }; 354 };
345 355
346 if let [GenericPredicate::Implemented(trait_ref), _] = predicates.as_ref() { 356 if let [GenericPredicate::Implemented(trait_ref), _] = predicates.as_ref() {
347 let trait_ = trait_ref.trait_; 357 let trait_ = trait_ref.hir_trait_id();
348 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) { 358 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) {
349 return write!(f, "{}", ty_display); 359 return write!(f, "{}", ty_display);
350 } 360 }
@@ -670,7 +680,7 @@ fn write_bounds_like_dyn_trait(
670 for p in predicates.iter() { 680 for p in predicates.iter() {
671 match p { 681 match p {
672 GenericPredicate::Implemented(trait_ref) => { 682 GenericPredicate::Implemented(trait_ref) => {
673 let trait_ = trait_ref.trait_; 683 let trait_ = trait_ref.hir_trait_id();
674 if !is_fn_trait { 684 if !is_fn_trait {
675 is_fn_trait = fn_traits(f.db.upcast(), trait_).any(|it| it == trait_); 685 is_fn_trait = fn_traits(f.db.upcast(), trait_).any(|it| it == trait_);
676 } 686 }
@@ -685,7 +695,7 @@ fn write_bounds_like_dyn_trait(
685 // existential) here, which is the only thing that's 695 // existential) here, which is the only thing that's
686 // possible in actual Rust, and hence don't print it 696 // possible in actual Rust, and hence don't print it
687 write!(f, "{}", f.db.trait_data(trait_).name)?; 697 write!(f, "{}", f.db.trait_data(trait_).name)?;
688 if let [_, params @ ..] = &*trait_ref.substs.0 { 698 if let [_, params @ ..] = &*trait_ref.substitution.0 {
689 if is_fn_trait { 699 if is_fn_trait {
690 if let Some(args) = params.first().and_then(|it| it.as_tuple()) { 700 if let Some(args) = params.first().and_then(|it| it.as_tuple()) {
691 write!(f, "(")?; 701 write!(f, "(")?;
@@ -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 {
@@ -745,16 +756,16 @@ impl TraitRef {
745 return write!(f, "{}", TYPE_HINT_TRUNCATION); 756 return write!(f, "{}", TYPE_HINT_TRUNCATION);
746 } 757 }
747 758
748 self.substs[0].hir_fmt(f)?; 759 self.substitution[0].hir_fmt(f)?;
749 if use_as { 760 if use_as {
750 write!(f, " as ")?; 761 write!(f, " as ")?;
751 } else { 762 } else {
752 write!(f, ": ")?; 763 write!(f, ": ")?;
753 } 764 }
754 write!(f, "{}", f.db.trait_data(self.trait_).name)?; 765 write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?;
755 if self.substs.len() > 1 { 766 if self.substitution.len() > 1 {
756 write!(f, "<")?; 767 write!(f, "<")?;
757 f.write_joined(&self.substs[1..], ", ")?; 768 f.write_joined(&self.substitution[1..], ", ")?;
758 write!(f, ">")?; 769 write!(f, ">")?;
759 } 770 }
760 Ok(()) 771 Ok(())
@@ -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 2610c9279..82186979a 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -37,12 +37,12 @@ use stdx::impl_from;
37use syntax::SmolStr; 37use syntax::SmolStr;
38 38
39use super::{ 39use 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};
43use crate::{ 43use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
45 to_assoc_type_id, AliasTy, Interner, TyKind, 45 to_assoc_type_id, to_chalk_trait_id, AliasEq, AliasTy, Interner, TyKind,
46}; 46};
47 47
48pub(crate) use unify::unify; 48pub(crate) use unify::unify;
@@ -394,16 +394,17 @@ impl<'a> InferenceContext<'a> {
394 .push(inner_ty) 394 .push(inner_ty)
395 .fill(params.iter().cloned()) 395 .fill(params.iter().cloned())
396 .build(); 396 .build();
397 let trait_ref = TraitRef { trait_, substs: substs.clone() }; 397 let trait_ref =
398 let projection = ProjectionPredicate { 398 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() };
399 ty: ty.clone(), 399 let alias_eq = AliasEq {
400 projection_ty: ProjectionTy { 400 alias: AliasTy::Projection(ProjectionTy {
401 associated_ty_id: to_assoc_type_id(res_assoc_ty), 401 associated_ty_id: to_assoc_type_id(res_assoc_ty),
402 substitution: substs, 402 substitution: substs,
403 }, 403 }),
404 ty: ty.clone(),
404 }; 405 };
405 self.obligations.push(Obligation::Trait(trait_ref)); 406 self.obligations.push(Obligation::Trait(trait_ref));
406 self.obligations.push(Obligation::Projection(projection)); 407 self.obligations.push(Obligation::AliasEq(alias_eq));
407 self.resolve_ty_as_possible(ty) 408 self.resolve_ty_as_possible(ty)
408 } 409 }
409 None => self.err_ty(), 410 None => self.err_ty(),
@@ -428,8 +429,8 @@ impl<'a> InferenceContext<'a> {
428 429
429 fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty { 430 fn normalize_projection_ty(&mut self, proj_ty: ProjectionTy) -> Ty {
430 let var = self.table.new_type_var(); 431 let var = self.table.new_type_var();
431 let predicate = ProjectionPredicate { projection_ty: proj_ty, ty: var.clone() }; 432 let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
432 let obligation = Obligation::Projection(predicate); 433 let obligation = Obligation::AliasEq(alias_eq);
433 self.obligations.push(obligation); 434 self.obligations.push(obligation);
434 var 435 var
435 } 436 }
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index b1f98c507..b86474ed4 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -8,7 +8,8 @@ use chalk_ir::{Mutability, TyVariableKind};
8use hir_def::lang_item::LangItemTarget; 8use hir_def::lang_item::LangItemTarget;
9 9
10use crate::{ 10use crate::{
11 autoderef, traits::Solution, Interner, Obligation, Substitution, TraitRef, Ty, TyKind, 11 autoderef, to_chalk_trait_id, traits::Solution, Interner, Obligation, Substitution, TraitRef,
12 Ty, TyKind,
12}; 13};
13 14
14use super::{InEnvironment, InferenceContext}; 15use super::{InEnvironment, InferenceContext};
@@ -140,7 +141,8 @@ impl<'a> InferenceContext<'a> {
140 .push(from_ty.clone()) 141 .push(from_ty.clone())
141 .push(to_ty.clone()) 142 .push(to_ty.clone())
142 .build(); 143 .build();
143 let trait_ref = TraitRef { trait_: coerce_unsized_trait, substs }; 144 let trait_ref =
145 TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs };
144 let goal = InEnvironment::new(self.trait_env.clone(), Obligation::Trait(trait_ref)); 146 let goal = InEnvironment::new(self.trait_env.clone(), Obligation::Trait(trait_ref));
145 147
146 let canonicalizer = self.canonicalizer(); 148 let canonicalizer = self.canonicalizer();
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 0be8c5a90..93548b6c0 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -18,7 +18,7 @@ use crate::{
18 lower::lower_to_chalk_mutability, 18 lower::lower_to_chalk_mutability,
19 method_resolution, op, 19 method_resolution, op,
20 primitive::{self, UintTy}, 20 primitive::{self, UintTy},
21 to_assoc_type_id, 21 to_assoc_type_id, to_chalk_trait_id,
22 traits::{chalk::from_chalk, FnTrait, InEnvironment}, 22 traits::{chalk::from_chalk, FnTrait, InEnvironment},
23 utils::{generics, variant_data, Generics}, 23 utils::{generics, variant_data, Generics},
24 AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar, 24 AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar,
@@ -90,8 +90,10 @@ impl<'a> InferenceContext<'a> {
90 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 90 Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
91 91
92 let trait_env = Arc::clone(&self.trait_env); 92 let trait_env = Arc::clone(&self.trait_env);
93 let implements_fn_trait = 93 let implements_fn_trait = Obligation::Trait(TraitRef {
94 Obligation::Trait(TraitRef { trait_: fn_once_trait, substs: substs.clone() }); 94 trait_id: to_chalk_trait_id(fn_once_trait),
95 substitution: substs.clone(),
96 });
95 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment { 97 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
96 value: implements_fn_trait.clone(), 98 value: implements_fn_trait.clone(),
97 environment: trait_env, 99 environment: trait_env,
@@ -948,7 +950,10 @@ impl<'a> InferenceContext<'a> {
948 // construct a TraitDef 950 // construct a TraitDef
949 let substs = 951 let substs =
950 parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); 952 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
951 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); 953 self.obligations.push(Obligation::Trait(TraitRef {
954 trait_id: to_chalk_trait_id(trait_),
955 substitution: substs,
956 }));
952 } 957 }
953 } 958 }
954 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} 959 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index ea01d6238..e15135fc1 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -9,7 +9,9 @@ use hir_def::{
9}; 9};
10use hir_expand::name::Name; 10use hir_expand::name::Name;
11 11
12use crate::{method_resolution, Interner, Substitution, Ty, TyKind, ValueTyDefId}; 12use crate::{
13 method_resolution, to_chalk_trait_id, Interner, Substitution, Ty, TyKind, ValueTyDefId,
14};
13 15
14use super::{ExprOrPatId, InferenceContext, TraitRef}; 16use super::{ExprOrPatId, InferenceContext, TraitRef};
15 17
@@ -165,7 +167,7 @@ impl<'a> InferenceContext<'a> {
165 segment: PathSegment<'_>, 167 segment: PathSegment<'_>,
166 id: ExprOrPatId, 168 id: ExprOrPatId,
167 ) -> Option<(ValueNs, Option<Substitution>)> { 169 ) -> Option<(ValueNs, Option<Substitution>)> {
168 let trait_ = trait_ref.trait_; 170 let trait_ = trait_ref.hir_trait_id();
169 let item = 171 let item =
170 self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id)).find_map(|item| { 172 self.db.trait_data(trait_).items.iter().map(|(_name, id)| (*id)).find_map(|item| {
171 match item { 173 match item {
@@ -200,7 +202,7 @@ impl<'a> InferenceContext<'a> {
200 }; 202 };
201 203
202 self.write_assoc_resolution(id, item); 204 self.write_assoc_resolution(id, item);
203 Some((def, Some(trait_ref.substs))) 205 Some((def, Some(trait_ref.substitution)))
204 } 206 }
205 207
206 fn resolve_ty_assoc_item( 208 fn resolve_ty_assoc_item(
@@ -255,8 +257,8 @@ impl<'a> InferenceContext<'a> {
255 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 257 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
256 .build(); 258 .build();
257 self.obligations.push(super::Obligation::Trait(TraitRef { 259 self.obligations.push(super::Obligation::Trait(TraitRef {
258 trait_, 260 trait_id: to_chalk_trait_id(trait_),
259 substs: trait_substs.clone(), 261 substitution: trait_substs.clone(),
260 })); 262 }));
261 Some(trait_substs) 263 Some(trait_substs)
262 } 264 }
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index b2d4f67b3..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
8use super::{InferenceContext, Obligation}; 8use super::{InferenceContext, Obligation};
9use crate::{ 9use 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
14impl<'a> InferenceContext<'a> { 14impl<'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 {
@@ -390,18 +390,29 @@ impl InferenceTable {
390 ) -> bool { 390 ) -> bool {
391 match (pred1, pred2) { 391 match (pred1, pred2) {
392 (GenericPredicate::Implemented(tr1), GenericPredicate::Implemented(tr2)) 392 (GenericPredicate::Implemented(tr1), GenericPredicate::Implemented(tr2))
393 if tr1.trait_ == tr2.trait_ => 393 if tr1.trait_id == tr2.trait_id =>
394 { 394 {
395 self.unify_substs(&tr1.substs, &tr2.substs, 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 52b498ff7..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};
48pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 48pub use traits::{AliasEq, InEnvironment, Obligation, TraitEnvironment};
49 49
50pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind}; 50pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind};
51 51
@@ -58,6 +58,8 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>;
58pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 58pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
59pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; 59pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
60 60
61pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
62
61#[derive(Clone, PartialEq, Eq, Debug, Hash)] 63#[derive(Clone, PartialEq, Eq, Debug, Hash)]
62pub enum Lifetime { 64pub enum Lifetime {
63 Parameter(LifetimeParamId), 65 Parameter(LifetimeParamId),
@@ -70,6 +72,20 @@ pub struct OpaqueTy {
70 pub substitution: Substitution, 72 pub substitution: Substitution,
71} 73}
72 74
75impl 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
73/// A "projection" type corresponds to an (unnormalized) 89/// A "projection" type corresponds to an (unnormalized)
74/// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the 90/// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
75/// trait and all its parameters are fully known. 91/// trait and all its parameters are fully known.
@@ -81,7 +97,10 @@ pub struct ProjectionTy {
81 97
82impl ProjectionTy { 98impl ProjectionTy {
83 pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef { 99 pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
84 TraitRef { trait_: self.trait_(db), substs: self.substitution.clone() } 100 TraitRef {
101 trait_id: to_chalk_trait_id(self.trait_(db)),
102 substitution: self.substitution.clone(),
103 }
85 } 104 }
86 105
87 fn trait_(&self, db: &dyn HirDatabase) -> TraitId { 106 fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
@@ -128,6 +147,25 @@ pub enum AliasTy {
128 Opaque(OpaqueTy), 147 Opaque(OpaqueTy),
129} 148}
130 149
150impl 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}
131/// A type. 169/// A type.
132/// 170///
133/// 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
@@ -493,23 +531,25 @@ impl<T: TypeWalk> TypeWalk for Binders<T> {
493} 531}
494 532
495/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. 533/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
496/// Name to be bikeshedded: TraitBound? TraitImplements?
497#[derive(Clone, PartialEq, Eq, Debug, Hash)] 534#[derive(Clone, PartialEq, Eq, Debug, Hash)]
498pub struct TraitRef { 535pub struct TraitRef {
499 /// FIXME name? 536 pub trait_id: ChalkTraitId,
500 pub trait_: TraitId, 537 pub substitution: Substitution,
501 pub substs: Substitution,
502} 538}
503 539
504impl TraitRef { 540impl TraitRef {
505 pub fn self_ty(&self) -> &Ty { 541 pub fn self_type_parameter(&self) -> &Ty {
506 &self.substs[0] 542 &self.substitution[0]
543 }
544
545 pub fn hir_trait_id(&self) -> TraitId {
546 from_chalk_trait_id(self.trait_id)
507 } 547 }
508} 548}
509 549
510impl TypeWalk for TraitRef { 550impl TypeWalk for TraitRef {
511 fn walk(&self, f: &mut impl FnMut(&Ty)) { 551 fn walk(&self, f: &mut impl FnMut(&Ty)) {
512 self.substs.walk(f); 552 self.substitution.walk(f);
513 } 553 }
514 554
515 fn walk_mut_binders( 555 fn walk_mut_binders(
@@ -517,7 +557,7 @@ impl TypeWalk for TraitRef {
517 f: &mut impl FnMut(&mut Ty, DebruijnIndex), 557 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
518 binders: DebruijnIndex, 558 binders: DebruijnIndex,
519 ) { 559 ) {
520 self.substs.walk_mut_binders(f, binders); 560 self.substitution.walk_mut_binders(f, binders);
521 } 561 }
522} 562}
523 563
@@ -528,7 +568,7 @@ pub enum GenericPredicate {
528 /// The given trait needs to be implemented for its type parameters. 568 /// The given trait needs to be implemented for its type parameters.
529 Implemented(TraitRef), 569 Implemented(TraitRef),
530 /// An associated type bindings like in `Iterator<Item = T>`. 570 /// An associated type bindings like in `Iterator<Item = T>`.
531 Projection(ProjectionPredicate), 571 AliasEq(AliasEq),
532 /// 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
533 /// be resolved, they will just be Unknown). 573 /// be resolved, they will just be Unknown).
534 Error, 574 Error,
@@ -546,8 +586,10 @@ impl GenericPredicate {
546 pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> { 586 pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> {
547 match self { 587 match self {
548 GenericPredicate::Implemented(tr) => Some(tr.clone()), 588 GenericPredicate::Implemented(tr) => Some(tr.clone()),
549 GenericPredicate::Projection(proj) => Some(proj.projection_ty.trait_ref(db)), 589 GenericPredicate::AliasEq(AliasEq { alias: AliasTy::Projection(proj), .. }) => {
550 GenericPredicate::Error => None, 590 Some(proj.trait_ref(db))
591 }
592 GenericPredicate::AliasEq(_) | GenericPredicate::Error => None,
551 } 593 }
552 } 594 }
553} 595}
@@ -556,7 +598,7 @@ impl TypeWalk for GenericPredicate {
556 fn walk(&self, f: &mut impl FnMut(&Ty)) { 598 fn walk(&self, f: &mut impl FnMut(&Ty)) {
557 match self { 599 match self {
558 GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f), 600 GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f),
559 GenericPredicate::Projection(projection_pred) => projection_pred.walk(f), 601 GenericPredicate::AliasEq(alias_eq) => alias_eq.walk(f),
560 GenericPredicate::Error => {} 602 GenericPredicate::Error => {}
561 } 603 }
562 } 604 }
@@ -568,9 +610,7 @@ impl TypeWalk for GenericPredicate {
568 ) { 610 ) {
569 match self { 611 match self {
570 GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders), 612 GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders),
571 GenericPredicate::Projection(projection_pred) => { 613 GenericPredicate::AliasEq(alias_eq) => alias_eq.walk_mut_binders(f, binders),
572 projection_pred.walk_mut_binders(f, binders)
573 }
574 GenericPredicate::Error => {} 614 GenericPredicate::Error => {}
575 } 615 }
576 } 616 }
@@ -784,7 +824,7 @@ impl Ty {
784 824
785 /// If this is a `dyn Trait`, returns that trait. 825 /// If this is a `dyn Trait`, returns that trait.
786 pub fn dyn_trait(&self) -> Option<TraitId> { 826 pub fn dyn_trait(&self) -> Option<TraitId> {
787 self.dyn_trait_ref().map(|it| it.trait_) 827 self.dyn_trait_ref().map(|it| it.trait_id).map(from_chalk_trait_id)
788 } 828 }
789 829
790 fn builtin_deref(&self) -> Option<Ty> { 830 fn builtin_deref(&self) -> Option<Ty> {
@@ -868,8 +908,8 @@ impl Ty {
868 // Parameters will be walked outside, and projection predicate is not used. 908 // Parameters will be walked outside, and projection predicate is not used.
869 // So just provide the Future trait. 909 // So just provide the Future trait.
870 let impl_bound = GenericPredicate::Implemented(TraitRef { 910 let impl_bound = GenericPredicate::Implemented(TraitRef {
871 trait_: future_trait, 911 trait_id: to_chalk_trait_id(future_trait),
872 substs: Substitution::empty(), 912 substitution: Substitution::empty(),
873 }); 913 });
874 Some(vec![impl_bound]) 914 Some(vec![impl_bound])
875 } else { 915 } else {
@@ -1158,3 +1198,11 @@ pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderI
1158 idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), 1198 idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(),
1159 } 1199 }
1160} 1200}
1201
1202pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId {
1203 chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id))
1204}
1205
1206pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId {
1207 salsa::InternKey::from_intern_id(id.0)
1208}
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 462882b2b..7d22c3df5 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -27,14 +27,14 @@ use stdx::impl_from;
27 27
28use crate::{ 28use crate::{
29 db::HirDatabase, 29 db::HirDatabase,
30 to_assoc_type_id, to_placeholder_idx, 30 to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
31 traits::chalk::{Interner, ToChalk}, 31 traits::chalk::{Interner, ToChalk},
32 utils::{ 32 utils::{
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
@@ -360,7 +360,7 @@ impl<'a> TyLoweringContext<'a> {
360 // FIXME handle type parameters on the segment 360 // FIXME handle type parameters on the segment
361 TyKind::Alias(AliasTy::Projection(ProjectionTy { 361 TyKind::Alias(AliasTy::Projection(ProjectionTy {
362 associated_ty_id: to_assoc_type_id(associated_ty), 362 associated_ty_id: to_assoc_type_id(associated_ty),
363 substitution: super_trait_ref.substs, 363 substitution: super_trait_ref.substitution,
364 })) 364 }))
365 .intern(&Interner) 365 .intern(&Interner)
366 } 366 }
@@ -470,9 +470,9 @@ impl<'a> TyLoweringContext<'a> {
470 "there should be generics if there's a generic param", 470 "there should be generics if there's a generic param",
471 ), 471 ),
472 ); 472 );
473 t.substs.clone().subst_bound_vars(&s) 473 t.substitution.clone().subst_bound_vars(&s)
474 } 474 }
475 TypeParamLoweringMode::Variable => t.substs.clone(), 475 TypeParamLoweringMode::Variable => t.substitution.clone(),
476 }; 476 };
477 // We need to shift in the bound vars, since 477 // We need to shift in the bound vars, since
478 // associated_type_shorthand_candidates does not do that 478 // associated_type_shorthand_candidates does not do that
@@ -641,7 +641,7 @@ impl<'a> TyLoweringContext<'a> {
641 if let Some(self_ty) = explicit_self_ty { 641 if let Some(self_ty) = explicit_self_ty {
642 substs.0[0] = self_ty; 642 substs.0[0] = self_ty;
643 } 643 }
644 TraitRef { trait_: resolved, substs } 644 TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
645 } 645 }
646 646
647 fn lower_trait_ref( 647 fn lower_trait_ref(
@@ -743,16 +743,16 @@ impl<'a> TyLoweringContext<'a> {
743 }; 743 };
744 let projection_ty = ProjectionTy { 744 let projection_ty = ProjectionTy {
745 associated_ty_id: to_assoc_type_id(associated_ty), 745 associated_ty_id: to_assoc_type_id(associated_ty),
746 substitution: super_trait_ref.substs, 746 substitution: super_trait_ref.substitution,
747 }; 747 };
748 let mut preds = SmallVec::with_capacity( 748 let mut preds = SmallVec::with_capacity(
749 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(), 749 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
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(
@@ -820,8 +820,8 @@ pub fn associated_type_shorthand_candidates<R>(
820 == TypeParamProvenance::TraitSelf 820 == TypeParamProvenance::TraitSelf
821 { 821 {
822 let trait_ref = TraitRef { 822 let trait_ref = TraitRef {
823 trait_: trait_id, 823 trait_id: to_chalk_trait_id(trait_id),
824 substs: Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST), 824 substitution: Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST),
825 }; 825 };
826 traits_.push(trait_ref); 826 traits_.push(trait_ref);
827 } 827 }
@@ -832,7 +832,7 @@ pub fn associated_type_shorthand_candidates<R>(
832 }; 832 };
833 833
834 for t in traits_from_env.into_iter().flat_map(move |t| all_super_trait_refs(db, t)) { 834 for t in traits_from_env.into_iter().flat_map(move |t| all_super_trait_refs(db, t)) {
835 let data = db.trait_data(t.trait_); 835 let data = db.trait_data(t.hir_trait_id());
836 836
837 for (name, assoc_id) in &data.items { 837 for (name, assoc_id) in &data.items {
838 match assoc_id { 838 match assoc_id {
@@ -926,7 +926,7 @@ pub(crate) fn trait_environment_query(
926 continue; 926 continue;
927 } 927 }
928 if let GenericPredicate::Implemented(tr) = &pred { 928 if let GenericPredicate::Implemented(tr) = &pred {
929 traits_in_scope.push((tr.self_ty().clone(), tr.trait_)); 929 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id()));
930 } 930 }
931 let program_clause: chalk_ir::ProgramClause<Interner> = 931 let program_clause: chalk_ir::ProgramClause<Interner> =
932 pred.clone().to_chalk(db).cast(&Interner); 932 pred.clone().to_chalk(db).cast(&Interner);
@@ -950,7 +950,7 @@ pub(crate) fn trait_environment_query(
950 // inside consts or type aliases) 950 // inside consts or type aliases)
951 cov_mark::hit!(trait_self_implements_self); 951 cov_mark::hit!(trait_self_implements_self);
952 let substs = Substitution::type_params(db, trait_id); 952 let substs = Substitution::type_params(db, trait_id);
953 let trait_ref = TraitRef { trait_: trait_id, substs }; 953 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
954 let pred = GenericPredicate::Implemented(trait_ref); 954 let pred = GenericPredicate::Implemented(trait_ref);
955 let program_clause: chalk_ir::ProgramClause<Interner> = 955 let program_clause: chalk_ir::ProgramClause<Interner> =
956 pred.clone().to_chalk(db).cast(&Interner); 956 pred.clone().to_chalk(db).cast(&Interner);
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 943d3339b..01b78fb44 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -19,6 +19,7 @@ use crate::{
19 db::HirDatabase, 19 db::HirDatabase,
20 from_foreign_def_id, 20 from_foreign_def_id,
21 primitive::{self, FloatTy, IntTy, UintTy}, 21 primitive::{self, FloatTy, IntTy, UintTy},
22 to_chalk_trait_id,
22 utils::all_super_traits, 23 utils::all_super_traits,
23 AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner, 24 AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner,
24 Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, 25 Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk,
@@ -101,7 +102,7 @@ impl TraitImpls {
101 for (_module_id, module_data) in crate_def_map.modules() { 102 for (_module_id, module_data) in crate_def_map.modules() {
102 for impl_id in module_data.scope.impls() { 103 for impl_id in module_data.scope.impls() {
103 let target_trait = match db.impl_trait(impl_id) { 104 let target_trait = match db.impl_trait(impl_id) {
104 Some(tr) => tr.value.trait_, 105 Some(tr) => tr.value.hir_trait_id(),
105 None => continue, 106 None => continue,
106 }; 107 };
107 let self_ty = db.impl_self_ty(impl_id); 108 let self_ty = db.impl_self_ty(impl_id);
@@ -773,7 +774,7 @@ fn generic_implements_goal(
773 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 774 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
774 .build(); 775 .build();
775 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1)); 776 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1));
776 let trait_ref = TraitRef { trait_, substs }; 777 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
777 let obligation = super::Obligation::Trait(trait_ref); 778 let obligation = super::Obligation::Trait(trait_ref);
778 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } 779 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) }
779} 780}
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index 40eb1034e..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};
8use hir_def::{lang_item::LangItemTarget, TraitId}; 8use hir_def::{lang_item::LangItemTarget, TraitId};
9use stdx::panic_context; 9use stdx::panic_context;
10 10
11use crate::{db::HirDatabase, DebruijnIndex, Substitution}; 11use crate::{
12 12 db::HirDatabase, AliasTy, Canonical, DebruijnIndex, GenericPredicate, HirDisplay, Substitution,
13use super::{ 13 TraitRef, Ty, TyKind, TypeWalk,
14 Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TyKind, TypeWalk,
15}; 14};
16 15
17use self::chalk::{from_chalk, Interner, ToChalk}; 16use 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
99impl Obligation { 98impl 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)]
112pub struct ProjectionPredicate { 109pub struct AliasEq {
113 pub projection_ty: ProjectionTy, 110 pub alias: AliasTy,
114 pub ty: Ty, 111 pub ty: Ty,
115} 112}
116 113
117impl TypeWalk for ProjectionPredicate { 114impl 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
@@ -137,13 +140,15 @@ pub(crate) fn trait_solve_query(
137 goal: Canonical<InEnvironment<Obligation>>, 140 goal: Canonical<InEnvironment<Obligation>>,
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.trait_).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 bef6e7e9c..080764e76 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -19,10 +19,10 @@ use crate::{
19 display::HirDisplay, 19 display::HirDisplay,
20 from_assoc_type_id, 20 from_assoc_type_id,
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, 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,
@@ -219,9 +219,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
219 // for<T> <Self> [Future<Self>, Future::Output<Self> = T] 219 // for<T> <Self> [Future<Self>, Future::Output<Self> = T]
220 // ^1 ^0 ^0 ^0 ^1 220 // ^1 ^0 ^0 ^0 ^1
221 let impl_bound = GenericPredicate::Implemented(TraitRef { 221 let impl_bound = GenericPredicate::Implemented(TraitRef {
222 trait_: future_trait, 222 trait_id: to_chalk_trait_id(future_trait),
223 // Self type as the first parameter. 223 // Self type as the first parameter.
224 substs: Substitution::single( 224 substitution: Substitution::single(
225 TyKind::BoundVar(BoundVar { 225 TyKind::BoundVar(BoundVar {
226 debruijn: DebruijnIndex::INNERMOST, 226 debruijn: DebruijnIndex::INNERMOST,
227 index: 0, 227 index: 0,
@@ -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(
@@ -546,7 +546,7 @@ fn impl_def_datum(
546 546
547 let generic_params = generics(db.upcast(), impl_id.into()); 547 let generic_params = generics(db.upcast(), impl_id.into());
548 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 548 let bound_vars = Substitution::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
549 let trait_ = trait_ref.trait_; 549 let trait_ = trait_ref.hir_trait_id();
550 let impl_type = if impl_id.lookup(db.upcast()).container.krate() == krate { 550 let impl_type = if impl_id.lookup(db.upcast()).container.krate() == krate {
551 rust_ir::ImplType::Local 551 rust_ir::ImplType::Local
552 } else { 552 } else {
@@ -614,7 +614,7 @@ fn type_alias_associated_ty_value(
614 let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved 614 let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved
615 615
616 let assoc_ty = db 616 let assoc_ty = db
617 .trait_data(trait_ref.trait_) 617 .trait_data(trait_ref.hir_trait_id())
618 .associated_type_by_name(&type_alias_data.name) 618 .associated_type_by_name(&type_alias_data.name)
619 .expect("assoc ty value should not exist"); // validated when building the impl data as well 619 .expect("assoc ty value should not exist"); // validated when building the impl data as well
620 let ty = db.ty(type_alias.into()); 620 let ty = db.ty(type_alias.into());
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}
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index 7351e4e54..b66243d48 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -55,9 +55,9 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
55 // lifetime problems, but since there usually shouldn't be more than a 55 // lifetime problems, but since there usually shouldn't be more than a
56 // few direct traits this should be fine (we could even use some kind of 56 // few direct traits this should be fine (we could even use some kind of
57 // SmallVec if performance is a concern) 57 // SmallVec if performance is a concern)
58 let generic_params = db.generic_params(trait_ref.trait_.into()); 58 let generic_params = db.generic_params(trait_ref.hir_trait_id().into());
59 let trait_self = match generic_params.find_trait_self_param() { 59 let trait_self = match generic_params.find_trait_self_param() {
60 Some(p) => TypeParamId { parent: trait_ref.trait_.into(), local_id: p }, 60 Some(p) => TypeParamId { parent: trait_ref.hir_trait_id().into(), local_id: p },
61 None => return Vec::new(), 61 None => return Vec::new(),
62 }; 62 };
63 db.generic_predicates_for_param(trait_self) 63 db.generic_predicates_for_param(trait_self)
@@ -68,7 +68,7 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
68 _ => None, 68 _ => None,
69 }) 69 })
70 }) 70 })
71 .map(|pred| pred.subst(&trait_ref.substs)) 71 .map(|pred| pred.subst(&trait_ref.substitution))
72 .collect() 72 .collect()
73} 73}
74 74
@@ -108,7 +108,7 @@ pub(super) fn all_super_trait_refs(db: &dyn HirDatabase, trait_ref: TraitRef) ->
108 // yeah this is quadratic, but trait hierarchies should be flat 108 // yeah this is quadratic, but trait hierarchies should be flat
109 // enough that this doesn't matter 109 // enough that this doesn't matter
110 for tt in direct_super_trait_refs(db, t) { 110 for tt in direct_super_trait_refs(db, t) {
111 if !result.iter().any(|tr| tr.trait_ == tt.trait_) { 111 if !result.iter().any(|tr| tr.trait_id == tt.trait_id) {
112 result.push(tt); 112 result.push(tt);
113 } 113 }
114 } 114 }
@@ -123,7 +123,7 @@ pub(super) fn associated_type_by_name_including_super_traits(
123 name: &Name, 123 name: &Name,
124) -> Option<(TraitRef, TypeAliasId)> { 124) -> Option<(TraitRef, TypeAliasId)> {
125 all_super_trait_refs(db, trait_ref).into_iter().find_map(|t| { 125 all_super_trait_refs(db, trait_ref).into_iter().find_map(|t| {
126 let assoc_type = db.trait_data(t.trait_).associated_type_by_name(name)?; 126 let assoc_type = db.trait_data(t.hir_trait_id()).associated_type_by_name(name)?;
127 Some((t, assoc_type)) 127 Some((t, assoc_type))
128 }) 128 })
129} 129}