Reduce Chalk max_size parameter, add test for slow case
This commit is contained in:
@@ -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 {
|
fn type_at_pos(db: &MockDatabase, pos: FilePosition) -> String {
|
||||||
let file = db.parse(pos.file_id);
|
let file = db.parse(pos.file_id);
|
||||||
let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap();
|
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;
|
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)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
struct ChalkContext<'a, DB> {
|
struct ChalkContext<'a, DB> {
|
||||||
db: &'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>> {
|
pub(crate) fn solver(_db: &impl HirDatabase, _krate: Crate) -> Arc<Mutex<Solver>> {
|
||||||
// krate parameter is just so we cache a unique solver per crate
|
// 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()))
|
Arc::new(Mutex::new(solver_choice.into_solver()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +59,7 @@ fn solve(
|
|||||||
) -> Option<chalk_solve::Solution> {
|
) -> Option<chalk_solve::Solution> {
|
||||||
let context = ChalkContext { db, krate };
|
let context = ChalkContext { db, krate };
|
||||||
let solver = db.solver(krate);
|
let solver = db.solver(krate);
|
||||||
|
debug!("solve goal: {:?}", goal);
|
||||||
let solution = solver.lock().unwrap().solve(&context, goal);
|
let solution = solver.lock().unwrap().solve(&context, goal);
|
||||||
debug!("solve({:?}) => {:?}", goal, solution);
|
debug!("solve({:?}) => {:?}", goal, solution);
|
||||||
solution
|
solution
|
||||||
|
|||||||
@@ -345,11 +345,14 @@ where
|
|||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
let trait_ = from_chalk(self.db, trait_id);
|
let trait_ = from_chalk(self.db, trait_id);
|
||||||
self.db
|
let result: Vec<_> = self
|
||||||
|
.db
|
||||||
.impls_for_trait(self.krate, trait_)
|
.impls_for_trait(self.krate, trait_)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|impl_block| impl_block.to_chalk(self.db))
|
.map(|impl_block| impl_block.to_chalk(self.db))
|
||||||
.collect()
|
.collect();
|
||||||
|
debug!("impls_for_trait returned {} impls", result.len());
|
||||||
|
result
|
||||||
}
|
}
|
||||||
fn impl_provided_for(
|
fn impl_provided_for(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
Reference in New Issue
Block a user