Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/term_search/tactics.rs')
| -rw-r--r-- | crates/hir/src/term_search/tactics.rs | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/crates/hir/src/term_search/tactics.rs b/crates/hir/src/term_search/tactics.rs index 63b2a2506f..a26728272d 100644 --- a/crates/hir/src/term_search/tactics.rs +++ b/crates/hir/src/term_search/tactics.rs @@ -4,6 +4,7 @@ //! * `ctx` - Context for the term search //! * `defs` - Set of items in scope at term search target location //! * `lookup` - Lookup table for types +//! * `should_continue` - Function that indicates when to stop iterating //! And they return iterator that yields type trees that unify with the `goal` type. use std::iter; @@ -97,16 +98,19 @@ pub(super) fn trivial<'a, DB: HirDatabase>( /// * `ctx` - Context for the term search /// * `defs` - Set of items in scope at term search target location /// * `lookup` - Lookup table for types +/// * `should_continue` - Function that indicates when to stop iterating pub(super) fn type_constructor<'a, DB: HirDatabase>( ctx: &'a TermSearchCtx<'a, DB>, defs: &'a FxHashSet<ScopeDef>, lookup: &'a mut LookupTable, + should_continue: &'a dyn std::ops::Fn() -> bool, ) -> impl Iterator<Item = Expr> + 'a { let db = ctx.sema.db; let module = ctx.scope.module(); fn variant_helper( db: &dyn HirDatabase, lookup: &mut LookupTable, + should_continue: &dyn std::ops::Fn() -> bool, parent_enum: Enum, variant: Variant, config: &TermSearchConfig, @@ -152,6 +156,7 @@ pub(super) fn type_constructor<'a, DB: HirDatabase>( .chain((non_default_type_params_len == 0).then_some(Vec::new())); generic_params + .filter(|_| should_continue()) .filter_map(move |generics| { // Insert default type params let mut g = generics.into_iter(); @@ -194,8 +199,14 @@ pub(super) fn type_constructor<'a, DB: HirDatabase>( defs.iter() .filter_map(move |def| match def { ScopeDef::ModuleDef(ModuleDef::Variant(it)) => { - let variant_exprs = - variant_helper(db, lookup, it.parent_enum(db), *it, &ctx.config); + let variant_exprs = variant_helper( + db, + lookup, + should_continue, + it.parent_enum(db), + *it, + &ctx.config, + ); if variant_exprs.is_empty() { return None; } @@ -213,7 +224,9 @@ pub(super) fn type_constructor<'a, DB: HirDatabase>( let exprs: Vec<(Type, Vec<Expr>)> = enum_ .variants(db) .into_iter() - .flat_map(|it| variant_helper(db, lookup, *enum_, it, &ctx.config)) + .flat_map(|it| { + variant_helper(db, lookup, should_continue, *enum_, it, &ctx.config) + }) .collect(); if exprs.is_empty() { @@ -271,6 +284,7 @@ pub(super) fn type_constructor<'a, DB: HirDatabase>( .chain((non_default_type_params_len == 0).then_some(Vec::new())); let exprs = generic_params + .filter(|_| should_continue()) .filter_map(|generics| { // Insert default type params let mut g = generics.into_iter(); @@ -345,10 +359,12 @@ pub(super) fn type_constructor<'a, DB: HirDatabase>( /// * `ctx` - Context for the term search /// * `defs` - Set of items in scope at term search target location /// * `lookup` - Lookup table for types +/// * `should_continue` - Function that indicates when to stop iterating pub(super) fn free_function<'a, DB: HirDatabase>( ctx: &'a TermSearchCtx<'a, DB>, defs: &'a FxHashSet<ScopeDef>, lookup: &'a mut LookupTable, + should_continue: &'a dyn std::ops::Fn() -> bool, ) -> impl Iterator<Item = Expr> + 'a { let db = ctx.sema.db; let module = ctx.scope.module(); @@ -390,6 +406,7 @@ pub(super) fn free_function<'a, DB: HirDatabase>( .permutations(non_default_type_params_len); let exprs: Vec<_> = generic_params + .filter(|_| should_continue()) .filter_map(|generics| { // Insert default type params let mut g = generics.into_iter(); @@ -474,10 +491,12 @@ pub(super) fn free_function<'a, DB: HirDatabase>( /// * `ctx` - Context for the term search /// * `defs` - Set of items in scope at term search target location /// * `lookup` - Lookup table for types +/// * `should_continue` - Function that indicates when to stop iterating pub(super) fn impl_method<'a, DB: HirDatabase>( ctx: &'a TermSearchCtx<'a, DB>, _defs: &'a FxHashSet<ScopeDef>, lookup: &'a mut LookupTable, + should_continue: &'a dyn std::ops::Fn() -> bool, ) -> impl Iterator<Item = Expr> + 'a { let db = ctx.sema.db; let module = ctx.scope.module(); @@ -554,6 +573,7 @@ pub(super) fn impl_method<'a, DB: HirDatabase>( .permutations(non_default_fn_type_params_len); let exprs: Vec<_> = generic_params + .filter(|_| should_continue()) .filter_map(|generics| { // Insert default type params let mut g = generics.into_iter(); @@ -645,10 +665,12 @@ pub(super) fn impl_method<'a, DB: HirDatabase>( /// * `ctx` - Context for the term search /// * `defs` - Set of items in scope at term search target location /// * `lookup` - Lookup table for types +/// * `should_continue` - Function that indicates when to stop iterating pub(super) fn struct_projection<'a, DB: HirDatabase>( ctx: &'a TermSearchCtx<'a, DB>, _defs: &'a FxHashSet<ScopeDef>, lookup: &'a mut LookupTable, + should_continue: &'a dyn std::ops::Fn() -> bool, ) -> impl Iterator<Item = Expr> + 'a { let db = ctx.sema.db; let module = ctx.scope.module(); @@ -656,6 +678,7 @@ pub(super) fn struct_projection<'a, DB: HirDatabase>( .new_types(NewTypesKey::StructProjection) .into_iter() .map(|ty| (ty.clone(), lookup.find(db, &ty).expect("Expr not in lookup"))) + .filter(|_| should_continue()) .flat_map(move |(ty, targets)| { ty.fields(db).into_iter().filter_map(move |(field, filed_ty)| { if !field.is_visible_from(db, module) { @@ -716,10 +739,12 @@ pub(super) fn famous_types<'a, DB: HirDatabase>( /// * `ctx` - Context for the term search /// * `defs` - Set of items in scope at term search target location /// * `lookup` - Lookup table for types +/// * `should_continue` - Function that indicates when to stop iterating pub(super) fn impl_static_method<'a, DB: HirDatabase>( ctx: &'a TermSearchCtx<'a, DB>, _defs: &'a FxHashSet<ScopeDef>, lookup: &'a mut LookupTable, + should_continue: &'a dyn std::ops::Fn() -> bool, ) -> impl Iterator<Item = Expr> + 'a { let db = ctx.sema.db; let module = ctx.scope.module(); @@ -728,6 +753,7 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>( .clone() .into_iter() .chain(iter::once(ctx.goal.clone())) + .filter(|_| should_continue()) .flat_map(|ty| { Impl::all_for_type(db, ty.clone()).into_iter().map(move |imp| (ty.clone(), imp)) }) @@ -801,6 +827,7 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>( .permutations(non_default_fn_type_params_len); let exprs: Vec<_> = generic_params + .filter(|_| should_continue()) .filter_map(|generics| { // Insert default type params let mut g = generics.into_iter(); @@ -884,10 +911,12 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>( /// * `ctx` - Context for the term search /// * `defs` - Set of items in scope at term search target location /// * `lookup` - Lookup table for types +/// * `should_continue` - Function that indicates when to stop iterating pub(super) fn make_tuple<'a, DB: HirDatabase>( ctx: &'a TermSearchCtx<'a, DB>, _defs: &'a FxHashSet<ScopeDef>, lookup: &'a mut LookupTable, + should_continue: &'a dyn std::ops::Fn() -> bool, ) -> impl Iterator<Item = Expr> + 'a { let db = ctx.sema.db; let module = ctx.scope.module(); @@ -896,6 +925,7 @@ pub(super) fn make_tuple<'a, DB: HirDatabase>( .types_wishlist() .clone() .into_iter() + .filter(|_| should_continue()) .filter(|ty| ty.is_tuple()) .filter_map(move |ty| { // Double check to not contain unknown @@ -915,6 +945,7 @@ pub(super) fn make_tuple<'a, DB: HirDatabase>( let exprs: Vec<Expr> = param_exprs .into_iter() .multi_cartesian_product() + .filter(|_| should_continue()) .map(|params| { let tys: Vec<Type> = params.iter().map(|it| it.ty(db)).collect(); let tuple_ty = Type::new_tuple(module.krate().into(), &tys); |