@@ -152,11 +152,37 @@ impl LookupTable {
152
152
& self . exhausted_scopedefs
153
153
}
154
154
155
+ /// Types queried but not found
155
156
fn take_types_wishlist ( & mut self ) -> FxHashSet < Type > {
156
157
std:: mem:: take ( & mut self . types_wishlist )
157
158
}
158
159
}
159
160
161
+ /// Context for the `term_search` function
162
+ pub struct TermSearchCtx < ' a , DB : HirDatabase > {
163
+ /// Semantics for the program
164
+ pub sema : & ' a Semantics < ' a , DB > ,
165
+ /// Semantic scope, captures context for the term search
166
+ pub scope : & ' a SemanticsScope < ' a > ,
167
+ /// Target / expected output type
168
+ pub goal : Type ,
169
+ /// Configuration for term search
170
+ pub config : TermSearchConfig ,
171
+ }
172
+
173
+ /// Configuration options for the term search
174
+ #[ derive( Debug , Clone , Copy ) ]
175
+ pub struct TermSearchConfig {
176
+ /// Enable borrow checking, this guarantees the outputs of the `term_search` to borrow-check
177
+ pub enable_borrowcheck : bool ,
178
+ }
179
+
180
+ impl Default for TermSearchConfig {
181
+ fn default ( ) -> Self {
182
+ Self { enable_borrowcheck : true }
183
+ }
184
+ }
185
+
160
186
/// # Term search
161
187
///
162
188
/// Search for terms (expressions) that unify with the `goal` type.
@@ -181,37 +207,32 @@ impl LookupTable {
181
207
/// Note that there are usually more ways we can get to the `goal` type but some are discarded to
182
208
/// reduce the memory consumption. It is also unlikely anyone is willing ti browse through
183
209
/// thousands of possible responses so we currently take first 10 from every tactic.
184
- pub fn term_search < DB : HirDatabase > (
185
- sema : & Semantics < ' _ , DB > ,
186
- scope : & SemanticsScope < ' _ > ,
187
- goal : & Type ,
188
- ) -> Vec < TypeTree > {
210
+ pub fn term_search < DB : HirDatabase > ( ctx : TermSearchCtx < ' _ , DB > ) -> Vec < TypeTree > {
211
+ let module = ctx. scope . module ( ) ;
189
212
let mut defs = FxHashSet :: default ( ) ;
190
- defs. insert ( ScopeDef :: ModuleDef ( ModuleDef :: Module ( scope . module ( ) ) ) ) ;
213
+ defs. insert ( ScopeDef :: ModuleDef ( ModuleDef :: Module ( module) ) ) ;
191
214
192
- scope. process_all_names ( & mut |_, def| {
215
+ ctx . scope . process_all_names ( & mut |_, def| {
193
216
defs. insert ( def) ;
194
217
} ) ;
195
- let module = scope. module ( ) ;
196
218
197
219
let mut lookup = LookupTable :: new ( ) ;
198
220
199
221
// Try trivial tactic first, also populates lookup table
200
- let mut solutions: Vec < TypeTree > =
201
- tactics:: trivial ( sema. db , & defs, & mut lookup, goal) . collect ( ) ;
222
+ let mut solutions: Vec < TypeTree > = tactics:: trivial ( & ctx, & defs, & mut lookup) . collect ( ) ;
202
223
// Use well known types tactic before iterations as it does not depend on other tactics
203
- solutions. extend ( tactics:: famous_types ( sema . db , & module , & defs, & mut lookup, goal ) ) ;
224
+ solutions. extend ( tactics:: famous_types ( & ctx , & defs, & mut lookup) ) ;
204
225
205
226
let mut solution_found = !solutions. is_empty ( ) ;
206
227
207
228
for _ in 0 ..5 {
208
229
lookup. new_round ( ) ;
209
230
210
- solutions. extend ( tactics:: type_constructor ( sema . db , & module , & defs, & mut lookup, goal ) ) ;
211
- solutions. extend ( tactics:: free_function ( sema . db , & module , & defs, & mut lookup, goal ) ) ;
212
- solutions. extend ( tactics:: impl_method ( sema . db , & module , & defs, & mut lookup, goal ) ) ;
213
- solutions. extend ( tactics:: struct_projection ( sema . db , & module , & defs, & mut lookup, goal ) ) ;
214
- solutions. extend ( tactics:: impl_static_method ( sema . db , & module , & defs, & mut lookup, goal ) ) ;
231
+ solutions. extend ( tactics:: type_constructor ( & ctx , & defs, & mut lookup) ) ;
232
+ solutions. extend ( tactics:: free_function ( & ctx , & defs, & mut lookup) ) ;
233
+ solutions. extend ( tactics:: impl_method ( & ctx , & defs, & mut lookup) ) ;
234
+ solutions. extend ( tactics:: struct_projection ( & ctx , & defs, & mut lookup) ) ;
235
+ solutions. extend ( tactics:: impl_static_method ( & ctx , & defs, & mut lookup) ) ;
215
236
216
237
// Break after 1 round after successful solution
217
238
if solution_found {
0 commit comments