diff options
Diffstat (limited to 'crates/hir_ty/src/traits.rs')
-rw-r--r-- | crates/hir_ty/src/traits.rs | 52 |
1 files changed, 11 insertions, 41 deletions
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs index c8883485c..9936d0803 100644 --- a/crates/hir_ty/src/traits.rs +++ b/crates/hir_ty/src/traits.rs | |||
@@ -1,28 +1,26 @@ | |||
1 | //! Trait solving using Chalk. | 1 | //! Trait solving using Chalk. |
2 | |||
2 | use std::env::var; | 3 | use std::env::var; |
3 | 4 | ||
4 | use base_db::CrateId; | ||
5 | use chalk_ir::cast::Cast; | 5 | use chalk_ir::cast::Cast; |
6 | use chalk_solve::{logging_db::LoggingRustIrDatabase, Solver}; | 6 | use chalk_solve::{logging_db::LoggingRustIrDatabase, Solver}; |
7 | |||
8 | use base_db::CrateId; | ||
7 | use hir_def::{lang_item::LangItemTarget, TraitId}; | 9 | use hir_def::{lang_item::LangItemTarget, TraitId}; |
8 | use stdx::panic_context; | 10 | use stdx::panic_context; |
9 | 11 | ||
10 | use crate::{ | 12 | use crate::{ |
11 | db::HirDatabase, AliasEq, AliasTy, Canonical, DomainGoal, Guidance, HirDisplay, InEnvironment, | 13 | db::HirDatabase, AliasEq, AliasTy, Canonical, DomainGoal, Guidance, HirDisplay, InEnvironment, |
12 | Solution, SolutionVariables, Ty, TyKind, WhereClause, | 14 | Interner, Solution, TraitRefExt, Ty, TyKind, WhereClause, |
13 | }; | 15 | }; |
14 | 16 | ||
15 | use self::chalk::{from_chalk, Interner, ToChalk}; | ||
16 | |||
17 | pub(crate) mod chalk; | ||
18 | |||
19 | /// This controls how much 'time' we give the Chalk solver before giving up. | 17 | /// This controls how much 'time' we give the Chalk solver before giving up. |
20 | const CHALK_SOLVER_FUEL: i32 = 100; | 18 | const CHALK_SOLVER_FUEL: i32 = 100; |
21 | 19 | ||
22 | #[derive(Debug, Copy, Clone)] | 20 | #[derive(Debug, Copy, Clone)] |
23 | struct ChalkContext<'a> { | 21 | pub(crate) struct ChalkContext<'a> { |
24 | db: &'a dyn HirDatabase, | 22 | pub(crate) db: &'a dyn HirDatabase, |
25 | krate: CrateId, | 23 | pub(crate) krate: CrateId, |
26 | } | 24 | } |
27 | 25 | ||
28 | fn create_chalk_solver() -> chalk_recursive::RecursiveSolver<Interner> { | 26 | fn create_chalk_solver() -> chalk_recursive::RecursiveSolver<Interner> { |
@@ -81,6 +79,7 @@ pub(crate) fn trait_solve_query( | |||
81 | db.trait_data(it.hir_trait_id()).name.to_string() | 79 | db.trait_data(it.hir_trait_id()).name.to_string() |
82 | } | 80 | } |
83 | DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(), | 81 | DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(), |
82 | _ => "??".to_string(), | ||
84 | }); | 83 | }); |
85 | log::info!("trait_solve_query({})", goal.value.goal.display(db)); | 84 | log::info!("trait_solve_query({})", goal.value.goal.display(db)); |
86 | 85 | ||
@@ -95,13 +94,12 @@ pub(crate) fn trait_solve_query( | |||
95 | } | 94 | } |
96 | } | 95 | } |
97 | 96 | ||
98 | let canonical = goal.to_chalk(db).cast(&Interner); | 97 | let canonical = goal.cast(&Interner); |
99 | 98 | ||
100 | // We currently don't deal with universes (I think / hope they're not yet | 99 | // We currently don't deal with universes (I think / hope they're not yet |
101 | // relevant for our use cases?) | 100 | // relevant for our use cases?) |
102 | let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 }; | 101 | let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 }; |
103 | let solution = solve(db, krate, &u_canonical); | 102 | solve(db, krate, &u_canonical) |
104 | solution.map(|solution| solution_from_chalk(db, solution)) | ||
105 | } | 103 | } |
106 | 104 | ||
107 | fn solve( | 105 | fn solve( |
@@ -148,7 +146,7 @@ fn solve( | |||
148 | // don't set the TLS for Chalk unless Chalk debugging is active, to make | 146 | // don't set the TLS for Chalk unless Chalk debugging is active, to make |
149 | // extra sure we only use it for debugging | 147 | // extra sure we only use it for debugging |
150 | let solution = | 148 | let solution = |
151 | if is_chalk_debug() { chalk::tls::set_current_program(db, solve) } else { solve() }; | 149 | if is_chalk_debug() { crate::tls::set_current_program(db, solve) } else { solve() }; |
152 | 150 | ||
153 | solution | 151 | solution |
154 | } | 152 | } |
@@ -169,34 +167,6 @@ fn is_chalk_print() -> bool { | |||
169 | std::env::var("CHALK_PRINT").is_ok() | 167 | std::env::var("CHALK_PRINT").is_ok() |
170 | } | 168 | } |
171 | 169 | ||
172 | fn solution_from_chalk( | ||
173 | db: &dyn HirDatabase, | ||
174 | solution: chalk_solve::Solution<Interner>, | ||
175 | ) -> Solution { | ||
176 | let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution<Interner>>| { | ||
177 | let result = from_chalk(db, subst); | ||
178 | SolutionVariables(result) | ||
179 | }; | ||
180 | match solution { | ||
181 | chalk_solve::Solution::Unique(constr_subst) => { | ||
182 | let subst = chalk_ir::Canonical { | ||
183 | value: constr_subst.value.subst, | ||
184 | binders: constr_subst.binders, | ||
185 | }; | ||
186 | Solution::Unique(convert_subst(subst)) | ||
187 | } | ||
188 | chalk_solve::Solution::Ambig(chalk_solve::Guidance::Definite(subst)) => { | ||
189 | Solution::Ambig(Guidance::Definite(convert_subst(subst))) | ||
190 | } | ||
191 | chalk_solve::Solution::Ambig(chalk_solve::Guidance::Suggested(subst)) => { | ||
192 | Solution::Ambig(Guidance::Suggested(convert_subst(subst))) | ||
193 | } | ||
194 | chalk_solve::Solution::Ambig(chalk_solve::Guidance::Unknown) => { | ||
195 | Solution::Ambig(Guidance::Unknown) | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | |||
200 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | 170 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
201 | pub enum FnTrait { | 171 | pub enum FnTrait { |
202 | FnOnce, | 172 | FnOnce, |