Skip to content

Commit f9f1d31

Browse files
committed
Use unit of work as fuel instead of time
1 parent 9785dcc commit f9f1d31

File tree

3 files changed

+48
-42
lines changed

3 files changed

+48
-42
lines changed

src/tools/rust-analyzer/crates/hir/src/term_search.rs

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
//! Term search
22
3-
use std::time::{Duration, Instant};
4-
53
use hir_def::type_ref::Mutability;
64
use hir_ty::db::HirDatabase;
75
use itertools::Itertools;
@@ -271,20 +269,13 @@ pub struct TermSearchConfig {
271269
pub enable_borrowcheck: bool,
272270
/// Indicate when to squash multiple trees to `Many` as there are too many to keep track
273271
pub many_alternatives_threshold: usize,
274-
/// Depth of the search i.e. number of cycles to run
275-
pub depth: usize,
276-
/// Time fuel for term search
277-
pub fuel: Option<Duration>,
272+
/// Fuel for term search
273+
pub fuel: u64,
278274
}
279275

280276
impl Default for TermSearchConfig {
281277
fn default() -> Self {
282-
Self {
283-
enable_borrowcheck: true,
284-
many_alternatives_threshold: 1,
285-
depth: 5,
286-
fuel: Some(Duration::from_millis(100)),
287-
}
278+
Self { enable_borrowcheck: true, many_alternatives_threshold: 1, fuel: 400 }
288279
}
289280
}
290281

@@ -319,40 +310,31 @@ pub fn term_search<DB: HirDatabase>(ctx: &TermSearchCtx<'_, DB>) -> Vec<Expr> {
319310
});
320311

321312
let mut lookup = LookupTable::new(ctx.config.many_alternatives_threshold, ctx.goal.clone());
322-
let start = Instant::now();
313+
let fuel = std::cell::Cell::new(ctx.config.fuel);
314+
315+
let should_continue = &|| {
316+
let remaining = fuel.get();
317+
fuel.set(remaining.saturating_sub(1));
318+
if remaining == 0 {
319+
tracing::debug!("fuel exhausted");
320+
}
321+
remaining > 0
322+
};
323323

324324
// Try trivial tactic first, also populates lookup table
325325
let mut solutions: Vec<Expr> = tactics::trivial(ctx, &defs, &mut lookup).collect();
326326
// Use well known types tactic before iterations as it does not depend on other tactics
327327
solutions.extend(tactics::famous_types(ctx, &defs, &mut lookup));
328328

329-
for _ in 0..ctx.config.depth {
329+
while should_continue() {
330330
lookup.new_round();
331331

332-
if ctx.config.fuel.is_some_and(|timeout| start.elapsed() > timeout) {
333-
break;
334-
}
335-
solutions.extend(tactics::type_constructor(ctx, &defs, &mut lookup));
336-
if ctx.config.fuel.is_some_and(|timeout| start.elapsed() > timeout) {
337-
break;
338-
}
339-
solutions.extend(tactics::free_function(ctx, &defs, &mut lookup));
340-
if ctx.config.fuel.is_some_and(|timeout| start.elapsed() > timeout) {
341-
break;
342-
}
343-
solutions.extend(tactics::impl_method(ctx, &defs, &mut lookup));
344-
if ctx.config.fuel.is_some_and(|timeout| start.elapsed() > timeout) {
345-
break;
346-
}
347-
solutions.extend(tactics::struct_projection(ctx, &defs, &mut lookup));
348-
if ctx.config.fuel.is_some_and(|timeout| start.elapsed() > timeout) {
349-
break;
350-
}
351-
solutions.extend(tactics::impl_static_method(ctx, &defs, &mut lookup));
352-
if ctx.config.fuel.is_some_and(|timeout| start.elapsed() > timeout) {
353-
break;
354-
}
355-
solutions.extend(tactics::make_tuple(ctx, &defs, &mut lookup));
332+
solutions.extend(tactics::type_constructor(ctx, &defs, &mut lookup, should_continue));
333+
solutions.extend(tactics::free_function(ctx, &defs, &mut lookup, should_continue));
334+
solutions.extend(tactics::impl_method(ctx, &defs, &mut lookup, should_continue));
335+
solutions.extend(tactics::struct_projection(ctx, &defs, &mut lookup, should_continue));
336+
solutions.extend(tactics::impl_static_method(ctx, &defs, &mut lookup, should_continue));
337+
solutions.extend(tactics::make_tuple(ctx, &defs, &mut lookup, should_continue));
356338

357339
// Discard not interesting `ScopeDef`s for speedup
358340
for def in lookup.exhausted_scopedefs() {

src/tools/rust-analyzer/crates/hir/src/term_search/tactics.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,14 @@ pub(super) fn type_constructor<'a, DB: HirDatabase>(
101101
ctx: &'a TermSearchCtx<'a, DB>,
102102
defs: &'a FxHashSet<ScopeDef>,
103103
lookup: &'a mut LookupTable,
104+
should_continue: &'a dyn std::ops::Fn() -> bool,
104105
) -> impl Iterator<Item = Expr> + 'a {
105106
let db = ctx.sema.db;
106107
let module = ctx.scope.module();
107108
fn variant_helper(
108109
db: &dyn HirDatabase,
109110
lookup: &mut LookupTable,
111+
should_continue: &dyn std::ops::Fn() -> bool,
110112
parent_enum: Enum,
111113
variant: Variant,
112114
config: &TermSearchConfig,
@@ -152,6 +154,7 @@ pub(super) fn type_constructor<'a, DB: HirDatabase>(
152154
.chain((non_default_type_params_len == 0).then_some(Vec::new()));
153155

154156
generic_params
157+
.filter(|_| should_continue())
155158
.filter_map(move |generics| {
156159
// Insert default type params
157160
let mut g = generics.into_iter();
@@ -194,8 +197,14 @@ pub(super) fn type_constructor<'a, DB: HirDatabase>(
194197
defs.iter()
195198
.filter_map(move |def| match def {
196199
ScopeDef::ModuleDef(ModuleDef::Variant(it)) => {
197-
let variant_exprs =
198-
variant_helper(db, lookup, it.parent_enum(db), *it, &ctx.config);
200+
let variant_exprs = variant_helper(
201+
db,
202+
lookup,
203+
should_continue,
204+
it.parent_enum(db),
205+
*it,
206+
&ctx.config,
207+
);
199208
if variant_exprs.is_empty() {
200209
return None;
201210
}
@@ -213,7 +222,9 @@ pub(super) fn type_constructor<'a, DB: HirDatabase>(
213222
let exprs: Vec<(Type, Vec<Expr>)> = enum_
214223
.variants(db)
215224
.into_iter()
216-
.flat_map(|it| variant_helper(db, lookup, *enum_, it, &ctx.config))
225+
.flat_map(|it| {
226+
variant_helper(db, lookup, should_continue, *enum_, it, &ctx.config)
227+
})
217228
.collect();
218229

219230
if exprs.is_empty() {
@@ -271,6 +282,7 @@ pub(super) fn type_constructor<'a, DB: HirDatabase>(
271282
.chain((non_default_type_params_len == 0).then_some(Vec::new()));
272283

273284
let exprs = generic_params
285+
.filter(|_| should_continue())
274286
.filter_map(|generics| {
275287
// Insert default type params
276288
let mut g = generics.into_iter();
@@ -349,6 +361,7 @@ pub(super) fn free_function<'a, DB: HirDatabase>(
349361
ctx: &'a TermSearchCtx<'a, DB>,
350362
defs: &'a FxHashSet<ScopeDef>,
351363
lookup: &'a mut LookupTable,
364+
should_continue: &'a dyn std::ops::Fn() -> bool,
352365
) -> impl Iterator<Item = Expr> + 'a {
353366
let db = ctx.sema.db;
354367
let module = ctx.scope.module();
@@ -390,6 +403,7 @@ pub(super) fn free_function<'a, DB: HirDatabase>(
390403
.permutations(non_default_type_params_len);
391404

392405
let exprs: Vec<_> = generic_params
406+
.filter(|_| should_continue())
393407
.filter_map(|generics| {
394408
// Insert default type params
395409
let mut g = generics.into_iter();
@@ -478,6 +492,7 @@ pub(super) fn impl_method<'a, DB: HirDatabase>(
478492
ctx: &'a TermSearchCtx<'a, DB>,
479493
_defs: &'a FxHashSet<ScopeDef>,
480494
lookup: &'a mut LookupTable,
495+
should_continue: &'a dyn std::ops::Fn() -> bool,
481496
) -> impl Iterator<Item = Expr> + 'a {
482497
let db = ctx.sema.db;
483498
let module = ctx.scope.module();
@@ -554,6 +569,7 @@ pub(super) fn impl_method<'a, DB: HirDatabase>(
554569
.permutations(non_default_fn_type_params_len);
555570

556571
let exprs: Vec<_> = generic_params
572+
.filter(|_| should_continue())
557573
.filter_map(|generics| {
558574
// Insert default type params
559575
let mut g = generics.into_iter();
@@ -649,13 +665,15 @@ pub(super) fn struct_projection<'a, DB: HirDatabase>(
649665
ctx: &'a TermSearchCtx<'a, DB>,
650666
_defs: &'a FxHashSet<ScopeDef>,
651667
lookup: &'a mut LookupTable,
668+
should_continue: &'a dyn std::ops::Fn() -> bool,
652669
) -> impl Iterator<Item = Expr> + 'a {
653670
let db = ctx.sema.db;
654671
let module = ctx.scope.module();
655672
lookup
656673
.new_types(NewTypesKey::StructProjection)
657674
.into_iter()
658675
.map(|ty| (ty.clone(), lookup.find(db, &ty).expect("Expr not in lookup")))
676+
.filter(|_| should_continue())
659677
.flat_map(move |(ty, targets)| {
660678
ty.fields(db).into_iter().filter_map(move |(field, filed_ty)| {
661679
if !field.is_visible_from(db, module) {
@@ -720,6 +738,7 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>(
720738
ctx: &'a TermSearchCtx<'a, DB>,
721739
_defs: &'a FxHashSet<ScopeDef>,
722740
lookup: &'a mut LookupTable,
741+
should_continue: &'a dyn std::ops::Fn() -> bool,
723742
) -> impl Iterator<Item = Expr> + 'a {
724743
let db = ctx.sema.db;
725744
let module = ctx.scope.module();
@@ -728,6 +747,7 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>(
728747
.clone()
729748
.into_iter()
730749
.chain(iter::once(ctx.goal.clone()))
750+
.filter(|_| should_continue())
731751
.flat_map(|ty| {
732752
Impl::all_for_type(db, ty.clone()).into_iter().map(move |imp| (ty.clone(), imp))
733753
})
@@ -801,6 +821,7 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>(
801821
.permutations(non_default_fn_type_params_len);
802822

803823
let exprs: Vec<_> = generic_params
824+
.filter(|_| should_continue())
804825
.filter_map(|generics| {
805826
// Insert default type params
806827
let mut g = generics.into_iter();
@@ -888,6 +909,7 @@ pub(super) fn make_tuple<'a, DB: HirDatabase>(
888909
ctx: &'a TermSearchCtx<'a, DB>,
889910
_defs: &'a FxHashSet<ScopeDef>,
890911
lookup: &'a mut LookupTable,
912+
should_continue: &'a dyn std::ops::Fn() -> bool,
891913
) -> impl Iterator<Item = Expr> + 'a {
892914
let db = ctx.sema.db;
893915
let module = ctx.scope.module();
@@ -896,6 +918,7 @@ pub(super) fn make_tuple<'a, DB: HirDatabase>(
896918
.types_wishlist()
897919
.clone()
898920
.into_iter()
921+
.filter(|_| should_continue())
899922
.filter(|ty| ty.is_tuple())
900923
.filter_map(move |ty| {
901924
// Double check to not contain unknown
@@ -915,6 +938,7 @@ pub(super) fn make_tuple<'a, DB: HirDatabase>(
915938
let exprs: Vec<Expr> = param_exprs
916939
.into_iter()
917940
.multi_cartesian_product()
941+
.filter(|_| should_continue())
918942
.map(|params| {
919943
let tys: Vec<Type> = params.iter().map(|it| it.ty(db)).collect();
920944
let tuple_ty = Type::new_tuple(module.krate().into(), &tys);

src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ pub(crate) fn complete_expr(acc: &mut Completions, ctx: &CompletionContext<'_>)
353353
config: hir::term_search::TermSearchConfig {
354354
enable_borrowcheck: false,
355355
many_alternatives_threshold: 1,
356-
depth: 3,
356+
fuel: 200,
357357
..Default::default()
358358
},
359359
};

0 commit comments

Comments
 (0)