Skip to content

Commit 117068d

Browse files
committed
Simplify impl_static_method tactic
1 parent 29425bd commit 117068d

File tree

1 file changed

+28
-102
lines changed

1 file changed

+28
-102
lines changed

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

Lines changed: 28 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,7 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>(
688688
.clone()
689689
.into_iter()
690690
.chain(iter::once(ctx.goal.clone()))
691+
.filter(|ty| !ty.type_arguments().any(|it| it.contains_unknown()))
691692
.filter(|_| should_continue())
692693
.flat_map(|ty| {
693694
Impl::all_for_type(db, ty.clone()).into_iter().map(move |imp| (ty.clone(), imp))
@@ -702,20 +703,6 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>(
702703
let fn_generics = GenericDef::from(it);
703704
let imp_generics = GenericDef::from(imp);
704705

705-
// Ignore const params for now
706-
let imp_type_params = imp_generics
707-
.type_or_const_params(db)
708-
.into_iter()
709-
.map(|it| it.as_type_param(db))
710-
.collect::<Option<Vec<TypeParam>>>()?;
711-
712-
// Ignore const params for now
713-
let fn_type_params = fn_generics
714-
.type_or_const_params(db)
715-
.into_iter()
716-
.map(|it| it.as_type_param(db))
717-
.collect::<Option<Vec<TypeParam>>>()?;
718-
719706
// Ignore all functions that have something to do with lifetimes as we don't check them
720707
if !fn_generics.lifetime_params(db).is_empty()
721708
|| !imp_generics.lifetime_params(db).is_empty()
@@ -733,104 +720,43 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>(
733720
return None;
734721
}
735722

736-
// Only account for stable type parameters for now, unstable params can be default
737-
// tho, for example in `Box<T, #[unstable] A: Allocator>`
738-
if imp_type_params.iter().any(|it| it.is_unstable(db) && it.default(db).is_none())
739-
|| fn_type_params.iter().any(|it| it.is_unstable(db) && it.default(db).is_none())
740-
{
741-
return None;
742-
}
743-
744-
// Double check that we have fully known type
745-
if ty.type_arguments().any(|it| it.contains_unknown()) {
723+
// Ignore functions with generics for now as they kill the performance
724+
// Also checking bounds for generics is problematic
725+
if fn_generics.type_or_const_params(db).len() > 0 {
746726
return None;
747727
}
748728

749-
let non_default_fn_type_params_len =
750-
fn_type_params.iter().filter(|it| it.default(db).is_none()).count();
751-
752-
// Ignore functions with generics for now as they kill the performance
753-
// Also checking bounds for generics is problematic
754-
if non_default_fn_type_params_len > 0 {
729+
let ret_ty = it.ret_type_with_args(db, ty.type_arguments());
730+
// Filter out functions that return references
731+
if ctx.config.enable_borrowcheck && ret_ty.contains_reference(db) || ret_ty.is_raw_ptr()
732+
{
755733
return None;
756734
}
757735

758-
let generic_params = lookup
759-
.iter_types()
760-
.collect::<Vec<_>>() // Force take ownership
736+
// Early exit if some param cannot be filled from lookup
737+
let param_exprs: Vec<Vec<Expr>> = it
738+
.params_without_self_with_args(db, ty.type_arguments())
761739
.into_iter()
762-
.permutations(non_default_fn_type_params_len);
763-
764-
let exprs: Vec<_> = generic_params
765-
.filter(|_| should_continue())
766-
.filter_map(|generics| {
767-
// Insert default type params
768-
let mut g = generics.into_iter();
769-
let generics: Vec<_> = ty
770-
.type_arguments()
771-
.map(Some)
772-
.chain(fn_type_params.iter().map(|it| match it.default(db) {
773-
Some(ty) => Some(ty),
774-
None => {
775-
let generic = g.next().expect("Missing type param");
776-
it.trait_bounds(db)
777-
.into_iter()
778-
.all(|bound| generic.impls_trait(db, bound, &[]));
779-
// Filter out generics that do not unify due to trait bounds
780-
it.ty(db).could_unify_with(db, &generic).then_some(generic)
781-
}
782-
}))
783-
.collect::<Option<_>>()?;
784-
785-
let ret_ty = it.ret_type_with_args(
786-
db,
787-
ty.type_arguments().chain(generics.iter().cloned()),
788-
);
789-
// Filter out functions that return references
790-
if ctx.config.enable_borrowcheck && ret_ty.contains_reference(db)
791-
|| ret_ty.is_raw_ptr()
792-
{
793-
return None;
794-
}
795-
796-
// Ignore functions that do not change the type
797-
// if ty.could_unify_with_deeply(db, &ret_ty) {
798-
// return None;
799-
// }
800-
801-
// Early exit if some param cannot be filled from lookup
802-
let param_exprs: Vec<Vec<Expr>> = it
803-
.params_without_self_with_args(
804-
db,
805-
ty.type_arguments().chain(generics.iter().cloned()),
806-
)
807-
.into_iter()
808-
.map(|field| lookup.find_autoref(db, field.ty()))
809-
.collect::<Option<_>>()?;
740+
.map(|field| lookup.find_autoref(db, field.ty()))
741+
.collect::<Option<_>>()?;
742+
743+
// Note that we need special case for 0 param constructors because of multi cartesian
744+
// product
745+
let generics = ty.type_arguments().collect();
746+
let fn_exprs: Vec<Expr> = if param_exprs.is_empty() {
747+
vec![Expr::Function { func: it, generics, params: Vec::new() }]
748+
} else {
749+
param_exprs
750+
.into_iter()
751+
.multi_cartesian_product()
752+
.map(|params| Expr::Function { func: it, generics: generics.clone(), params })
753+
.collect()
754+
};
810755

811-
// Note that we need special case for 0 param constructors because of multi cartesian
812-
// product
813-
let fn_exprs: Vec<Expr> = if param_exprs.is_empty() {
814-
vec![Expr::Function { func: it, generics, params: Vec::new() }]
815-
} else {
816-
param_exprs
817-
.into_iter()
818-
.multi_cartesian_product()
819-
.map(|params| Expr::Function {
820-
func: it,
821-
generics: generics.clone(),
822-
params,
823-
})
824-
.collect()
825-
};
756+
lookup.insert(ret_ty.clone(), fn_exprs.iter().cloned());
826757

827-
lookup.insert(ret_ty.clone(), fn_exprs.iter().cloned());
828-
Some((ret_ty, fn_exprs))
829-
})
830-
.collect();
831-
Some(exprs)
758+
Some((ret_ty, fn_exprs))
832759
})
833-
.flatten()
834760
.filter_map(|(ty, exprs)| ty.could_unify_with_deeply(db, &ctx.goal).then_some(exprs))
835761
.flatten()
836762
}

0 commit comments

Comments
 (0)