Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/term_search/mod.rs')
| -rw-r--r-- | crates/hir/src/term_search/mod.rs | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/crates/hir/src/term_search/mod.rs b/crates/hir/src/term_search/mod.rs index 009d561e7d..457165296a 100644 --- a/crates/hir/src/term_search/mod.rs +++ b/crates/hir/src/term_search/mod.rs @@ -152,11 +152,37 @@ impl LookupTable { &self.exhausted_scopedefs } + /// Types queried but not found fn take_types_wishlist(&mut self) -> FxHashSet<Type> { std::mem::take(&mut self.types_wishlist) } } +/// Context for the `term_search` function +pub struct TermSearchCtx<'a, DB: HirDatabase> { + /// Semantics for the program + pub sema: &'a Semantics<'a, DB>, + /// Semantic scope, captures context for the term search + pub scope: &'a SemanticsScope<'a>, + /// Target / expected output type + pub goal: Type, + /// Configuration for term search + pub config: TermSearchConfig, +} + +/// Configuration options for the term search +#[derive(Debug, Clone, Copy)] +pub struct TermSearchConfig { + /// Enable borrow checking, this guarantees the outputs of the `term_search` to borrow-check + pub enable_borrowcheck: bool, +} + +impl Default for TermSearchConfig { + fn default() -> Self { + Self { enable_borrowcheck: true } + } +} + /// # Term search /// /// Search for terms (expressions) that unify with the `goal` type. @@ -181,37 +207,32 @@ impl LookupTable { /// Note that there are usually more ways we can get to the `goal` type but some are discarded to /// reduce the memory consumption. It is also unlikely anyone is willing ti browse through /// thousands of possible responses so we currently take first 10 from every tactic. -pub fn term_search<DB: HirDatabase>( - sema: &Semantics<'_, DB>, - scope: &SemanticsScope<'_>, - goal: &Type, -) -> Vec<TypeTree> { +pub fn term_search<DB: HirDatabase>(ctx: TermSearchCtx<'_, DB>) -> Vec<TypeTree> { + let module = ctx.scope.module(); let mut defs = FxHashSet::default(); - defs.insert(ScopeDef::ModuleDef(ModuleDef::Module(scope.module()))); + defs.insert(ScopeDef::ModuleDef(ModuleDef::Module(module))); - scope.process_all_names(&mut |_, def| { + ctx.scope.process_all_names(&mut |_, def| { defs.insert(def); }); - let module = scope.module(); let mut lookup = LookupTable::new(); // Try trivial tactic first, also populates lookup table - let mut solutions: Vec<TypeTree> = - tactics::trivial(sema.db, &defs, &mut lookup, goal).collect(); + let mut solutions: Vec<TypeTree> = tactics::trivial(&ctx, &defs, &mut lookup).collect(); // Use well known types tactic before iterations as it does not depend on other tactics - solutions.extend(tactics::famous_types(sema.db, &module, &defs, &mut lookup, goal)); + solutions.extend(tactics::famous_types(&ctx, &defs, &mut lookup)); let mut solution_found = !solutions.is_empty(); for _ in 0..5 { lookup.new_round(); - solutions.extend(tactics::type_constructor(sema.db, &module, &defs, &mut lookup, goal)); - solutions.extend(tactics::free_function(sema.db, &module, &defs, &mut lookup, goal)); - solutions.extend(tactics::impl_method(sema.db, &module, &defs, &mut lookup, goal)); - solutions.extend(tactics::struct_projection(sema.db, &module, &defs, &mut lookup, goal)); - solutions.extend(tactics::impl_static_method(sema.db, &module, &defs, &mut lookup, goal)); + solutions.extend(tactics::type_constructor(&ctx, &defs, &mut lookup)); + solutions.extend(tactics::free_function(&ctx, &defs, &mut lookup)); + solutions.extend(tactics::impl_method(&ctx, &defs, &mut lookup)); + solutions.extend(tactics::struct_projection(&ctx, &defs, &mut lookup)); + solutions.extend(tactics::impl_static_method(&ctx, &defs, &mut lookup)); // Break after 1 round after successful solution if solution_found { |