aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/traits.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty/traits.rs')
-rw-r--r--crates/ra_hir/src/ty/traits.rs33
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;
8use ra_prof::profile; 8use ra_prof::profile;
9 9
10use crate::{Crate, Trait, db::HirDatabase, ImplBlock}; 10use crate::{Crate, Trait, db::HirDatabase, ImplBlock};
11use super::{TraitRef, Ty, Canonical}; 11use super::{TraitRef, Ty, Canonical, ProjectionTy};
12 12
13use self::chalk::{ToChalk, from_chalk}; 13use 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)]
82pub 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
108pub(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
101fn solution_from_chalk(db: &impl HirDatabase, solution: chalk_solve::Solution) -> Solution { 132fn 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