diff options
author | Florian Diebold <[email protected]> | 2021-03-20 10:23:59 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-03-20 11:47:12 +0000 |
commit | 7ec3b66f7a3ac0a33cf435bc3596fdac542fc52a (patch) | |
tree | 70a77a26ca09d8d5cd843b1cd9d59af229cd0daf /crates/hir_ty | |
parent | 8e7e405f6ab0c1ee10bfdd3d55a97628fe4cd6dd (diff) |
Turn Obligation into something similar to chalk_ir::DomainGoal
This includes starting to make use of Chalk's `Cast` trait.
Diffstat (limited to 'crates/hir_ty')
-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 | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 20 | ||||
-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 | 13 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 7 | ||||
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/traits.rs | 34 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 10 |
13 files changed, 124 insertions, 86 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 300da0f38..91a2e0b5b 100644 --- a/crates/hir_ty/src/db.rs +++ b/crates/hir_ty/src/db.rs | |||
@@ -119,7 +119,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> { | |||
119 | fn trait_solve( | 119 | fn trait_solve( |
120 | &self, | 120 | &self, |
121 | krate: CrateId, | 121 | krate: CrateId, |
122 | goal: crate::Canonical<crate::InEnvironment<crate::Obligation>>, | 122 | goal: crate::Canonical<crate::InEnvironment<crate::DomainGoal>>, |
123 | ) -> Option<crate::traits::Solution>; | 123 | ) -> Option<crate::traits::Solution>; |
124 | 124 | ||
125 | #[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 4765c99a4..3845009ae 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -19,7 +19,7 @@ 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, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy, | 22 | CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy, |
23 | ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause, | 23 | ProjectionTy, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause, |
24 | }; | 24 | }; |
25 | 25 | ||
@@ -805,22 +805,12 @@ impl HirDisplay for Lifetime { | |||
805 | } | 805 | } |
806 | } | 806 | } |
807 | 807 | ||
808 | impl HirDisplay for Obligation { | 808 | impl HirDisplay for DomainGoal { |
809 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 809 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
810 | match self { | 810 | match self { |
811 | Obligation::Trait(tr) => { | 811 | DomainGoal::Holds(wc) => { |
812 | write!(f, "Implements(")?; | 812 | write!(f, "Holds(")?; |
813 | tr.hir_fmt(f)?; | 813 | wc.hir_fmt(f)?; |
814 | write!(f, ")") | ||
815 | } | ||
816 | Obligation::AliasEq(AliasEq { alias, ty }) => { | ||
817 | write!(f, "Normalize(")?; | ||
818 | match alias { | ||
819 | AliasTy::Projection(projection_ty) => projection_ty.hir_fmt(f)?, | ||
820 | AliasTy::Opaque(opaque) => opaque.hir_fmt(f)?, | ||
821 | } | ||
822 | write!(f, " => ")?; | ||
823 | ty.hir_fmt(f)?; | ||
824 | write!(f, ")") | 814 | write!(f, ")") |
825 | } | 815 | } |
826 | } | 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 5b7b423fa..1fc03c8f4 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs | |||
@@ -5,7 +5,7 @@ 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, InEnvironment, InferenceVar, | 10 | AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, InEnvironment, InferenceVar, |
11 | Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause, | 11 | Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause, |
@@ -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 { |
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 8de2d422f..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 | ||
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/traits.rs b/crates/hir_ty/src/traits.rs index 87c92bd12..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, HirDisplay, Substitution, TraitRef, Ty, | 12 | db::HirDatabase, AliasTy, Canonical, DebruijnIndex, HirDisplay, Substitution, Ty, TyKind, |
13 | TyKind, TypeWalk, WhereClause, | 13 | TypeWalk, WhereClause, |
14 | }; | 14 | }; |
15 | 15 | ||
16 | use self::chalk::{from_chalk, Interner, ToChalk}; | 16 | use self::chalk::{from_chalk, Interner, ToChalk}; |
@@ -88,20 +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: WhereClause) -> Option<Obligation> { | ||
100 | match predicate { | ||
101 | WhereClause::Implemented(trait_ref) => Some(Obligation::Trait(trait_ref)), | ||
102 | WhereClause::AliasEq(alias_eq) => Some(Obligation::AliasEq(alias_eq)), | ||
103 | } | ||
104 | } | ||
105 | } | 93 | } |
106 | 94 | ||
107 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | 95 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] |
@@ -136,16 +124,20 @@ impl TypeWalk for AliasEq { | |||
136 | pub(crate) fn trait_solve_query( | 124 | pub(crate) fn trait_solve_query( |
137 | db: &dyn HirDatabase, | 125 | db: &dyn HirDatabase, |
138 | krate: CrateId, | 126 | krate: CrateId, |
139 | goal: Canonical<InEnvironment<Obligation>>, | 127 | goal: Canonical<InEnvironment<DomainGoal>>, |
140 | ) -> Option<Solution> { | 128 | ) -> Option<Solution> { |
141 | 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 { |
142 | Obligation::Trait(it) => db.trait_data(it.hir_trait_id()).name.to_string(), | 130 | DomainGoal::Holds(WhereClause::Implemented(it)) => { |
143 | 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(), | ||
144 | }); | 134 | }); |
145 | log::info!("trait_solve_query({})", goal.value.value.display(db)); | 135 | log::info!("trait_solve_query({})", goal.value.value.display(db)); |
146 | 136 | ||
147 | if let Obligation::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), .. }) = | 137 | if let DomainGoal::Holds(WhereClause::AliasEq(AliasEq { |
148 | &goal.value.value | 138 | alias: AliasTy::Projection(projection_ty), |
139 | .. | ||
140 | })) = &goal.value.value | ||
149 | { | 141 | { |
150 | if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) { | 142 | if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) { |
151 | // 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/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 7841c216c..65feb82e5 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -13,7 +13,7 @@ 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, InEnvironment, OpaqueTy, ProjectionTy, Scalar, Substitution, | 17 | AliasTy, CallableDefId, FnPointer, InEnvironment, OpaqueTy, ProjectionTy, Scalar, Substitution, |
18 | TraitRef, Ty, WhereClause, | 18 | TraitRef, Ty, WhereClause, |
19 | }; | 19 | }; |
@@ -422,13 +422,15 @@ impl ToChalk for AliasEq { | |||
422 | } | 422 | } |
423 | } | 423 | } |
424 | 424 | ||
425 | impl ToChalk for Obligation { | 425 | impl ToChalk for DomainGoal { |
426 | type Chalk = chalk_ir::DomainGoal<Interner>; | 426 | type Chalk = chalk_ir::DomainGoal<Interner>; |
427 | 427 | ||
428 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> { | 428 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> { |
429 | match self { | 429 | match self { |
430 | Obligation::Trait(tr) => tr.to_chalk(db).cast(&Interner), | 430 | DomainGoal::Holds(WhereClause::Implemented(tr)) => tr.to_chalk(db).cast(&Interner), |
431 | 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 | } | ||
432 | } | 434 | } |
433 | } | 435 | } |
434 | 436 | ||