@@ -4,6 +4,7 @@ use std::sync::Arc;
4
4
use chalk_ir:: cast:: Cast ;
5
5
use log:: debug;
6
6
use parking_lot:: Mutex ;
7
+ use ra_db:: salsa;
7
8
use ra_prof:: profile;
8
9
use rustc_hash:: FxHashSet ;
9
10
@@ -14,7 +15,33 @@ use self::chalk::{from_chalk, ToChalk};
14
15
15
16
pub ( crate ) mod chalk;
16
17
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
+ }
18
45
19
46
/// This controls the maximum size of types Chalk considers. If we set this too
20
47
/// 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> {
27
54
krate : Crate ,
28
55
}
29
56
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 ( ) ;
31
62
// krate parameter is just so we cache a unique solver per crate
32
63
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 ( ) ) ) }
35
66
}
36
67
37
68
/// Collects impls for the given trait in the whole dependency tree of `krate`.
@@ -127,7 +158,7 @@ pub(crate) fn trait_solve_query(
127
158
// We currently don't deal with universes (I think / hope they're not yet
128
159
// relevant for our use cases?)
129
160
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) ;
131
162
solution. map ( |solution| solution_from_chalk ( db, solution) )
132
163
}
133
164
0 commit comments