Skip to content

Commit b4f3eb4

Browse files
committed
Simplify impl_method tactic
1 parent 23d3ac7 commit b4f3eb4

File tree

1 file changed

+41
-104
lines changed

1 file changed

+41
-104
lines changed

crates/hir/src/term_search/tactics.rs

Lines changed: 41 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,8 @@ pub(super) fn impl_method<'a, DB: HirDatabase>(
438438
lookup
439439
.new_types(NewTypesKey::ImplMethod)
440440
.into_iter()
441+
.filter(|ty| !ty.type_arguments().any(|it| it.contains_unknown()))
442+
.filter(|_| should_continue())
441443
.flat_map(|ty| {
442444
Impl::all_for_type(db, ty.clone()).into_iter().map(move |imp| (ty.clone(), imp))
443445
})
@@ -450,22 +452,10 @@ pub(super) fn impl_method<'a, DB: HirDatabase>(
450452
let fn_generics = GenericDef::from(it);
451453
let imp_generics = GenericDef::from(imp);
452454

453-
// Ignore const params for now
454-
let imp_type_params = imp_generics
455-
.type_or_const_params(db)
456-
.into_iter()
457-
.map(|it| it.as_type_param(db))
458-
.collect::<Option<Vec<TypeParam>>>()?;
459-
460-
// Ignore const params for now
461-
let fn_type_params = fn_generics
462-
.type_or_const_params(db)
463-
.into_iter()
464-
.map(|it| it.as_type_param(db))
465-
.collect::<Option<Vec<TypeParam>>>()?;
466-
467455
// Ignore all functions that have something to do with lifetimes as we don't check them
468-
if !fn_generics.lifetime_params(db).is_empty() {
456+
if !fn_generics.lifetime_params(db).is_empty()
457+
|| !imp_generics.lifetime_params(db).is_empty()
458+
{
469459
return None;
470460
}
471461

@@ -479,112 +469,59 @@ pub(super) fn impl_method<'a, DB: HirDatabase>(
479469
return None;
480470
}
481471

482-
// Only account for stable type parameters for now, unstable params can be default
483-
// tho, for example in `Box<T, #[unstable] A: Allocator>`
484-
if imp_type_params.iter().any(|it| it.is_unstable(db) && it.default(db).is_none())
485-
|| fn_type_params.iter().any(|it| it.is_unstable(db) && it.default(db).is_none())
486-
{
472+
// Ignore functions with generics for now as they kill the performance
473+
// Also checking bounds for generics is problematic
474+
if fn_generics.type_or_const_params(db).len() > 0 {
487475
return None;
488476
}
489477

490-
// Double check that we have fully known type
491-
if ty.type_arguments().any(|it| it.contains_unknown()) {
478+
let ret_ty = it.ret_type_with_args(db, ty.type_arguments());
479+
// Filter out functions that return references
480+
if ctx.config.enable_borrowcheck && ret_ty.contains_reference(db) || ret_ty.is_raw_ptr()
481+
{
492482
return None;
493483
}
494484

495-
let non_default_fn_type_params_len =
496-
fn_type_params.iter().filter(|it| it.default(db).is_none()).count();
497-
498-
// Ignore functions with generics for now as they kill the performance
499-
// Also checking bounds for generics is problematic
500-
if non_default_fn_type_params_len > 0 {
485+
// Ignore functions that do not change the type
486+
if ty.could_unify_with_deeply(db, &ret_ty) {
501487
return None;
502488
}
503489

504-
let generic_params = lookup
505-
.iter_types()
506-
.collect::<Vec<_>>() // Force take ownership
507-
.into_iter()
508-
.permutations(non_default_fn_type_params_len);
490+
let self_ty =
491+
it.self_param(db).expect("No self param").ty_with_args(db, ty.type_arguments());
509492

510-
let exprs: Vec<_> = generic_params
511-
.filter(|_| should_continue())
512-
.filter_map(|generics| {
513-
// Insert default type params
514-
let mut g = generics.into_iter();
515-
let generics: Vec<_> = ty
516-
.type_arguments()
517-
.map(Some)
518-
.chain(fn_type_params.iter().map(|it| match it.default(db) {
519-
Some(ty) => Some(ty),
520-
None => {
521-
let generic = g.next().expect("Missing type param");
522-
// Filter out generics that do not unify due to trait bounds
523-
it.ty(db).could_unify_with(db, &generic).then_some(generic)
524-
}
525-
}))
526-
.collect::<Option<_>>()?;
527-
528-
let ret_ty = it.ret_type_with_args(
529-
db,
530-
ty.type_arguments().chain(generics.iter().cloned()),
531-
);
532-
// Filter out functions that return references
533-
if ctx.config.enable_borrowcheck && ret_ty.contains_reference(db)
534-
|| ret_ty.is_raw_ptr()
535-
{
536-
return None;
537-
}
493+
// Ignore functions that have different self type
494+
if !self_ty.autoderef(db).any(|s_ty| ty == s_ty) {
495+
return None;
496+
}
538497

539-
// Ignore functions that do not change the type
540-
if ty.could_unify_with_deeply(db, &ret_ty) {
541-
return None;
542-
}
498+
let target_type_exprs = lookup.find(db, &ty).expect("Type not in lookup");
543499

544-
let self_ty = it
545-
.self_param(db)
546-
.expect("No self param")
547-
.ty_with_args(db, ty.type_arguments().chain(generics.iter().cloned()));
500+
// Early exit if some param cannot be filled from lookup
501+
let param_exprs: Vec<Vec<Expr>> = it
502+
.params_without_self_with_args(db, ty.type_arguments())
503+
.into_iter()
504+
.map(|field| lookup.find_autoref(db, field.ty()))
505+
.collect::<Option<_>>()?;
548506

549-
// Ignore functions that have different self type
550-
if !self_ty.autoderef(db).any(|s_ty| ty == s_ty) {
551-
return None;
507+
let generics: Vec<_> = ty.type_arguments().collect();
508+
let fn_exprs: Vec<Expr> = std::iter::once(target_type_exprs)
509+
.chain(param_exprs)
510+
.multi_cartesian_product()
511+
.map(|params| {
512+
let mut params = params.into_iter();
513+
let target = Box::new(params.next().unwrap());
514+
Expr::Method {
515+
func: it,
516+
generics: generics.clone(),
517+
target,
518+
params: params.collect(),
552519
}
553-
554-
let target_type_exprs = lookup.find(db, &ty).expect("Type not in lookup");
555-
556-
// Early exit if some param cannot be filled from lookup
557-
let param_exprs: Vec<Vec<Expr>> = it
558-
.params_without_self_with_args(
559-
db,
560-
ty.type_arguments().chain(generics.iter().cloned()),
561-
)
562-
.into_iter()
563-
.map(|field| lookup.find_autoref(db, field.ty()))
564-
.collect::<Option<_>>()?;
565-
566-
let fn_exprs: Vec<Expr> = std::iter::once(target_type_exprs)
567-
.chain(param_exprs)
568-
.multi_cartesian_product()
569-
.map(|params| {
570-
let mut params = params.into_iter();
571-
let target = Box::new(params.next().unwrap());
572-
Expr::Method {
573-
func: it,
574-
generics: generics.clone(),
575-
target,
576-
params: params.collect(),
577-
}
578-
})
579-
.collect();
580-
581-
lookup.insert(ret_ty.clone(), fn_exprs.iter().cloned());
582-
Some((ret_ty, fn_exprs))
583520
})
584521
.collect();
585-
Some(exprs)
522+
523+
Some((ret_ty, fn_exprs))
586524
})
587-
.flatten()
588525
.filter_map(|(ty, exprs)| ty.could_unify_with_deeply(db, &ctx.goal).then_some(exprs))
589526
.flatten()
590527
}

0 commit comments

Comments
 (0)