Reduce Chalk max_size parameter, add test for slow case
This commit is contained in:
parent
d8cd0e36f5
commit
7744cd41e2
@ -2581,6 +2581,35 @@ fn test() { foo.call()<|>; }
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn method_resolution_slow() {
|
||||
// this can get quite slow if we set the solver size limit too high
|
||||
let t = type_at(
|
||||
r#"
|
||||
//- /main.rs
|
||||
trait Send {}
|
||||
|
||||
struct S1; impl Send for S1;
|
||||
struct S2; impl Send for S2;
|
||||
struct U1;
|
||||
|
||||
trait Trait { fn method(self); }
|
||||
|
||||
struct X1<A, B> {}
|
||||
impl<A, B> Send for X1<A, B> where A: Send, B: Send {}
|
||||
|
||||
struct S<B, C> {}
|
||||
|
||||
trait Fn {}
|
||||
|
||||
impl<B, C> Trait for S<B, C> where C: Fn, B: Send {}
|
||||
|
||||
fn test() { (S {}).method()<|>; }
|
||||
"#,
|
||||
);
|
||||
assert_eq!(t, "{unknown}");
|
||||
}
|
||||
|
||||
fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
|
||||
let file = db.parse(pos.file_id);
|
||||
let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap();
|
||||
|
@ -14,6 +14,11 @@ mod chalk;
|
||||
|
||||
pub(crate) type Solver = chalk_solve::Solver;
|
||||
|
||||
/// This controls the maximum size of types Chalk considers. If we set this too
|
||||
/// high, we can run into slow edge cases; if we set it too low, Chalk won't
|
||||
/// find some solutions.
|
||||
const CHALK_SOLVER_MAX_SIZE: usize = 2;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct ChalkContext<'a, DB> {
|
||||
db: &'a DB,
|
||||
@ -22,7 +27,8 @@ struct ChalkContext<'a, DB> {
|
||||
|
||||
pub(crate) fn solver(_db: &impl HirDatabase, _krate: Crate) -> Arc<Mutex<Solver>> {
|
||||
// krate parameter is just so we cache a unique solver per crate
|
||||
let solver_choice = chalk_solve::SolverChoice::SLG { max_size: 10 };
|
||||
let solver_choice = chalk_solve::SolverChoice::SLG { max_size: CHALK_SOLVER_MAX_SIZE };
|
||||
debug!("Creating new solver for crate {:?}", _krate);
|
||||
Arc::new(Mutex::new(solver_choice.into_solver()))
|
||||
}
|
||||
|
||||
@ -53,6 +59,7 @@ fn solve(
|
||||
) -> Option<chalk_solve::Solution> {
|
||||
let context = ChalkContext { db, krate };
|
||||
let solver = db.solver(krate);
|
||||
debug!("solve goal: {:?}", goal);
|
||||
let solution = solver.lock().unwrap().solve(&context, goal);
|
||||
debug!("solve({:?}) => {:?}", goal, solution);
|
||||
solution
|
||||
|
@ -345,11 +345,14 @@ where
|
||||
return Vec::new();
|
||||
}
|
||||
let trait_ = from_chalk(self.db, trait_id);
|
||||
self.db
|
||||
let result: Vec<_> = self
|
||||
.db
|
||||
.impls_for_trait(self.krate, trait_)
|
||||
.iter()
|
||||
.map(|impl_block| impl_block.to_chalk(self.db))
|
||||
.collect()
|
||||
.collect();
|
||||
debug!("impls_for_trait returned {} impls", result.len());
|
||||
result
|
||||
}
|
||||
fn impl_provided_for(
|
||||
&self,
|
||||
|
Loading…
x
Reference in New Issue
Block a user