diff options
Diffstat (limited to 'crates/ra_hir/src/ty/traits.rs')
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index fda7f9c04..9a6349d4b 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -8,7 +8,7 @@ use chalk_ir::cast::Cast; | |||
8 | use ra_prof::profile; | 8 | use ra_prof::profile; |
9 | 9 | ||
10 | use crate::{Crate, Trait, db::HirDatabase, ImplBlock}; | 10 | use crate::{Crate, Trait, db::HirDatabase, ImplBlock}; |
11 | use super::{TraitRef, Ty, Canonical}; | 11 | use super::{TraitRef, Ty, Canonical, ProjectionTy}; |
12 | 12 | ||
13 | use self::chalk::{ToChalk, from_chalk}; | 13 | use self::chalk::{ToChalk, from_chalk}; |
14 | 14 | ||
@@ -75,6 +75,13 @@ pub enum Obligation { | |||
75 | /// Prove that a certain type implements a trait (the type is the `Self` type | 75 | /// Prove that a certain type implements a trait (the type is the `Self` type |
76 | /// parameter to the `TraitRef`). | 76 | /// parameter to the `TraitRef`). |
77 | Trait(TraitRef), | 77 | Trait(TraitRef), |
78 | // Projection(ProjectionPredicate), | ||
79 | } | ||
80 | |||
81 | #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
82 | pub struct ProjectionPredicate { | ||
83 | pub projection_ty: ProjectionTy, | ||
84 | pub ty: Ty, | ||
78 | } | 85 | } |
79 | 86 | ||
80 | /// Check using Chalk whether trait is implemented for given parameters including `Self` type. | 87 | /// Check using Chalk whether trait is implemented for given parameters including `Self` type. |
@@ -98,6 +105,30 @@ pub(crate) fn implements_query( | |||
98 | solution.map(|solution| solution_from_chalk(db, solution)) | 105 | solution.map(|solution| solution_from_chalk(db, solution)) |
99 | } | 106 | } |
100 | 107 | ||
108 | pub(crate) fn normalize_query( | ||
109 | db: &impl HirDatabase, | ||
110 | krate: Crate, | ||
111 | projection: Canonical<ProjectionPredicate>, | ||
112 | ) -> Option<Solution> { | ||
113 | let goal: chalk_ir::Goal = chalk_ir::Normalize { | ||
114 | projection: projection.value.projection_ty.to_chalk(db), | ||
115 | ty: projection.value.ty.to_chalk(db), | ||
116 | } | ||
117 | .cast(); | ||
118 | debug!("goal: {:?}", goal); | ||
119 | // FIXME unify with `implements` | ||
120 | let env = chalk_ir::Environment::new(); | ||
121 | let in_env = chalk_ir::InEnvironment::new(&env, goal); | ||
122 | let parameter = chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::ROOT); | ||
123 | let canonical = | ||
124 | chalk_ir::Canonical { value: in_env, binders: vec![parameter; projection.num_vars] }; | ||
125 | // We currently don't deal with universes (I think / hope they're not yet | ||
126 | // relevant for our use cases?) | ||
127 | let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 }; | ||
128 | let solution = solve(db, krate, &u_canonical); | ||
129 | solution.map(|solution| solution_from_chalk(db, solution)) | ||
130 | } | ||
131 | |||
101 | fn solution_from_chalk(db: &impl HirDatabase, solution: chalk_solve::Solution) -> Solution { | 132 | fn solution_from_chalk(db: &impl HirDatabase, solution: chalk_solve::Solution) -> Solution { |
102 | let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution>| { | 133 | let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution>| { |
103 | let value = subst | 134 | let value = subst |