Skip to content

Commit d35251c

Browse files
committed
switch from volatile to untracked read
1 parent 0194adb commit d35251c

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed

crates/ra_hir/src/db.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::sync::Arc;
22

3-
use parking_lot::Mutex;
43
use ra_db::{salsa, SourceDatabase};
54
use ra_syntax::{ast, Parse, SmolStr, SyntaxNode};
65

@@ -147,6 +146,7 @@ pub trait DefDatabase: InternDatabase {
147146
}
148147

149148
#[salsa::query_group(HirDatabaseStorage)]
149+
#[salsa::requires(salsa::Database)]
150150
pub trait HirDatabase: DefDatabase + AstDatabase {
151151
#[salsa::invoke(ExprScopes::expr_scopes_query)]
152152
fn expr_scopes(&self, def: DefWithBody) -> Arc<ExprScopes>;
@@ -187,11 +187,10 @@ pub trait HirDatabase: DefDatabase + AstDatabase {
187187
/// This provides the Chalk trait solver instance. Because Chalk always
188188
/// works from a specific crate, this query is keyed on the crate; and
189189
/// because Chalk does its own internal caching, the solver is wrapped in a
190-
/// Mutex and the query is marked volatile, to make sure the cached state is
191-
/// thrown away when input facts change.
190+
/// Mutex and the query does an untracked read internally, to make sure the
191+
/// cached state is thrown away when input facts change.
192192
#[salsa::invoke(crate::ty::traits::trait_solver_query)]
193-
#[salsa::volatile]
194-
fn trait_solver(&self, krate: Crate) -> Arc<Mutex<crate::ty::traits::Solver>>;
193+
fn trait_solver(&self, krate: Crate) -> crate::ty::traits::ChalkSolver;
195194

196195
#[salsa::invoke(crate::ty::traits::chalk::associated_ty_data_query)]
197196
fn associated_ty_data(&self, id: chalk_ir::TypeId) -> Arc<chalk_rust_ir::AssociatedTyDatum>;

crates/ra_hir/src/ty/traits.rs

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::sync::Arc;
44
use chalk_ir::cast::Cast;
55
use log::debug;
66
use parking_lot::Mutex;
7+
use ra_db::salsa;
78
use ra_prof::profile;
89
use rustc_hash::FxHashSet;
910

@@ -14,7 +15,33 @@ use self::chalk::{from_chalk, ToChalk};
1415

1516
pub(crate) mod chalk;
1617

17-
pub(crate) type Solver = chalk_solve::Solver;
18+
#[derive(Debug, Clone)]
19+
pub struct ChalkSolver {
20+
krate: Crate,
21+
inner: Arc<Mutex<chalk_solve::Solver>>,
22+
}
23+
24+
impl PartialEq for ChalkSolver {
25+
fn eq(&self, other: &ChalkSolver) -> bool {
26+
Arc::ptr_eq(&self.inner, &other.inner)
27+
}
28+
}
29+
30+
impl Eq for ChalkSolver {}
31+
32+
impl ChalkSolver {
33+
fn solve(
34+
&self,
35+
db: &impl HirDatabase,
36+
goal: &chalk_ir::UCanonical<chalk_ir::InEnvironment<chalk_ir::Goal>>,
37+
) -> Option<chalk_solve::Solution> {
38+
let context = ChalkContext { db, krate: self.krate };
39+
debug!("solve goal: {:?}", goal);
40+
let solution = self.inner.lock().solve_with_fuel(&context, goal, Some(1000));
41+
debug!("solve({:?}) => {:?}", goal, solution);
42+
solution
43+
}
44+
}
1845

1946
/// This controls the maximum size of types Chalk considers. If we set this too
2047
/// high, we can run into slow edge cases; if we set it too low, Chalk won't
@@ -27,11 +54,15 @@ struct ChalkContext<'a, DB> {
2754
krate: Crate,
2855
}
2956

30-
pub(crate) fn trait_solver_query(_db: &impl HirDatabase, _krate: Crate) -> Arc<Mutex<Solver>> {
57+
pub(crate) fn trait_solver_query(
58+
db: &(impl HirDatabase + salsa::Database),
59+
krate: Crate,
60+
) -> ChalkSolver {
61+
db.salsa_runtime().report_untracked_read();
3162
// krate parameter is just so we cache a unique solver per crate
3263
let solver_choice = chalk_solve::SolverChoice::SLG { max_size: CHALK_SOLVER_MAX_SIZE };
33-
debug!("Creating new solver for crate {:?}", _krate);
34-
Arc::new(Mutex::new(solver_choice.into_solver()))
64+
debug!("Creating new solver for crate {:?}", krate);
65+
ChalkSolver { krate, inner: Arc::new(Mutex::new(solver_choice.into_solver())) }
3566
}
3667

3768
/// Collects impls for the given trait in the whole dependency tree of `krate`.
@@ -127,7 +158,7 @@ pub(crate) fn trait_solve_query(
127158
// We currently don't deal with universes (I think / hope they're not yet
128159
// relevant for our use cases?)
129160
let u_canonical = chalk_ir::UCanonical { canonical, universes: 1 };
130-
let solution = solve(db, krate, &u_canonical);
161+
let solution = db.trait_solver(krate).solve(db, &u_canonical);
131162
solution.map(|solution| solution_from_chalk(db, solution))
132163
}
133164

0 commit comments

Comments
 (0)