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.rs9
-rw-r--r--crates/hir_ty/src/chalk_cast.rs53
-rw-r--r--crates/hir_ty/src/db.rs13
-rw-r--r--crates/hir_ty/src/display.rs55
-rw-r--r--crates/hir_ty/src/infer.rs12
-rw-r--r--crates/hir_ty/src/infer/coerce.rs7
-rw-r--r--crates/hir_ty/src/infer/expr.rs25
-rw-r--r--crates/hir_ty/src/infer/path.rs12
-rw-r--r--crates/hir_ty/src/infer/unify.rs30
-rw-r--r--crates/hir_ty/src/lib.rs48
-rw-r--r--crates/hir_ty/src/lower.rs40
-rw-r--r--crates/hir_ty/src/method_resolution.rs6
-rw-r--r--crates/hir_ty/src/tests/traits.rs4
-rw-r--r--crates/hir_ty/src/traits.rs35
-rw-r--r--crates/hir_ty/src/traits/chalk.rs16
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs41
-rw-r--r--crates/hir_ty/src/utils.rs4
17 files changed, 199 insertions, 211 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index 33b966026..23ab042c1 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -6,6 +6,7 @@
6use std::iter::successors; 6use std::iter::successors;
7 7
8use base_db::CrateId; 8use base_db::CrateId;
9use chalk_ir::cast::Cast;
9use hir_def::lang_item::LangItemTarget; 10use hir_def::lang_item::LangItemTarget;
10use hir_expand::name::name; 11use hir_expand::name::name;
11use log::{info, warn}; 12use log::{info, warn};
@@ -15,8 +16,8 @@ use crate::{
15 to_assoc_type_id, to_chalk_trait_id, 16 to_assoc_type_id, to_chalk_trait_id,
16 traits::{InEnvironment, Solution}, 17 traits::{InEnvironment, Solution},
17 utils::generics, 18 utils::generics,
18 AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, Obligation, ProjectionTy, 19 AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, ProjectionTy, Substitution,
19 Substitution, TraitRef, Ty, TyKind, 20 TraitRef, Ty, TyKind,
20}; 21};
21 22
22const AUTODEREF_RECURSION_LIMIT: usize = 10; 23const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -74,7 +75,7 @@ fn deref_by_trait(
74 let implements_goal = Canonical { 75 let implements_goal = Canonical {
75 kinds: ty.value.kinds.clone(), 76 kinds: ty.value.kinds.clone(),
76 value: InEnvironment { 77 value: InEnvironment {
77 value: Obligation::Trait(trait_ref), 78 value: trait_ref.cast(&Interner),
78 environment: ty.environment.clone(), 79 environment: ty.environment.clone(),
79 }, 80 },
80 }; 81 };
@@ -92,7 +93,7 @@ fn deref_by_trait(
92 .intern(&Interner), 93 .intern(&Interner),
93 }; 94 };
94 95
95 let obligation = super::Obligation::AliasEq(projection); 96 let obligation = projection.cast(&Interner);
96 97
97 let in_env = InEnvironment { value: obligation, environment: ty.environment }; 98 let in_env = InEnvironment { value: obligation, environment: ty.environment };
98 99
diff --git a/crates/hir_ty/src/chalk_cast.rs b/crates/hir_ty/src/chalk_cast.rs
new file mode 100644
index 000000000..bf884ae15
--- /dev/null
+++ b/crates/hir_ty/src/chalk_cast.rs
@@ -0,0 +1,53 @@
1//! Implementations of the Chalk `Cast` trait for our types.
2
3use chalk_ir::{
4 cast::{Cast, CastTo},
5 interner::HasInterner,
6};
7
8use crate::{AliasEq, DomainGoal, Interner, TraitRef, WhereClause};
9
10macro_rules! has_interner {
11 ($t:ty) => {
12 impl HasInterner for $t {
13 type Interner = crate::Interner;
14 }
15 };
16}
17
18has_interner!(WhereClause);
19has_interner!(DomainGoal);
20
21impl CastTo<WhereClause> for TraitRef {
22 fn cast_to(self, _interner: &Interner) -> WhereClause {
23 WhereClause::Implemented(self)
24 }
25}
26
27impl CastTo<WhereClause> for AliasEq {
28 fn cast_to(self, _interner: &Interner) -> WhereClause {
29 WhereClause::AliasEq(self)
30 }
31}
32
33impl CastTo<DomainGoal> for WhereClause {
34 fn cast_to(self, _interner: &Interner) -> DomainGoal {
35 DomainGoal::Holds(self)
36 }
37}
38
39macro_rules! transitive_impl {
40 ($a:ty, $b:ty, $c:ty) => {
41 impl CastTo<$c> for $a {
42 fn cast_to(self, interner: &Interner) -> $c {
43 self.cast::<$b>(interner).cast(interner)
44 }
45 }
46 };
47}
48
49// In Chalk, these can be done as blanket impls, but that doesn't work here
50// because of coherence
51
52transitive_impl!(TraitRef, WhereClause, DomainGoal);
53transitive_impl!(AliasEq, WhereClause, DomainGoal);
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs
index 74a048672..91a2e0b5b 100644
--- a/crates/hir_ty/src/db.rs
+++ b/crates/hir_ty/src/db.rs
@@ -12,8 +12,8 @@ use la_arena::ArenaMap;
12use crate::{ 12use crate::{
13 method_resolution::{InherentImpls, TraitImpls}, 13 method_resolution::{InherentImpls, TraitImpls},
14 traits::chalk, 14 traits::chalk,
15 Binders, CallableDefId, FnDefId, GenericPredicate, ImplTraitId, InferenceResult, PolyFnSig, 15 Binders, CallableDefId, FnDefId, ImplTraitId, InferenceResult, PolyFnSig, ReturnTypeImplTraits,
16 ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId, 16 TraitRef, Ty, TyDefId, ValueTyDefId, WhereClause,
17}; 17};
18use hir_expand::name::Name; 18use hir_expand::name::Name;
19 19
@@ -57,13 +57,10 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
57 57
58 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)] 58 #[salsa::invoke(crate::lower::generic_predicates_for_param_query)]
59 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)] 59 #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)]
60 fn generic_predicates_for_param( 60 fn generic_predicates_for_param(&self, param_id: TypeParamId) -> Arc<[Binders<WhereClause>]>;
61 &self,
62 param_id: TypeParamId,
63 ) -> Arc<[Binders<GenericPredicate>]>;
64 61
65 #[salsa::invoke(crate::lower::generic_predicates_query)] 62 #[salsa::invoke(crate::lower::generic_predicates_query)]
66 fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>; 63 fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<WhereClause>]>;
67 64
68 #[salsa::invoke(crate::lower::trait_environment_query)] 65 #[salsa::invoke(crate::lower::trait_environment_query)]
69 fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>; 66 fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>;
@@ -122,7 +119,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
122 fn trait_solve( 119 fn trait_solve(
123 &self, 120 &self,
124 krate: CrateId, 121 krate: CrateId,
125 goal: crate::Canonical<crate::InEnvironment<crate::Obligation>>, 122 goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>,
126 ) -> Option<crate::traits::Solution>; 123 ) -> Option<crate::traits::Solution>;
127 124
128 #[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)] 125 #[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)]
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 59a1bd9b0..3845009ae 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -19,8 +19,8 @@ use hir_expand::name::Name;
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, AliasEq, AliasTy, 21 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy,
22 CallableDefId, CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation, 22 CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy,
23 OpaqueTy, ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind, 23 ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause,
24}; 24};
25 25
26pub struct HirFormatter<'a> { 26pub struct HirFormatter<'a> {
@@ -353,7 +353,7 @@ impl HirDisplay for Ty {
353 _ => Cow::Borrowed(&[][..]), 353 _ => Cow::Borrowed(&[][..]),
354 }; 354 };
355 355
356 if let [GenericPredicate::Implemented(trait_ref), _] = predicates.as_ref() { 356 if let [WhereClause::Implemented(trait_ref), _] = predicates.as_ref() {
357 let trait_ = trait_ref.hir_trait_id(); 357 let trait_ = trait_ref.hir_trait_id();
358 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) { 358 if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_) {
359 return write!(f, "{}", ty_display); 359 return write!(f, "{}", ty_display);
@@ -652,7 +652,7 @@ fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = Trai
652 652
653pub fn write_bounds_like_dyn_trait_with_prefix( 653pub fn write_bounds_like_dyn_trait_with_prefix(
654 prefix: &str, 654 prefix: &str,
655 predicates: &[GenericPredicate], 655 predicates: &[WhereClause],
656 f: &mut HirFormatter, 656 f: &mut HirFormatter,
657) -> Result<(), HirDisplayError> { 657) -> Result<(), HirDisplayError> {
658 write!(f, "{}", prefix)?; 658 write!(f, "{}", prefix)?;
@@ -665,7 +665,7 @@ pub fn write_bounds_like_dyn_trait_with_prefix(
665} 665}
666 666
667fn write_bounds_like_dyn_trait( 667fn write_bounds_like_dyn_trait(
668 predicates: &[GenericPredicate], 668 predicates: &[WhereClause],
669 f: &mut HirFormatter, 669 f: &mut HirFormatter,
670) -> Result<(), HirDisplayError> { 670) -> Result<(), HirDisplayError> {
671 // Note: This code is written to produce nice results (i.e. 671 // Note: This code is written to produce nice results (i.e.
@@ -679,7 +679,7 @@ fn write_bounds_like_dyn_trait(
679 let mut is_fn_trait = false; 679 let mut is_fn_trait = false;
680 for p in predicates.iter() { 680 for p in predicates.iter() {
681 match p { 681 match p {
682 GenericPredicate::Implemented(trait_ref) => { 682 WhereClause::Implemented(trait_ref) => {
683 let trait_ = trait_ref.hir_trait_id(); 683 let trait_ = trait_ref.hir_trait_id();
684 if !is_fn_trait { 684 if !is_fn_trait {
685 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_);
@@ -710,12 +710,12 @@ fn write_bounds_like_dyn_trait(
710 } 710 }
711 } 711 }
712 } 712 }
713 GenericPredicate::AliasEq(alias_eq) if is_fn_trait => { 713 WhereClause::AliasEq(alias_eq) if is_fn_trait => {
714 is_fn_trait = false; 714 is_fn_trait = false;
715 write!(f, " -> ")?; 715 write!(f, " -> ")?;
716 alias_eq.ty.hir_fmt(f)?; 716 alias_eq.ty.hir_fmt(f)?;
717 } 717 }
718 GenericPredicate::AliasEq(AliasEq { ty, alias }) => { 718 WhereClause::AliasEq(AliasEq { ty, alias }) => {
719 // in types in actual Rust, these will always come 719 // in types in actual Rust, these will always come
720 // after the corresponding Implemented predicate 720 // after the corresponding Implemented predicate
721 if angle_open { 721 if angle_open {
@@ -731,16 +731,6 @@ fn write_bounds_like_dyn_trait(
731 } 731 }
732 ty.hir_fmt(f)?; 732 ty.hir_fmt(f)?;
733 } 733 }
734 GenericPredicate::Error => {
735 if angle_open {
736 // impl Trait<X, {error}>
737 write!(f, ", ")?;
738 } else if !first {
739 // impl Trait + {error}
740 write!(f, " + ")?;
741 }
742 p.hir_fmt(f)?;
743 }
744 } 734 }
745 first = false; 735 first = false;
746 } 736 }
@@ -778,18 +768,15 @@ impl HirDisplay for TraitRef {
778 } 768 }
779} 769}
780 770
781impl HirDisplay for GenericPredicate { 771impl HirDisplay for WhereClause {
782 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 772 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
783 if f.should_truncate() { 773 if f.should_truncate() {
784 return write!(f, "{}", TYPE_HINT_TRUNCATION); 774 return write!(f, "{}", TYPE_HINT_TRUNCATION);
785 } 775 }
786 776
787 match self { 777 match self {
788 GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?, 778 WhereClause::Implemented(trait_ref) => trait_ref.hir_fmt(f)?,
789 GenericPredicate::AliasEq(AliasEq { 779 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
790 alias: AliasTy::Projection(projection_ty),
791 ty,
792 }) => {
793 write!(f, "<")?; 780 write!(f, "<")?;
794 projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?; 781 projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?;
795 write!( 782 write!(
@@ -799,7 +786,7 @@ impl HirDisplay for GenericPredicate {
799 )?; 786 )?;
800 ty.hir_fmt(f)?; 787 ty.hir_fmt(f)?;
801 } 788 }
802 GenericPredicate::AliasEq(_) | GenericPredicate::Error => write!(f, "{{error}}")?, 789 WhereClause::AliasEq(_) => write!(f, "{{error}}")?,
803 } 790 }
804 Ok(()) 791 Ok(())
805 } 792 }
@@ -818,22 +805,12 @@ impl HirDisplay for Lifetime {
818 } 805 }
819} 806}
820 807
821impl HirDisplay for Obligation { 808impl HirDisplay for DomainGoal {
822 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 809 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
823 match self { 810 match self {
824 Obligation::Trait(tr) => { 811 DomainGoal::Holds(wc) => {
825 write!(f, "Implements(")?; 812 write!(f, "Holds(")?;
826 tr.hir_fmt(f)?; 813 wc.hir_fmt(f)?;
827 write!(f, ")")
828 }
829 Obligation::AliasEq(AliasEq { alias, ty }) => {
830 write!(f, "Normalize(")?;
831 match alias {
832 AliasTy::Projection(projection_ty) => projection_ty.hir_fmt(f)?,
833 AliasTy::Opaque(opaque) => opaque.hir_fmt(f)?,
834 }
835 write!(f, " => ")?;
836 ty.hir_fmt(f)?;
837 write!(f, ")") 814 write!(f, ")")
838 } 815 }
839 } 816 }
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 82186979a..b9e434c78 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -18,7 +18,7 @@ use std::mem;
18use std::ops::Index; 18use std::ops::Index;
19use std::sync::Arc; 19use std::sync::Arc;
20 20
21use chalk_ir::Mutability; 21use chalk_ir::{cast::Cast, Mutability};
22use hir_def::{ 22use hir_def::{
23 body::Body, 23 body::Body,
24 data::{ConstData, FunctionData, StaticData}, 24 data::{ConstData, FunctionData, StaticData},
@@ -37,7 +37,7 @@ use stdx::impl_from;
37use syntax::SmolStr; 37use syntax::SmolStr;
38 38
39use super::{ 39use super::{
40 traits::{Guidance, Obligation, Solution}, 40 traits::{DomainGoal, Guidance, Solution},
41 InEnvironment, ProjectionTy, Substitution, TraitEnvironment, TraitRef, Ty, TypeWalk, 41 InEnvironment, ProjectionTy, Substitution, TraitEnvironment, TraitRef, Ty, TypeWalk,
42}; 42};
43use crate::{ 43use crate::{
@@ -204,7 +204,7 @@ struct InferenceContext<'a> {
204 resolver: Resolver, 204 resolver: Resolver,
205 table: unify::InferenceTable, 205 table: unify::InferenceTable,
206 trait_env: Arc<TraitEnvironment>, 206 trait_env: Arc<TraitEnvironment>,
207 obligations: Vec<Obligation>, 207 obligations: Vec<DomainGoal>,
208 result: InferenceResult, 208 result: InferenceResult,
209 /// The return type of the function being inferred, or the closure if we're 209 /// The return type of the function being inferred, or the closure if we're
210 /// currently within one. 210 /// currently within one.
@@ -403,8 +403,8 @@ impl<'a> InferenceContext<'a> {
403 }), 403 }),
404 ty: ty.clone(), 404 ty: ty.clone(),
405 }; 405 };
406 self.obligations.push(Obligation::Trait(trait_ref)); 406 self.obligations.push(trait_ref.cast(&Interner));
407 self.obligations.push(Obligation::AliasEq(alias_eq)); 407 self.obligations.push(alias_eq.cast(&Interner));
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(),
@@ -430,7 +430,7 @@ impl<'a> InferenceContext<'a> {
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 alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() }; 432 let alias_eq = AliasEq { alias: AliasTy::Projection(proj_ty), ty: var.clone() };
433 let obligation = Obligation::AliasEq(alias_eq); 433 let obligation = alias_eq.cast(&Interner);
434 self.obligations.push(obligation); 434 self.obligations.push(obligation);
435 var 435 var
436 } 436 }
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index b86474ed4..07eb96573 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -4,12 +4,11 @@
4//! 4//!
5//! See: https://doc.rust-lang.org/nomicon/coercions.html 5//! See: https://doc.rust-lang.org/nomicon/coercions.html
6 6
7use chalk_ir::{Mutability, TyVariableKind}; 7use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
8use hir_def::lang_item::LangItemTarget; 8use hir_def::lang_item::LangItemTarget;
9 9
10use crate::{ 10use crate::{
11 autoderef, to_chalk_trait_id, traits::Solution, Interner, Obligation, Substitution, TraitRef, 11 autoderef, to_chalk_trait_id, traits::Solution, Interner, Substitution, TraitRef, Ty, TyKind,
12 Ty, TyKind,
13}; 12};
14 13
15use super::{InEnvironment, InferenceContext}; 14use super::{InEnvironment, InferenceContext};
@@ -143,7 +142,7 @@ impl<'a> InferenceContext<'a> {
143 .build(); 142 .build();
144 let trait_ref = 143 let trait_ref =
145 TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs }; 144 TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs };
146 let goal = InEnvironment::new(self.trait_env.clone(), Obligation::Trait(trait_ref)); 145 let goal = InEnvironment::new(self.trait_env.clone(), trait_ref.cast(&Interner));
147 146
148 let canonicalizer = self.canonicalizer(); 147 let canonicalizer = self.canonicalizer();
149 let canonicalized = canonicalizer.canonicalize_obligation(goal); 148 let canonicalized = canonicalizer.canonicalize_obligation(goal);
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 93548b6c0..79bbc5dab 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -3,7 +3,7 @@
3use std::iter::{repeat, repeat_with}; 3use std::iter::{repeat, repeat_with};
4use std::{mem, sync::Arc}; 4use std::{mem, sync::Arc};
5 5
6use chalk_ir::{Mutability, TyVariableKind}; 6use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
7use hir_def::{ 7use hir_def::{
8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
9 path::{GenericArg, GenericArgs}, 9 path::{GenericArg, GenericArgs},
@@ -21,7 +21,7 @@ use crate::{
21 to_assoc_type_id, to_chalk_trait_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, DomainGoal, FnPointer, FnSig, Interner, Rawness, Scalar,
25 Substitution, TraitRef, Ty, TyKind, 25 Substitution, TraitRef, Ty, TyKind,
26}; 26};
27 27
@@ -90,10 +90,9 @@ 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 = Obligation::Trait(TraitRef { 93 let implements_fn_trait: DomainGoal =
94 trait_id: to_chalk_trait_id(fn_once_trait), 94 TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() }
95 substitution: substs.clone(), 95 .cast(&Interner);
96 });
97 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment { 96 let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
98 value: implements_fn_trait.clone(), 97 value: implements_fn_trait.clone(),
99 environment: trait_env, 98 environment: trait_env,
@@ -938,22 +937,20 @@ impl<'a> InferenceContext<'a> {
938 let generic_predicates = self.db.generic_predicates(def.into()); 937 let generic_predicates = self.db.generic_predicates(def.into());
939 for predicate in generic_predicates.iter() { 938 for predicate in generic_predicates.iter() {
940 let predicate = predicate.clone().subst(parameters); 939 let predicate = predicate.clone().subst(parameters);
941 if let Some(obligation) = Obligation::from_predicate(predicate) { 940 self.obligations.push(predicate.cast(&Interner));
942 self.obligations.push(obligation);
943 }
944 } 941 }
945 // add obligation for trait implementation, if this is a trait method 942 // add obligation for trait implementation, if this is a trait method
946 match def { 943 match def {
947 CallableDefId::FunctionId(f) => { 944 CallableDefId::FunctionId(f) => {
948 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container 945 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
949 { 946 {
950 // construct a TraitDef 947 // construct a TraitRef
951 let substs = 948 let substs =
952 parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); 949 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
953 self.obligations.push(Obligation::Trait(TraitRef { 950 self.obligations.push(
954 trait_id: to_chalk_trait_id(trait_), 951 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }
955 substitution: substs, 952 .cast(&Interner),
956 })); 953 );
957 } 954 }
958 } 955 }
959 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} 956 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index e15135fc1..58cce56ab 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -2,6 +2,7 @@
2 2
3use std::iter; 3use std::iter;
4 4
5use chalk_ir::cast::Cast;
5use hir_def::{ 6use hir_def::{
6 path::{Path, PathSegment}, 7 path::{Path, PathSegment},
7 resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, 8 resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs},
@@ -256,10 +257,13 @@ impl<'a> InferenceContext<'a> {
256 .push(ty.clone()) 257 .push(ty.clone())
257 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 258 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
258 .build(); 259 .build();
259 self.obligations.push(super::Obligation::Trait(TraitRef { 260 self.obligations.push(
260 trait_id: to_chalk_trait_id(trait_), 261 TraitRef {
261 substitution: trait_substs.clone(), 262 trait_id: to_chalk_trait_id(trait_),
262 })); 263 substitution: trait_substs.clone(),
264 }
265 .cast(&Interner),
266 );
263 Some(trait_substs) 267 Some(trait_substs)
264 } 268 }
265 AssocContainerId::ModuleId(_) => None, 269 AssocContainerId::ModuleId(_) => None,
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 4738ec08a..1fc03c8f4 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -5,10 +5,10 @@ use std::borrow::Cow;
5use chalk_ir::{FloatTy, IntTy, TyVariableKind}; 5use chalk_ir::{FloatTy, IntTy, TyVariableKind};
6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; 6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
7 7
8use super::{InferenceContext, Obligation}; 8use super::{DomainGoal, InferenceContext};
9use crate::{ 9use crate::{
10 AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, GenericPredicate, 10 AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, InEnvironment, InferenceVar,
11 InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, 11 Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause,
12}; 12};
13 13
14impl<'a> InferenceContext<'a> { 14impl<'a> InferenceContext<'a> {
@@ -87,14 +87,11 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
87 87
88 pub(crate) fn canonicalize_obligation( 88 pub(crate) fn canonicalize_obligation(
89 mut self, 89 mut self,
90 obligation: InEnvironment<Obligation>, 90 obligation: InEnvironment<DomainGoal>,
91 ) -> Canonicalized<InEnvironment<Obligation>> { 91 ) -> Canonicalized<InEnvironment<DomainGoal>> {
92 let result = match obligation.value { 92 let result = match obligation.value {
93 Obligation::Trait(tr) => { 93 DomainGoal::Holds(wc) => {
94 Obligation::Trait(self.do_canonicalize(tr, DebruijnIndex::INNERMOST)) 94 DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST))
95 }
96 Obligation::AliasEq(alias_eq) => {
97 Obligation::AliasEq(self.do_canonicalize(alias_eq, DebruijnIndex::INNERMOST))
98 } 95 }
99 }; 96 };
100 self.into_canonicalized(InEnvironment { 97 self.into_canonicalized(InEnvironment {
@@ -382,21 +379,16 @@ impl InferenceTable {
382 } 379 }
383 } 380 }
384 381
385 fn unify_preds( 382 fn unify_preds(&mut self, pred1: &WhereClause, pred2: &WhereClause, depth: usize) -> bool {
386 &mut self,
387 pred1: &GenericPredicate,
388 pred2: &GenericPredicate,
389 depth: usize,
390 ) -> bool {
391 match (pred1, pred2) { 383 match (pred1, pred2) {
392 (GenericPredicate::Implemented(tr1), GenericPredicate::Implemented(tr2)) 384 (WhereClause::Implemented(tr1), WhereClause::Implemented(tr2))
393 if tr1.trait_id == tr2.trait_id => 385 if tr1.trait_id == tr2.trait_id =>
394 { 386 {
395 self.unify_substs(&tr1.substitution, &tr2.substitution, depth + 1) 387 self.unify_substs(&tr1.substitution, &tr2.substitution, depth + 1)
396 } 388 }
397 ( 389 (
398 GenericPredicate::AliasEq(AliasEq { alias: alias1, ty: ty1 }), 390 WhereClause::AliasEq(AliasEq { alias: alias1, ty: ty1 }),
399 GenericPredicate::AliasEq(AliasEq { alias: alias2, ty: ty2 }), 391 WhereClause::AliasEq(AliasEq { alias: alias2, ty: ty2 }),
400 ) => { 392 ) => {
401 let (substitution1, substitution2) = match (alias1, alias2) { 393 let (substitution1, substitution2) = match (alias1, alias2) {
402 (AliasTy::Projection(projection_ty1), AliasTy::Projection(projection_ty2)) 394 (AliasTy::Projection(projection_ty1), AliasTy::Projection(projection_ty2))
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 2afcb5413..c46529879 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -13,6 +13,7 @@ mod op;
13mod lower; 13mod lower;
14pub(crate) mod infer; 14pub(crate) mod infer;
15pub(crate) mod utils; 15pub(crate) mod utils;
16mod chalk_cast;
16 17
17pub mod display; 18pub mod display;
18pub mod db; 19pub mod db;
@@ -45,9 +46,11 @@ pub use lower::{
45 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, 46 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
46 TyDefId, TyLoweringContext, ValueTyDefId, 47 TyDefId, TyLoweringContext, ValueTyDefId,
47}; 48};
48pub use traits::{AliasEq, InEnvironment, Obligation, TraitEnvironment}; 49pub use traits::{AliasEq, DomainGoal, InEnvironment, TraitEnvironment};
49 50
50pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind}; 51pub use chalk_ir::{
52 cast::Cast, AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind,
53};
51 54
52pub use crate::traits::chalk::Interner; 55pub use crate::traits::chalk::Interner;
53 56
@@ -276,7 +279,7 @@ pub enum TyKind {
276 /// represents the `Self` type inside the bounds. This is currently 279 /// represents the `Self` type inside the bounds. This is currently
277 /// implicit; Chalk has the `Binders` struct to make it explicit, but it 280 /// implicit; Chalk has the `Binders` struct to make it explicit, but it
278 /// didn't seem worth the overhead yet. 281 /// didn't seem worth the overhead yet.
279 Dyn(Arc<[GenericPredicate]>), 282 Dyn(Arc<[WhereClause]>),
280 283
281 /// A placeholder for a type which could not be computed; this is propagated 284 /// A placeholder for a type which could not be computed; this is propagated
282 /// to avoid useless error messages. Doubles as a placeholder where type 285 /// to avoid useless error messages. Doubles as a placeholder where type
@@ -564,42 +567,34 @@ impl TypeWalk for TraitRef {
564/// Like `generics::WherePredicate`, but with resolved types: A condition on the 567/// Like `generics::WherePredicate`, but with resolved types: A condition on the
565/// parameters of a generic item. 568/// parameters of a generic item.
566#[derive(Debug, Clone, PartialEq, Eq, Hash)] 569#[derive(Debug, Clone, PartialEq, Eq, Hash)]
567pub enum GenericPredicate { 570pub enum WhereClause {
568 /// The given trait needs to be implemented for its type parameters. 571 /// The given trait needs to be implemented for its type parameters.
569 Implemented(TraitRef), 572 Implemented(TraitRef),
570 /// An associated type bindings like in `Iterator<Item = T>`. 573 /// An associated type bindings like in `Iterator<Item = T>`.
571 AliasEq(AliasEq), 574 AliasEq(AliasEq),
572 /// We couldn't resolve the trait reference. (If some type parameters can't
573 /// be resolved, they will just be Unknown).
574 Error,
575} 575}
576 576
577impl GenericPredicate { 577impl WhereClause {
578 pub fn is_error(&self) -> bool {
579 matches!(self, GenericPredicate::Error)
580 }
581
582 pub fn is_implemented(&self) -> bool { 578 pub fn is_implemented(&self) -> bool {
583 matches!(self, GenericPredicate::Implemented(_)) 579 matches!(self, WhereClause::Implemented(_))
584 } 580 }
585 581
586 pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> { 582 pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> {
587 match self { 583 match self {
588 GenericPredicate::Implemented(tr) => Some(tr.clone()), 584 WhereClause::Implemented(tr) => Some(tr.clone()),
589 GenericPredicate::AliasEq(AliasEq { alias: AliasTy::Projection(proj), .. }) => { 585 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(proj), .. }) => {
590 Some(proj.trait_ref(db)) 586 Some(proj.trait_ref(db))
591 } 587 }
592 GenericPredicate::AliasEq(_) | GenericPredicate::Error => None, 588 WhereClause::AliasEq(_) => None,
593 } 589 }
594 } 590 }
595} 591}
596 592
597impl TypeWalk for GenericPredicate { 593impl TypeWalk for WhereClause {
598 fn walk(&self, f: &mut impl FnMut(&Ty)) { 594 fn walk(&self, f: &mut impl FnMut(&Ty)) {
599 match self { 595 match self {
600 GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f), 596 WhereClause::Implemented(trait_ref) => trait_ref.walk(f),
601 GenericPredicate::AliasEq(alias_eq) => alias_eq.walk(f), 597 WhereClause::AliasEq(alias_eq) => alias_eq.walk(f),
602 GenericPredicate::Error => {}
603 } 598 }
604 } 599 }
605 600
@@ -609,9 +604,8 @@ impl TypeWalk for GenericPredicate {
609 binders: DebruijnIndex, 604 binders: DebruijnIndex,
610 ) { 605 ) {
611 match self { 606 match self {
612 GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders), 607 WhereClause::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders),
613 GenericPredicate::AliasEq(alias_eq) => alias_eq.walk_mut_binders(f, binders), 608 WhereClause::AliasEq(alias_eq) => alias_eq.walk_mut_binders(f, binders),
614 GenericPredicate::Error => {}
615 } 609 }
616 } 610 }
617} 611}
@@ -815,7 +809,7 @@ impl Ty {
815 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { 809 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> {
816 match self.interned(&Interner) { 810 match self.interned(&Interner) {
817 TyKind::Dyn(bounds) => bounds.get(0).and_then(|b| match b { 811 TyKind::Dyn(bounds) => bounds.get(0).and_then(|b| match b {
818 GenericPredicate::Implemented(trait_ref) => Some(trait_ref), 812 WhereClause::Implemented(trait_ref) => Some(trait_ref),
819 _ => None, 813 _ => None,
820 }), 814 }),
821 _ => None, 815 _ => None,
@@ -894,7 +888,7 @@ impl Ty {
894 } 888 }
895 } 889 }
896 890
897 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { 891 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<WhereClause>> {
898 match self.interned(&Interner) { 892 match self.interned(&Interner) {
899 TyKind::OpaqueType(opaque_ty_id, ..) => { 893 TyKind::OpaqueType(opaque_ty_id, ..) => {
900 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { 894 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
@@ -907,7 +901,7 @@ impl Ty {
907 // This is only used by type walking. 901 // This is only used by type walking.
908 // Parameters will be walked outside, and projection predicate is not used. 902 // Parameters will be walked outside, and projection predicate is not used.
909 // So just provide the Future trait. 903 // So just provide the Future trait.
910 let impl_bound = GenericPredicate::Implemented(TraitRef { 904 let impl_bound = WhereClause::Implemented(TraitRef {
911 trait_id: to_chalk_trait_id(future_trait), 905 trait_id: to_chalk_trait_id(future_trait),
912 substitution: Substitution::empty(), 906 substitution: Substitution::empty(),
913 }); 907 });
@@ -1166,7 +1160,7 @@ pub struct ReturnTypeImplTraits {
1166 1160
1167#[derive(Clone, PartialEq, Eq, Debug, Hash)] 1161#[derive(Clone, PartialEq, Eq, Debug, Hash)]
1168pub(crate) struct ReturnTypeImplTrait { 1162pub(crate) struct ReturnTypeImplTrait {
1169 pub(crate) bounds: Binders<Vec<GenericPredicate>>, 1163 pub(crate) bounds: Binders<Vec<WhereClause>>,
1170} 1164}
1171 1165
1172pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { 1166pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId {
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 7d22c3df5..cbbb535e5 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -33,9 +33,9 @@ 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 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, 36 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, ImplTraitId,
37 GenericPredicate, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionTy, ReturnTypeImplTrait, 37 OpaqueTy, PolyFnSig, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution,
38 ReturnTypeImplTraits, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, 38 TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, WhereClause,
39}; 39};
40 40
41#[derive(Debug)] 41#[derive(Debug)]
@@ -373,8 +373,7 @@ impl<'a> TyLoweringContext<'a> {
373 // FIXME report error (ambiguous associated type) 373 // FIXME report error (ambiguous associated type)
374 TyKind::Unknown.intern(&Interner) 374 TyKind::Unknown.intern(&Interner)
375 } else { 375 } else {
376 TyKind::Dyn(Arc::new([GenericPredicate::Implemented(trait_ref)])) 376 TyKind::Dyn(Arc::new([WhereClause::Implemented(trait_ref)])).intern(&Interner)
377 .intern(&Interner)
378 }; 377 };
379 return (ty, None); 378 return (ty, None);
380 } 379 }
@@ -667,7 +666,7 @@ impl<'a> TyLoweringContext<'a> {
667 pub(crate) fn lower_where_predicate( 666 pub(crate) fn lower_where_predicate(
668 &'a self, 667 &'a self,
669 where_predicate: &'a WherePredicate, 668 where_predicate: &'a WherePredicate,
670 ) -> impl Iterator<Item = GenericPredicate> + 'a { 669 ) -> impl Iterator<Item = WhereClause> + 'a {
671 match where_predicate { 670 match where_predicate {
672 WherePredicate::ForLifetime { target, bound, .. } 671 WherePredicate::ForLifetime { target, bound, .. }
673 | WherePredicate::TypeBound { target, bound } => { 672 | WherePredicate::TypeBound { target, bound } => {
@@ -699,17 +698,15 @@ impl<'a> TyLoweringContext<'a> {
699 &'a self, 698 &'a self,
700 bound: &'a TypeBound, 699 bound: &'a TypeBound,
701 self_ty: Ty, 700 self_ty: Ty,
702 ) -> impl Iterator<Item = GenericPredicate> + 'a { 701 ) -> impl Iterator<Item = WhereClause> + 'a {
703 let mut bindings = None; 702 let mut bindings = None;
704 let trait_ref = match bound { 703 let trait_ref = match bound {
705 TypeBound::Path(path) => { 704 TypeBound::Path(path) => {
706 bindings = self.lower_trait_ref_from_path(path, Some(self_ty)); 705 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
707 Some( 706 bindings.clone().map(WhereClause::Implemented)
708 bindings.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented),
709 )
710 } 707 }
711 TypeBound::Lifetime(_) => None, 708 TypeBound::Lifetime(_) => None,
712 TypeBound::Error => Some(GenericPredicate::Error), 709 TypeBound::Error => None,
713 }; 710 };
714 trait_ref.into_iter().chain( 711 trait_ref.into_iter().chain(
715 bindings 712 bindings
@@ -722,7 +719,7 @@ impl<'a> TyLoweringContext<'a> {
722 &'a self, 719 &'a self,
723 bound: &'a TypeBound, 720 bound: &'a TypeBound,
724 trait_ref: TraitRef, 721 trait_ref: TraitRef,
725 ) -> impl Iterator<Item = GenericPredicate> + 'a { 722 ) -> impl Iterator<Item = WhereClause> + 'a {
726 let last_segment = match bound { 723 let last_segment = match bound {
727 TypeBound::Path(path) => path.segments().last(), 724 TypeBound::Path(path) => path.segments().last(),
728 TypeBound::Error | TypeBound::Lifetime(_) => None, 725 TypeBound::Error | TypeBound::Lifetime(_) => None,
@@ -738,7 +735,7 @@ impl<'a> TyLoweringContext<'a> {
738 &binding.name, 735 &binding.name,
739 ); 736 );
740 let (super_trait_ref, associated_ty) = match found { 737 let (super_trait_ref, associated_ty) = match found {
741 None => return SmallVec::<[GenericPredicate; 1]>::new(), 738 None => return SmallVec::<[WhereClause; 1]>::new(),
742 Some(t) => t, 739 Some(t) => t,
743 }; 740 };
744 let projection_ty = ProjectionTy { 741 let projection_ty = ProjectionTy {
@@ -752,7 +749,7 @@ impl<'a> TyLoweringContext<'a> {
752 let ty = self.lower_ty(type_ref); 749 let ty = self.lower_ty(type_ref);
753 let alias_eq = 750 let alias_eq =
754 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty }; 751 AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
755 preds.push(GenericPredicate::AliasEq(alias_eq)); 752 preds.push(WhereClause::AliasEq(alias_eq));
756 } 753 }
757 for bound in &binding.bounds { 754 for bound in &binding.bounds {
758 preds.extend(self.lower_type_bound( 755 preds.extend(self.lower_type_bound(
@@ -809,7 +806,7 @@ pub fn associated_type_shorthand_candidates<R>(
809 let mut traits_: Vec<_> = predicates 806 let mut traits_: Vec<_> = predicates
810 .iter() 807 .iter()
811 .filter_map(|pred| match &pred.value { 808 .filter_map(|pred| match &pred.value {
812 GenericPredicate::Implemented(tr) => Some(tr.clone()), 809 WhereClause::Implemented(tr) => Some(tr.clone()),
813 _ => None, 810 _ => None,
814 }) 811 })
815 .collect(); 812 .collect();
@@ -881,7 +878,7 @@ pub(crate) fn field_types_query(
881pub(crate) fn generic_predicates_for_param_query( 878pub(crate) fn generic_predicates_for_param_query(
882 db: &dyn HirDatabase, 879 db: &dyn HirDatabase,
883 param_id: TypeParamId, 880 param_id: TypeParamId,
884) -> Arc<[Binders<GenericPredicate>]> { 881) -> Arc<[Binders<WhereClause>]> {
885 let resolver = param_id.parent.resolver(db.upcast()); 882 let resolver = param_id.parent.resolver(db.upcast());
886 let ctx = 883 let ctx =
887 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 884 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
@@ -907,7 +904,7 @@ pub(crate) fn generic_predicates_for_param_recover(
907 _db: &dyn HirDatabase, 904 _db: &dyn HirDatabase,
908 _cycle: &[String], 905 _cycle: &[String],
909 _param_id: &TypeParamId, 906 _param_id: &TypeParamId,
910) -> Arc<[Binders<GenericPredicate>]> { 907) -> Arc<[Binders<WhereClause>]> {
911 Arc::new([]) 908 Arc::new([])
912} 909}
913 910
@@ -922,10 +919,7 @@ pub(crate) fn trait_environment_query(
922 let mut clauses = Vec::new(); 919 let mut clauses = Vec::new();
923 for pred in resolver.where_predicates_in_scope() { 920 for pred in resolver.where_predicates_in_scope() {
924 for pred in ctx.lower_where_predicate(pred) { 921 for pred in ctx.lower_where_predicate(pred) {
925 if pred.is_error() { 922 if let WhereClause::Implemented(tr) = &pred {
926 continue;
927 }
928 if let GenericPredicate::Implemented(tr) = &pred {
929 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id())); 923 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id()));
930 } 924 }
931 let program_clause: chalk_ir::ProgramClause<Interner> = 925 let program_clause: chalk_ir::ProgramClause<Interner> =
@@ -951,7 +945,7 @@ pub(crate) fn trait_environment_query(
951 cov_mark::hit!(trait_self_implements_self); 945 cov_mark::hit!(trait_self_implements_self);
952 let substs = Substitution::type_params(db, trait_id); 946 let substs = Substitution::type_params(db, trait_id);
953 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs }; 947 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution: substs };
954 let pred = GenericPredicate::Implemented(trait_ref); 948 let pred = WhereClause::Implemented(trait_ref);
955 let program_clause: chalk_ir::ProgramClause<Interner> = 949 let program_clause: chalk_ir::ProgramClause<Interner> =
956 pred.clone().to_chalk(db).cast(&Interner); 950 pred.clone().to_chalk(db).cast(&Interner);
957 clauses.push(program_clause.into_from_env_clause(&Interner)); 951 clauses.push(program_clause.into_from_env_clause(&Interner));
@@ -966,7 +960,7 @@ pub(crate) fn trait_environment_query(
966pub(crate) fn generic_predicates_query( 960pub(crate) fn generic_predicates_query(
967 db: &dyn HirDatabase, 961 db: &dyn HirDatabase,
968 def: GenericDefId, 962 def: GenericDefId,
969) -> Arc<[Binders<GenericPredicate>]> { 963) -> Arc<[Binders<WhereClause>]> {
970 let resolver = def.resolver(db.upcast()); 964 let resolver = def.resolver(db.upcast());
971 let ctx = 965 let ctx =
972 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 966 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 01b78fb44..da6bc2a4a 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -6,7 +6,7 @@ use std::{iter, sync::Arc};
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use base_db::CrateId; 8use base_db::CrateId;
9use chalk_ir::Mutability; 9use chalk_ir::{cast::Cast, Mutability};
10use hir_def::{ 10use hir_def::{
11 lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, 11 lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule,
12 ImplId, Lookup, ModuleId, TraitId, 12 ImplId, Lookup, ModuleId, TraitId,
@@ -767,7 +767,7 @@ fn generic_implements_goal(
767 env: Arc<TraitEnvironment>, 767 env: Arc<TraitEnvironment>,
768 trait_: TraitId, 768 trait_: TraitId,
769 self_ty: Canonical<Ty>, 769 self_ty: Canonical<Ty>,
770) -> Canonical<InEnvironment<super::Obligation>> { 770) -> Canonical<InEnvironment<super::DomainGoal>> {
771 let mut kinds = self_ty.kinds.to_vec(); 771 let mut kinds = self_ty.kinds.to_vec();
772 let substs = super::Substitution::build_for_def(db, trait_) 772 let substs = super::Substitution::build_for_def(db, trait_)
773 .push(self_ty.value) 773 .push(self_ty.value)
@@ -775,7 +775,7 @@ fn generic_implements_goal(
775 .build(); 775 .build();
776 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));
777 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }; 777 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
778 let obligation = super::Obligation::Trait(trait_ref); 778 let obligation = trait_ref.cast(&Interner);
779 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } 779 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) }
780} 780}
781 781
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 8270fa219..8f2bdffc0 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -1412,8 +1412,8 @@ fn weird_bounds() {
1412 50..51 'b': impl 1412 50..51 'b': impl
1413 69..70 'c': impl Trait 1413 69..70 'c': impl Trait
1414 86..87 'd': impl 1414 86..87 'd': impl
1415 107..108 'e': impl {error} 1415 107..108 'e': impl
1416 123..124 'f': impl Trait + {error} 1416 123..124 'f': impl Trait
1417 147..149 '{}': () 1417 147..149 '{}': ()
1418 "#]], 1418 "#]],
1419 ); 1419 );
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index ac7de7605..7dadd1ffb 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -9,8 +9,8 @@ use hir_def::{lang_item::LangItemTarget, TraitId};
9use stdx::panic_context; 9use stdx::panic_context;
10 10
11use crate::{ 11use crate::{
12 db::HirDatabase, AliasTy, Canonical, DebruijnIndex, GenericPredicate, HirDisplay, Substitution, 12 db::HirDatabase, AliasTy, Canonical, DebruijnIndex, HirDisplay, Substitution, Ty, TyKind,
13 TraitRef, Ty, TyKind, TypeWalk, 13 TypeWalk, WhereClause,
14}; 14};
15 15
16use self::chalk::{from_chalk, Interner, ToChalk}; 16use self::chalk::{from_chalk, Interner, ToChalk};
@@ -88,21 +88,8 @@ impl<T> InEnvironment<T> {
88/// a certain type implements a certain trait. Proving the Obligation might 88/// a certain type implements a certain trait. Proving the Obligation might
89/// result in additional information about inference variables. 89/// result in additional information about inference variables.
90#[derive(Clone, Debug, PartialEq, Eq, Hash)] 90#[derive(Clone, Debug, PartialEq, Eq, Hash)]
91pub enum Obligation { 91pub enum DomainGoal {
92 /// Prove that a certain type implements a trait (the type is the `Self` type 92 Holds(WhereClause),
93 /// parameter to the `TraitRef`).
94 Trait(TraitRef),
95 AliasEq(AliasEq),
96}
97
98impl Obligation {
99 pub fn from_predicate(predicate: GenericPredicate) -> Option<Obligation> {
100 match predicate {
101 GenericPredicate::Implemented(trait_ref) => Some(Obligation::Trait(trait_ref)),
102 GenericPredicate::AliasEq(alias_eq) => Some(Obligation::AliasEq(alias_eq)),
103 GenericPredicate::Error => None,
104 }
105 }
106} 93}
107 94
108#[derive(Clone, Debug, PartialEq, Eq, Hash)] 95#[derive(Clone, Debug, PartialEq, Eq, Hash)]
@@ -137,16 +124,20 @@ impl TypeWalk for AliasEq {
137pub(crate) fn trait_solve_query( 124pub(crate) fn trait_solve_query(
138 db: &dyn HirDatabase, 125 db: &dyn HirDatabase,
139 krate: CrateId, 126 krate: CrateId,
140 goal: Canonical<InEnvironment<Obligation>>, 127 goal: Canonical<InEnvironment<DomainGoal>>,
141) -> Option<Solution> { 128) -> Option<Solution> {
142 let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value { 129 let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value {
143 Obligation::Trait(it) => db.trait_data(it.hir_trait_id()).name.to_string(), 130 DomainGoal::Holds(WhereClause::Implemented(it)) => {
144 Obligation::AliasEq(_) => "alias_eq".to_string(), 131 db.trait_data(it.hir_trait_id()).name.to_string()
132 }
133 DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(),
145 }); 134 });
146 log::info!("trait_solve_query({})", goal.value.value.display(db)); 135 log::info!("trait_solve_query({})", goal.value.value.display(db));
147 136
148 if let Obligation::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), .. }) = 137 if let DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
149 &goal.value.value 138 alias: AliasTy::Projection(projection_ty),
139 ..
140 })) = &goal.value.value
150 { 141 {
151 if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) { 142 if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) {
152 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible 143 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 080764e76..734679414 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 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, 24 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, ProjectionTy,
25 GenericPredicate, ProjectionTy, Substitution, TraitRef, Ty, TyKind, 25 Substitution, TraitRef, Ty, TyKind, WhereClause,
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,
@@ -187,13 +187,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
187 let data = &datas.value.impl_traits[idx as usize]; 187 let data = &datas.value.impl_traits[idx as usize];
188 let bound = OpaqueTyDatumBound { 188 let bound = OpaqueTyDatumBound {
189 bounds: make_binders( 189 bounds: make_binders(
190 data.bounds 190 data.bounds.value.iter().cloned().map(|b| b.to_chalk(self.db)).collect(),
191 .value
192 .iter()
193 .cloned()
194 .filter(|b| !b.is_error())
195 .map(|b| b.to_chalk(self.db))
196 .collect(),
197 1, 191 1,
198 ), 192 ),
199 where_clauses: make_binders(vec![], 0), 193 where_clauses: make_binders(vec![], 0),
@@ -218,7 +212,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
218 // |-------------OpaqueTyDatumBound--------------| 212 // |-------------OpaqueTyDatumBound--------------|
219 // for<T> <Self> [Future<Self>, Future::Output<Self> = T] 213 // for<T> <Self> [Future<Self>, Future::Output<Self> = T]
220 // ^1 ^0 ^0 ^0 ^1 214 // ^1 ^0 ^0 ^0 ^1
221 let impl_bound = GenericPredicate::Implemented(TraitRef { 215 let impl_bound = WhereClause::Implemented(TraitRef {
222 trait_id: to_chalk_trait_id(future_trait), 216 trait_id: to_chalk_trait_id(future_trait),
223 // Self type as the first parameter. 217 // Self type as the first parameter.
224 substitution: Substitution::single( 218 substitution: Substitution::single(
@@ -229,7 +223,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
229 .intern(&Interner), 223 .intern(&Interner),
230 ), 224 ),
231 }); 225 });
232 let proj_bound = GenericPredicate::AliasEq(AliasEq { 226 let proj_bound = WhereClause::AliasEq(AliasEq {
233 alias: AliasTy::Projection(ProjectionTy { 227 alias: AliasTy::Projection(ProjectionTy {
234 associated_ty_id: to_assoc_type_id(future_output), 228 associated_ty_id: to_assoc_type_id(future_output),
235 // Self type as the first parameter. 229 // Self type as the first parameter.
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index 62b779008..65feb82e5 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -13,9 +13,9 @@ use crate::{
13 db::HirDatabase, 13 db::HirDatabase,
14 from_assoc_type_id, 14 from_assoc_type_id,
15 primitive::UintTy, 15 primitive::UintTy,
16 traits::{Canonical, Obligation}, 16 traits::{Canonical, DomainGoal},
17 AliasTy, CallableDefId, FnPointer, GenericPredicate, InEnvironment, OpaqueTy, ProjectionTy, 17 AliasTy, CallableDefId, FnPointer, InEnvironment, OpaqueTy, ProjectionTy, Scalar, Substitution,
18 Scalar, Substitution, TraitRef, Ty, 18 TraitRef, Ty, WhereClause,
19}; 19};
20 20
21use super::interner::*; 21use super::interner::*;
@@ -98,7 +98,7 @@ impl ToChalk for Ty {
98 TyKind::Dyn(predicates) => { 98 TyKind::Dyn(predicates) => {
99 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( 99 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
100 &Interner, 100 &Interner,
101 predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)), 101 predicates.iter().cloned().map(|p| p.to_chalk(db)),
102 ); 102 );
103 let bounded_ty = chalk_ir::DynTy { 103 let bounded_ty = chalk_ir::DynTy {
104 bounds: make_binders(where_clauses, 1), 104 bounds: make_binders(where_clauses, 1),
@@ -304,28 +304,27 @@ impl ToChalk for TypeAliasAsValue {
304 } 304 }
305} 305}
306 306
307impl ToChalk for GenericPredicate { 307impl ToChalk for WhereClause {
308 type Chalk = chalk_ir::QuantifiedWhereClause<Interner>; 308 type Chalk = chalk_ir::QuantifiedWhereClause<Interner>;
309 309
310 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::QuantifiedWhereClause<Interner> { 310 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::QuantifiedWhereClause<Interner> {
311 match self { 311 match self {
312 GenericPredicate::Implemented(trait_ref) => { 312 WhereClause::Implemented(trait_ref) => {
313 let chalk_trait_ref = trait_ref.to_chalk(db); 313 let chalk_trait_ref = trait_ref.to_chalk(db);
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::AliasEq(alias_eq) => make_binders( 317 WhereClause::AliasEq(alias_eq) => make_binders(
318 chalk_ir::WhereClause::AliasEq(alias_eq.to_chalk(db).shifted_in(&Interner)), 318 chalk_ir::WhereClause::AliasEq(alias_eq.to_chalk(db).shifted_in(&Interner)),
319 0, 319 0,
320 ), 320 ),
321 GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"),
322 } 321 }
323 } 322 }
324 323
325 fn from_chalk( 324 fn from_chalk(
326 db: &dyn HirDatabase, 325 db: &dyn HirDatabase,
327 where_clause: chalk_ir::QuantifiedWhereClause<Interner>, 326 where_clause: chalk_ir::QuantifiedWhereClause<Interner>,
328 ) -> GenericPredicate { 327 ) -> WhereClause {
329 // we don't produce any where clauses with binders and can't currently deal with them 328 // we don't produce any where clauses with binders and can't currently deal with them
330 match where_clause 329 match where_clause
331 .skip_binders() 330 .skip_binders()
@@ -333,11 +332,9 @@ impl ToChalk for GenericPredicate {
333 .shifted_out(&Interner) 332 .shifted_out(&Interner)
334 .expect("unexpected bound vars in where clause") 333 .expect("unexpected bound vars in where clause")
335 { 334 {
336 chalk_ir::WhereClause::Implemented(tr) => { 335 chalk_ir::WhereClause::Implemented(tr) => WhereClause::Implemented(from_chalk(db, tr)),
337 GenericPredicate::Implemented(from_chalk(db, tr))
338 }
339 chalk_ir::WhereClause::AliasEq(alias_eq) => { 336 chalk_ir::WhereClause::AliasEq(alias_eq) => {
340 GenericPredicate::AliasEq(from_chalk(db, alias_eq)) 337 WhereClause::AliasEq(from_chalk(db, alias_eq))
341 } 338 }
342 339
343 chalk_ir::WhereClause::LifetimeOutlives(_) => { 340 chalk_ir::WhereClause::LifetimeOutlives(_) => {
@@ -425,13 +422,15 @@ impl ToChalk for AliasEq {
425 } 422 }
426} 423}
427 424
428impl ToChalk for Obligation { 425impl ToChalk for DomainGoal {
429 type Chalk = chalk_ir::DomainGoal<Interner>; 426 type Chalk = chalk_ir::DomainGoal<Interner>;
430 427
431 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> { 428 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> {
432 match self { 429 match self {
433 Obligation::Trait(tr) => tr.to_chalk(db).cast(&Interner), 430 DomainGoal::Holds(WhereClause::Implemented(tr)) => tr.to_chalk(db).cast(&Interner),
434 Obligation::AliasEq(alias_eq) => alias_eq.to_chalk(db).cast(&Interner), 431 DomainGoal::Holds(WhereClause::AliasEq(alias_eq)) => {
432 alias_eq.to_chalk(db).cast(&Interner)
433 }
435 } 434 }
436 } 435 }
437 436
@@ -523,10 +522,6 @@ pub(super) fn convert_where_clauses(
523 let generic_predicates = db.generic_predicates(def); 522 let generic_predicates = db.generic_predicates(def);
524 let mut result = Vec::with_capacity(generic_predicates.len()); 523 let mut result = Vec::with_capacity(generic_predicates.len());
525 for pred in generic_predicates.iter() { 524 for pred in generic_predicates.iter() {
526 if pred.value.is_error() {
527 // skip errored predicates completely
528 continue;
529 }
530 result.push(pred.clone().subst(substs).to_chalk(db)); 525 result.push(pred.clone().subst(substs).to_chalk(db));
531 } 526 }
532 result 527 result
@@ -534,13 +529,13 @@ pub(super) fn convert_where_clauses(
534 529
535pub(super) fn generic_predicate_to_inline_bound( 530pub(super) fn generic_predicate_to_inline_bound(
536 db: &dyn HirDatabase, 531 db: &dyn HirDatabase,
537 pred: &GenericPredicate, 532 pred: &WhereClause,
538 self_ty: &Ty, 533 self_ty: &Ty,
539) -> Option<rust_ir::InlineBound<Interner>> { 534) -> Option<rust_ir::InlineBound<Interner>> {
540 // An InlineBound is like a GenericPredicate, except the self type is left out. 535 // An InlineBound is like a GenericPredicate, except the self type is left out.
541 // We don't have a special type for this, but Chalk does. 536 // We don't have a special type for this, but Chalk does.
542 match pred { 537 match pred {
543 GenericPredicate::Implemented(trait_ref) => { 538 WhereClause::Implemented(trait_ref) => {
544 if &trait_ref.substitution[0] != self_ty { 539 if &trait_ref.substitution[0] != self_ty {
545 // we can only convert predicates back to type bounds if they 540 // we can only convert predicates back to type bounds if they
546 // have the expected self type 541 // have the expected self type
@@ -553,7 +548,7 @@ pub(super) fn generic_predicate_to_inline_bound(
553 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; 548 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
554 Some(rust_ir::InlineBound::TraitBound(trait_bound)) 549 Some(rust_ir::InlineBound::TraitBound(trait_bound))
555 } 550 }
556 GenericPredicate::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { 551 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
557 if &projection_ty.substitution[0] != self_ty { 552 if &projection_ty.substitution[0] != self_ty {
558 return None; 553 return None;
559 } 554 }
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index b66243d48..1ec1ecd43 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -15,7 +15,7 @@ use hir_def::{
15}; 15};
16use hir_expand::name::{name, Name}; 16use hir_expand::name::{name, Name};
17 17
18use crate::{db::HirDatabase, GenericPredicate, TraitRef}; 18use crate::{db::HirDatabase, TraitRef, WhereClause};
19 19
20fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> { 20fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
21 let resolver = trait_.resolver(db); 21 let resolver = trait_.resolver(db);
@@ -64,7 +64,7 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
64 .iter() 64 .iter()
65 .filter_map(|pred| { 65 .filter_map(|pred| {
66 pred.as_ref().filter_map(|pred| match pred { 66 pred.as_ref().filter_map(|pred| match pred {
67 GenericPredicate::Implemented(tr) => Some(tr.clone()), 67 WhereClause::Implemented(tr) => Some(tr.clone()),
68 _ => None, 68 _ => None,
69 }) 69 })
70 }) 70 })