@@ -10,9 +10,7 @@ pub(crate) mod variant;
10
10
pub ( crate ) mod union_literal;
11
11
pub ( crate ) mod literal;
12
12
13
- use core:: panic;
14
-
15
- use hir:: { AsAssocItem , HasAttrs , HirDisplay , ModuleDef , ScopeDef , Type } ;
13
+ use hir:: { AsAssocItem , Function , HasAttrs , HirDisplay , ModuleDef , ScopeDef , Type } ;
16
14
use ide_db:: {
17
15
documentation:: { Documentation , HasDocs } ,
18
16
helpers:: item_name,
@@ -395,17 +393,14 @@ fn render_resolution_path(
395
393
ScopeDef :: ModuleDef ( ModuleDef :: Adt ( adt) ) | ScopeDef :: AdtSelfType ( adt) => {
396
394
set_item_relevance ( adt. ty ( db) )
397
395
}
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 ( _) ) => ( ) ,
404
400
ScopeDef :: ModuleDef ( ModuleDef :: Const ( konst) ) => set_item_relevance ( konst. ty ( db) ) ,
405
401
ScopeDef :: ModuleDef ( ModuleDef :: Static ( stat) ) => set_item_relevance ( stat. ty ( db) ) ,
406
402
ScopeDef :: ModuleDef ( ModuleDef :: BuiltinType ( bt) ) => set_item_relevance ( bt. ty ( db) ) ,
407
403
ScopeDef :: ImplSelfType ( imp) => set_item_relevance ( imp. self_ty ( db) ) ,
408
-
409
404
ScopeDef :: GenericParam ( _)
410
405
| ScopeDef :: Label ( _)
411
406
| ScopeDef :: Unknown
@@ -502,6 +497,20 @@ fn scope_def_is_deprecated(ctx: &RenderContext<'_>, resolution: ScopeDef) -> boo
502
497
}
503
498
}
504
499
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
+
505
514
fn compute_type_match (
506
515
ctx : & CompletionContext < ' _ > ,
507
516
completion_ty : & hir:: Type ,
@@ -514,35 +523,42 @@ fn compute_type_match(
514
523
return None ;
515
524
}
516
525
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)
524
527
}
525
528
526
- fn compute_type_match2 (
529
+ fn compute_function_type_match (
527
530
ctx : & CompletionContext < ' _ > ,
528
- completion_ty1 : & hir:: Type ,
529
- completion_ty2 : & hir:: Type ,
531
+ func : & Function ,
530
532
) -> 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.
532
536
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 ( ) {
536
543
return None ;
537
544
}
538
545
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 ;
545
554
}
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 ) )
546
562
}
547
563
548
564
fn compute_exact_name_match ( ctx : & CompletionContext < ' _ > , completion_name : & str ) -> bool {
@@ -796,7 +812,7 @@ fn main() {
796
812
) ;
797
813
}
798
814
799
- // TODO: does this test even make sense?
815
+ // TODO: How dowe test ModuleDef::Variant(Variant?)
800
816
#[ test]
801
817
fn set_enum_variant_type_completion_info ( ) {
802
818
check_relevance (
@@ -820,7 +836,7 @@ pub mod test_mod_a {
820
836
fn test(input: dep::test_mod_b::Enum) { }
821
837
822
838
fn main() {
823
- test(Enum$0);
839
+ test(Enum::Variant $0);
824
840
}
825
841
"# ,
826
842
expect ! [ [ r#"
@@ -859,7 +875,7 @@ fn main() {
859
875
}
860
876
"# ,
861
877
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]
863
879
fn main []
864
880
fn test []
865
881
md dep []
@@ -868,7 +884,6 @@ fn main() {
868
884
) ;
869
885
}
870
886
871
- // TODO This test does not trigger the const case
872
887
#[ test]
873
888
fn set_const_type_completion_info ( ) {
874
889
check_relevance (
@@ -933,8 +948,38 @@ fn main() {
933
948
) ;
934
949
}
935
950
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
+
938
983
#[ test]
939
984
fn set_self_type_completion_info ( ) {
940
985
check_relevance (
@@ -964,34 +1009,26 @@ fn func(input: Struct) { }
964
1009
) ;
965
1010
}
966
1011
967
- // TODO: how do we actually test builtins?
968
-
969
1012
#[ test]
970
1013
fn set_builtin_type_completion_info ( ) {
971
1014
check_relevance (
972
1015
r#"
973
- //- /lib.rs crate:dep
974
-
975
- pub mod test_mod_b {
976
- static STATIC: i32 = 5;
977
- }
1016
+ //- /main.rs crate:main
978
1017
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;
986
1020
987
1021
fn main() {
988
- test(STATIC$0);
1022
+ let input = false;
1023
+ let inputbad = 3;
1024
+ test(inp$0);
989
1025
}
990
1026
"# ,
991
1027
expect ! [ [ r#"
1028
+ lc input [type+name+local]
1029
+ lc inputbad [local]
992
1030
fn main() []
993
1031
fn test(…) []
994
- md dep []
995
1032
"# ] ] ,
996
1033
) ;
997
1034
}
0 commit comments