@@ -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