diff options
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r-- | crates/hir_ty/src/autoderef.rs | 9 | ||||
-rw-r--r-- | crates/hir_ty/src/chalk_cast.rs | 53 | ||||
-rw-r--r-- | crates/hir_ty/src/db.rs | 13 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 55 | ||||
-rw-r--r-- | crates/hir_ty/src/infer.rs | 12 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/coerce.rs | 7 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 25 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/path.rs | 12 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/unify.rs | 30 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 48 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 40 | ||||
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/traits.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/traits.rs | 35 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 16 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 41 | ||||
-rw-r--r-- | crates/hir_ty/src/utils.rs | 4 |
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 @@ | |||
6 | use std::iter::successors; | 6 | use std::iter::successors; |
7 | 7 | ||
8 | use base_db::CrateId; | 8 | use base_db::CrateId; |
9 | use chalk_ir::cast::Cast; | ||
9 | use hir_def::lang_item::LangItemTarget; | 10 | use hir_def::lang_item::LangItemTarget; |
10 | use hir_expand::name::name; | 11 | use hir_expand::name::name; |
11 | use log::{info, warn}; | 12 | use 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 | ||
22 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 23 | const 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 | |||
3 | use chalk_ir::{ | ||
4 | cast::{Cast, CastTo}, | ||
5 | interner::HasInterner, | ||
6 | }; | ||
7 | |||
8 | use crate::{AliasEq, DomainGoal, Interner, TraitRef, WhereClause}; | ||
9 | |||
10 | macro_rules! has_interner { | ||
11 | ($t:ty) => { | ||
12 | impl HasInterner for $t { | ||
13 | type Interner = crate::Interner; | ||
14 | } | ||
15 | }; | ||
16 | } | ||
17 | |||
18 | has_interner!(WhereClause); | ||
19 | has_interner!(DomainGoal); | ||
20 | |||
21 | impl CastTo<WhereClause> for TraitRef { | ||
22 | fn cast_to(self, _interner: &Interner) -> WhereClause { | ||
23 | WhereClause::Implemented(self) | ||
24 | } | ||
25 | } | ||
26 | |||
27 | impl CastTo<WhereClause> for AliasEq { | ||
28 | fn cast_to(self, _interner: &Interner) -> WhereClause { | ||
29 | WhereClause::AliasEq(self) | ||
30 | } | ||
31 | } | ||
32 | |||
33 | impl CastTo<DomainGoal> for WhereClause { | ||
34 | fn cast_to(self, _interner: &Interner) -> DomainGoal { | ||
35 | DomainGoal::Holds(self) | ||
36 | } | ||
37 | } | ||
38 | |||
39 | macro_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 | |||
52 | transitive_impl!(TraitRef, WhereClause, DomainGoal); | ||
53 | transitive_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; | |||
12 | use crate::{ | 12 | use 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 | }; |
18 | use hir_expand::name::Name; | 18 | use 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; | |||
19 | use crate::{ | 19 | use crate::{ |
20 | db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, | 20 | db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive, |
21 | to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, 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 | ||
26 | pub struct HirFormatter<'a> { | 26 | pub 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 | ||
653 | pub fn write_bounds_like_dyn_trait_with_prefix( | 653 | pub 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 | ||
667 | fn write_bounds_like_dyn_trait( | 667 | fn 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 | ||
781 | impl HirDisplay for GenericPredicate { | 771 | impl 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 | ||
821 | impl HirDisplay for Obligation { | 808 | impl 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; | |||
18 | use std::ops::Index; | 18 | use std::ops::Index; |
19 | use std::sync::Arc; | 19 | use std::sync::Arc; |
20 | 20 | ||
21 | use chalk_ir::Mutability; | 21 | use chalk_ir::{cast::Cast, Mutability}; |
22 | use hir_def::{ | 22 | use 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; | |||
37 | use syntax::SmolStr; | 37 | use syntax::SmolStr; |
38 | 38 | ||
39 | use super::{ | 39 | use 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 | }; |
43 | use crate::{ | 43 | use 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 | ||
7 | use chalk_ir::{Mutability, TyVariableKind}; | 7 | use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; |
8 | use hir_def::lang_item::LangItemTarget; | 8 | use hir_def::lang_item::LangItemTarget; |
9 | 9 | ||
10 | use crate::{ | 10 | use 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 | ||
15 | use super::{InEnvironment, InferenceContext}; | 14 | use 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 @@ | |||
3 | use std::iter::{repeat, repeat_with}; | 3 | use std::iter::{repeat, repeat_with}; |
4 | use std::{mem, sync::Arc}; | 4 | use std::{mem, sync::Arc}; |
5 | 5 | ||
6 | use chalk_ir::{Mutability, TyVariableKind}; | 6 | use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; |
7 | use hir_def::{ | 7 | use 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 | ||
3 | use std::iter; | 3 | use std::iter; |
4 | 4 | ||
5 | use chalk_ir::cast::Cast; | ||
5 | use hir_def::{ | 6 | use 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; | |||
5 | use chalk_ir::{FloatTy, IntTy, TyVariableKind}; | 5 | use chalk_ir::{FloatTy, IntTy, TyVariableKind}; |
6 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | 6 | use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; |
7 | 7 | ||
8 | use super::{InferenceContext, Obligation}; | 8 | use super::{DomainGoal, InferenceContext}; |
9 | use crate::{ | 9 | use 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 | ||
14 | impl<'a> InferenceContext<'a> { | 14 | impl<'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; | |||
13 | mod lower; | 13 | mod lower; |
14 | pub(crate) mod infer; | 14 | pub(crate) mod infer; |
15 | pub(crate) mod utils; | 15 | pub(crate) mod utils; |
16 | mod chalk_cast; | ||
16 | 17 | ||
17 | pub mod display; | 18 | pub mod display; |
18 | pub mod db; | 19 | pub 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 | }; |
48 | pub use traits::{AliasEq, InEnvironment, Obligation, TraitEnvironment}; | 49 | pub use traits::{AliasEq, DomainGoal, InEnvironment, TraitEnvironment}; |
49 | 50 | ||
50 | pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind}; | 51 | pub use chalk_ir::{ |
52 | cast::Cast, AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind, | ||
53 | }; | ||
51 | 54 | ||
52 | pub use crate::traits::chalk::Interner; | 55 | pub 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)] |
567 | pub enum GenericPredicate { | 570 | pub 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 | ||
577 | impl GenericPredicate { | 577 | impl 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 | ||
597 | impl TypeWalk for GenericPredicate { | 593 | impl 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)] |
1168 | pub(crate) struct ReturnTypeImplTrait { | 1162 | pub(crate) struct ReturnTypeImplTrait { |
1169 | pub(crate) bounds: Binders<Vec<GenericPredicate>>, | 1163 | pub(crate) bounds: Binders<Vec<WhereClause>>, |
1170 | } | 1164 | } |
1171 | 1165 | ||
1172 | pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { | 1166 | pub 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( | |||
881 | pub(crate) fn generic_predicates_for_param_query( | 878 | pub(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( | |||
966 | pub(crate) fn generic_predicates_query( | 960 | pub(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 | ||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use base_db::CrateId; | 8 | use base_db::CrateId; |
9 | use chalk_ir::Mutability; | 9 | use chalk_ir::{cast::Cast, Mutability}; |
10 | use hir_def::{ | 10 | use 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}; | |||
9 | use stdx::panic_context; | 9 | use stdx::panic_context; |
10 | 10 | ||
11 | use crate::{ | 11 | use 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 | ||
16 | use self::chalk::{from_chalk, Interner, ToChalk}; | 16 | use 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)] |
91 | pub enum Obligation { | 91 | pub 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 | |||
98 | impl 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 { | |||
137 | pub(crate) fn trait_solve_query( | 124 | pub(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 | }; |
27 | use mapping::{ | 27 | use mapping::{ |
28 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, | 28 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, |
@@ -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 | ||
21 | use super::interner::*; | 21 | use 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 | ||
307 | impl ToChalk for GenericPredicate { | 307 | impl 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 | ||
428 | impl ToChalk for Obligation { | 425 | impl 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 | ||
535 | pub(super) fn generic_predicate_to_inline_bound( | 530 | pub(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 | }; |
16 | use hir_expand::name::{name, Name}; | 16 | use hir_expand::name::{name, Name}; |
17 | 17 | ||
18 | use crate::{db::HirDatabase, GenericPredicate, TraitRef}; | 18 | use crate::{db::HirDatabase, TraitRef, WhereClause}; |
19 | 19 | ||
20 | fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> { | 20 | fn 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 | }) |