@@ -10,9 +10,7 @@ pub(crate) mod variant;
1010pub ( crate ) mod union_literal;
1111pub ( crate ) mod literal;
1212
13- use core:: panic;
14-
15- use hir:: { AsAssocItem , HasAttrs , HirDisplay , ModuleDef , ScopeDef , Type } ;
13+ use hir:: { AsAssocItem , Function , HasAttrs , HirDisplay , ModuleDef , ScopeDef , Type } ;
1614use ide_db:: {
1715 documentation:: { Documentation , HasDocs } ,
1816 helpers:: item_name,
@@ -395,17 +393,14 @@ fn render_resolution_path(
395393 ScopeDef :: ModuleDef ( ModuleDef :: Adt ( adt) ) | ScopeDef :: AdtSelfType ( adt) => {
396394 set_item_relevance ( adt. ty ( db) )
397395 }
398- ScopeDef :: ModuleDef ( ModuleDef :: Function ( func) ) => {
399- set_item_relevance ( func. ty ( db) . as_callable ( db) . unwrap ( ) . ty )
400- }
401- ScopeDef :: ModuleDef ( ModuleDef :: Variant ( variant) ) => {
402- set_item_relevance ( variant. parent_enum ( db) . ty ( db) )
403- }
396+ // Functions are handled at the start of the function.
397+ ScopeDef :: ModuleDef ( ModuleDef :: Function ( _) ) => ( ) , // TODO: Should merge with the match case earlier in the function?
398+ // Enum variants are handled at the start of the function.
399+ ScopeDef :: ModuleDef ( ModuleDef :: Variant ( _) ) => ( ) ,
404400 ScopeDef :: ModuleDef ( ModuleDef :: Const ( konst) ) => set_item_relevance ( konst. ty ( db) ) ,
405401 ScopeDef :: ModuleDef ( ModuleDef :: Static ( stat) ) => set_item_relevance ( stat. ty ( db) ) ,
406402 ScopeDef :: ModuleDef ( ModuleDef :: BuiltinType ( bt) ) => set_item_relevance ( bt. ty ( db) ) ,
407403 ScopeDef :: ImplSelfType ( imp) => set_item_relevance ( imp. self_ty ( db) ) ,
408-
409404 ScopeDef :: GenericParam ( _)
410405 | ScopeDef :: Label ( _)
411406 | ScopeDef :: Unknown
@@ -502,6 +497,20 @@ fn scope_def_is_deprecated(ctx: &RenderContext<'_>, resolution: ScopeDef) -> boo
502497 }
503498}
504499
500+ fn match_types (
501+ ctx : & CompletionContext < ' _ > ,
502+ ty1 : & hir:: Type ,
503+ ty2 : & hir:: Type ,
504+ ) -> Option < CompletionRelevanceTypeMatch > {
505+ if ty1 == ty2 {
506+ Some ( CompletionRelevanceTypeMatch :: Exact )
507+ } else if ty1. could_unify_with ( ctx. db , ty2) {
508+ Some ( CompletionRelevanceTypeMatch :: CouldUnify )
509+ } else {
510+ None
511+ }
512+ }
513+
505514fn compute_type_match (
506515 ctx : & CompletionContext < ' _ > ,
507516 completion_ty : & hir:: Type ,
@@ -514,35 +523,42 @@ fn compute_type_match(
514523 return None ;
515524 }
516525
517- if completion_ty == expected_type {
518- Some ( CompletionRelevanceTypeMatch :: Exact )
519- } else if expected_type. could_unify_with ( ctx. db , completion_ty) {
520- Some ( CompletionRelevanceTypeMatch :: CouldUnify )
521- } else {
522- None
523- }
526+ match_types ( ctx, expected_type, completion_ty)
524527}
525528
526- fn compute_type_match2 (
529+ fn compute_function_type_match (
527530 ctx : & CompletionContext < ' _ > ,
528- completion_ty1 : & hir:: Type ,
529- completion_ty2 : & hir:: Type ,
531+ func : & Function ,
530532) -> Option < CompletionRelevanceTypeMatch > {
531- let expected_type = completion_ty1;
533+ // We compute a vec of function parameters + the return type for the expected
534+ // type as well as the function we are matching with. Doing this allows for
535+ // matching all of the types in one iterator.
532536
533- // We don't ever consider unit type to be an exact type match, since
534- // nearly always this is not meaningful to the user.
535- if expected_type. is_unit ( ) {
537+ let expected_callable = ctx. expected_type . as_ref ( ) ?. as_callable ( ctx. db ) ?;
538+ let expected_types = expected_callable. params ( ctx. db ) . into_iter ( ) . map ( |param| param. 1 ) ;
539+ let actual_types =
540+ func. ty ( ctx. db ) . as_callable ( ctx. db ) ?. params ( ctx. db ) . into_iter ( ) . map ( |param| param. 1 ) ;
541+
542+ if expected_types. len ( ) != actual_types. len ( ) {
536543 return None ;
537544 }
538545
539- if completion_ty2 == expected_type {
540- Some ( CompletionRelevanceTypeMatch :: Exact )
541- } else if expected_type. could_unify_with ( ctx. db , completion_ty2) {
542- Some ( CompletionRelevanceTypeMatch :: CouldUnify )
543- } else {
544- None
546+ let mut matches = expected_types
547+ . zip ( actual_types)
548+ . chain ( [ ( expected_callable. return_type ( ) , func. ret_type ( ctx. db ) ) ] )
549+ . map ( |( expected_type, actual_type) | match_types ( ctx, & expected_type, & actual_type) ) ;
550+
551+ // Any missing type match indicates that these types can not be unified.
552+ if matches. any ( |type_match| type_match. is_none ( ) ) {
553+ return None ;
545554 }
555+
556+ // If any of the types are unifiable but not exact we consider the function types as a whole
557+ // to be unifiable. Otherwise if every pair of types is an exact match the functions are an
558+ // exact type match.
559+ matches
560+ . find ( |type_match| matches ! ( type_match, Some ( CompletionRelevanceTypeMatch :: CouldUnify ) ) )
561+ . unwrap_or ( Some ( CompletionRelevanceTypeMatch :: Exact ) )
546562}
547563
548564fn compute_exact_name_match ( ctx : & CompletionContext < ' _ > , completion_name : & str ) -> bool {
@@ -796,7 +812,7 @@ fn main() {
796812 ) ;
797813 }
798814
799- // TODO: does this test even make sense?
815+ // TODO: How dowe test ModuleDef::Variant(Variant?)
800816 #[ test]
801817 fn set_enum_variant_type_completion_info ( ) {
802818 check_relevance (
@@ -820,7 +836,7 @@ pub mod test_mod_a {
820836fn test(input: dep::test_mod_b::Enum) { }
821837
822838fn main() {
823- test(Enum$0);
839+ test(Enum::Variant $0);
824840}
825841"# ,
826842 expect ! [ [ r#"
@@ -859,7 +875,7 @@ fn main() {
859875}
860876"# ,
861877 expect ! [ [ r#"
862- fn Function (use dep::test_mod_a::Function) [type_could_unify +requires_import]
878+ fn Function (use dep::test_mod_a::Function) [type +requires_import]
863879 fn main []
864880 fn test []
865881 md dep []
@@ -868,7 +884,6 @@ fn main() {
868884 ) ;
869885 }
870886
871- // TODO This test does not trigger the const case
872887 #[ test]
873888 fn set_const_type_completion_info ( ) {
874889 check_relevance (
@@ -933,8 +948,38 @@ fn main() {
933948 ) ;
934949 }
935950
936- // TODO: seems like something is going wrong here. Exapt type match has no effect
937- // EDIT: maybe it is actually working
951+ #[ test]
952+ fn set_self_type_completion_info_with_params ( ) {
953+ check_relevance (
954+ r#"
955+ //- /lib.rs crate:dep
956+ pub struct Struct;
957+
958+ impl Struct {
959+ pub fn Function(&self, input: i32) -> bool {
960+ false
961+ }
962+ }
963+
964+
965+ //- /main.rs crate:main deps:dep
966+
967+ use dep::Struct;
968+
969+
970+ fn test(input: fn(&dep::Struct, i32) -> bool) { }
971+
972+ fn main() {
973+ test(Struct::Function$0);
974+ }
975+
976+ "# ,
977+ expect ! [ [ r#"
978+ me Function [type]
979+ "# ] ] ,
980+ ) ;
981+ }
982+
938983 #[ test]
939984 fn set_self_type_completion_info ( ) {
940985 check_relevance (
@@ -964,34 +1009,26 @@ fn func(input: Struct) { }
9641009 ) ;
9651010 }
9661011
967- // TODO: how do we actually test builtins?
968-
9691012 #[ test]
9701013 fn set_builtin_type_completion_info ( ) {
9711014 check_relevance (
9721015 r#"
973- //- /lib.rs crate:dep
974-
975- pub mod test_mod_b {
976- static STATIC: i32 = 5;
977- }
1016+ //- /main.rs crate:main
9781017
979- pub mod test_mod_a {
980- static STATIC: &str = "test";
981- }
982-
983- //- /main.rs crate:main deps:dep
984-
985- fn test(input: i32) { }
1018+ fn test(input: bool) { }
1019+ pub Input: bool = false;
9861020
9871021fn main() {
988- test(STATIC$0);
1022+ let input = false;
1023+ let inputbad = 3;
1024+ test(inp$0);
9891025}
9901026"# ,
9911027 expect ! [ [ r#"
1028+ lc input [type+name+local]
1029+ lc inputbad [local]
9921030 fn main() []
9931031 fn test(…) []
994- md dep []
9951032 "# ] ] ,
9961033 ) ;
9971034 }
0 commit comments