diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-04-10 14:25:24 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-04-10 14:25:24 +0100 |
commit | 0a891d19ae6740c13ddbf8dfaf8b4703d5ca821b (patch) | |
tree | 1daf136828992006de9e21784a89b2d14be61b74 /crates/ra_hir_ty/src/traits.rs | |
parent | 176f7f61175bc433c56083a758bd7a28a8ae31f8 (diff) | |
parent | a0a80a41034b1240dc3e8fd794ae1d4f77714d99 (diff) |
Merge #3748
3748: Implement Chalk's debug methods using TLS r=matklad a=flodiebold
Chalk now panics if we don't implement these methods and run with CHALK_DEBUG, so I thought I'd try to implement them 'properly'. Sadly, it seems impossible to do without transmuting lifetimes somewhere. The problem is that we need a `&dyn HirDatabase` to get names etc., which we can't just put into TLS. I thought I could just use `scoped-tls`, but that doesn't support references to unsized types. So I put the `&dyn` into another struct and put the reference to *that* into the TLS, but I have to transmute the lifetime to 'static for that to work. I think this is sound, but I still don't really want to do it this way...
Having names in the Chalk debug output is very nice, but maybe IDs will have to suffice :disappointed:
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty/src/traits.rs')
-rw-r--r-- | crates/ra_hir_ty/src/traits.rs | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs index 5a1e12ce9..21e233379 100644 --- a/crates/ra_hir_ty/src/traits.rs +++ b/crates/ra_hir_ty/src/traits.rs | |||
@@ -177,7 +177,7 @@ fn solve( | |||
177 | 177 | ||
178 | let fuel = std::cell::Cell::new(CHALK_SOLVER_FUEL); | 178 | let fuel = std::cell::Cell::new(CHALK_SOLVER_FUEL); |
179 | 179 | ||
180 | let solution = solver.solve_limited(&context, goal, || { | 180 | let should_continue = || { |
181 | context.db.check_canceled(); | 181 | context.db.check_canceled(); |
182 | let remaining = fuel.get(); | 182 | let remaining = fuel.get(); |
183 | fuel.set(remaining - 1); | 183 | fuel.set(remaining - 1); |
@@ -185,12 +185,21 @@ fn solve( | |||
185 | log::debug!("fuel exhausted"); | 185 | log::debug!("fuel exhausted"); |
186 | } | 186 | } |
187 | remaining > 0 | 187 | remaining > 0 |
188 | }); | 188 | }; |
189 | let mut solve = || solver.solve_limited(&context, goal, should_continue); | ||
190 | // don't set the TLS for Chalk unless Chalk debugging is active, to make | ||
191 | // extra sure we only use it for debugging | ||
192 | let solution = | ||
193 | if is_chalk_debug() { chalk::tls::set_current_program(db, solve) } else { solve() }; | ||
189 | 194 | ||
190 | log::debug!("solve({:?}) => {:?}", goal, solution); | 195 | log::debug!("solve({:?}) => {:?}", goal, solution); |
191 | solution | 196 | solution |
192 | } | 197 | } |
193 | 198 | ||
199 | fn is_chalk_debug() -> bool { | ||
200 | std::env::var("CHALK_DEBUG").is_ok() | ||
201 | } | ||
202 | |||
194 | fn solution_from_chalk( | 203 | fn solution_from_chalk( |
195 | db: &dyn HirDatabase, | 204 | db: &dyn HirDatabase, |
196 | solution: chalk_solve::Solution<Interner>, | 205 | solution: chalk_solve::Solution<Interner>, |