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.rs63
1 files changed, 28 insertions, 35 deletions
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs
index 3e28852b6..d99843319 100644
--- a/crates/ra_hir/src/ty/traits.rs
+++ b/crates/ra_hir/src/ty/traits.rs
@@ -67,10 +67,33 @@ fn solve(
67 solution 67 solution
68} 68}
69 69
70/// A set of clauses that we assume to be true. E.g. if we are inside this function:
71/// ```rust
72/// fn foo<T: Default>(t: T) {}
73/// ```
74/// we assume that `T: Default`.
75#[derive(Clone, Debug, PartialEq, Eq, Hash)]
76pub struct Environment {
77 pub predicates: Vec<GenericPredicate>,
78}
79
80/// Something (usually a goal), along with an environment.
81#[derive(Clone, Debug, PartialEq, Eq, Hash)]
82pub struct InEnvironment<T> {
83 pub environment: Arc<Environment>,
84 pub value: T,
85}
86
87impl<T> InEnvironment<T> {
88 pub fn new(environment: Arc<Environment>, value: T) -> InEnvironment<T> {
89 InEnvironment { environment, value }
90 }
91}
92
70/// Something that needs to be proven (by Chalk) during type checking, e.g. that 93/// Something that needs to be proven (by Chalk) during type checking, e.g. that
71/// a certain type implements a certain trait. Proving the Obligation might 94/// a certain type implements a certain trait. Proving the Obligation might
72/// result in additional information about inference variables. 95/// result in additional information about inference variables.
73#[derive(Clone, Debug, PartialEq, Eq)] 96#[derive(Clone, Debug, PartialEq, Eq, Hash)]
74pub enum Obligation { 97pub enum Obligation {
75 /// Prove that a certain type implements a trait (the type is the `Self` type 98 /// Prove that a certain type implements a trait (the type is the `Self` type
76 /// parameter to the `TraitRef`). 99 /// parameter to the `TraitRef`).
@@ -93,44 +116,14 @@ pub struct ProjectionPredicate {
93 pub ty: Ty, 116 pub ty: Ty,
94} 117}
95 118
96/// Check using Chalk whether trait is implemented for given parameters including `Self` type. 119/// Solve a trait goal using Chalk.
97pub(crate) fn implements_query( 120pub(crate) fn solve_query(
98 db: &impl HirDatabase, 121 db: &impl HirDatabase,
99 krate: Crate, 122 krate: Crate,
100 trait_ref: Canonical<TraitRef>, 123 trait_ref: Canonical<InEnvironment<Obligation>>,
101) -> Option<Solution> { 124) -> Option<Solution> {
102 let _p = profile("implements_query"); 125 let _p = profile("implements_query");
103 let goal: chalk_ir::Goal = trait_ref.value.to_chalk(db).cast(); 126 let canonical = trait_ref.to_chalk(db).cast();
104 debug!("goal: {:?}", goal);
105 let env = chalk_ir::Environment::new();
106 let in_env = chalk_ir::InEnvironment::new(&env, goal);
107 let parameter = chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::ROOT);
108 let canonical =
109 chalk_ir::Canonical { value: in_env, binders: vec![parameter; trait_ref.num_vars] };
110 // We currently don't deal with universes (I think / hope they're not yet
111 // relevant for our use cases?)
112 let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 };
113 let solution = solve(db, krate, &u_canonical);
114 solution.map(|solution| solution_from_chalk(db, solution))
115}
116
117pub(crate) fn normalize_query(
118 db: &impl HirDatabase,
119 krate: Crate,
120 projection: Canonical<ProjectionPredicate>,
121) -> Option<Solution> {
122 let goal: chalk_ir::Goal = chalk_ir::Normalize {
123 projection: projection.value.projection_ty.to_chalk(db),
124 ty: projection.value.ty.to_chalk(db),
125 }
126 .cast();
127 debug!("goal: {:?}", goal);
128 // FIXME unify with `implements`
129 let env = chalk_ir::Environment::new();
130 let in_env = chalk_ir::InEnvironment::new(&env, goal);
131 let parameter = chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::ROOT);
132 let canonical =
133 chalk_ir::Canonical { value: in_env, binders: vec![parameter; projection.num_vars] };
134 // We currently don't deal with universes (I think / hope they're not yet 127 // We currently don't deal with universes (I think / hope they're not yet
135 // relevant for our use cases?) 128 // relevant for our use cases?)
136 let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 }; 129 let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 };