@@ -10,7 +10,7 @@ pub(crate) mod type_alias;
1010pub ( crate ) mod union_literal;
1111pub ( crate ) mod variant;
1212
13- use hir:: { AsAssocItem , HasAttrs , HirDisplay , ModuleDef , ScopeDef , Type } ;
13+ use hir:: { AsAssocItem , HasAttrs , HirDisplay , Impl , ModuleDef , ScopeDef , Type } ;
1414use ide_db:: text_edit:: TextEdit ;
1515use ide_db:: {
1616 RootDatabase , SnippetCap , SymbolKind ,
@@ -23,7 +23,9 @@ use syntax::{AstNode, SmolStr, SyntaxKind, TextRange, ToSmolStr, ast, format_smo
2323use crate :: {
2424 CompletionContext , CompletionItem , CompletionItemKind , CompletionItemRefMode ,
2525 CompletionRelevance ,
26- context:: { DotAccess , DotAccessKind , PathCompletionCtx , PathKind , PatternContext } ,
26+ context:: {
27+ DotAccess , DotAccessKind , PathCompletionCtx , PathKind , PatternContext , TypeLocation ,
28+ } ,
2729 item:: { Builder , CompletionRelevanceTypeMatch } ,
2830 render:: {
2931 function:: render_fn,
@@ -422,6 +424,7 @@ fn render_resolution_path(
422424 }
423425
424426 let completion = ctx. completion ;
427+ let module = completion. module ;
425428 let cap = ctx. snippet_cap ( ) ;
426429 let db = completion. db ;
427430 let config = completion. config ;
@@ -466,6 +469,7 @@ fn render_resolution_path(
466469 exact_name_match : compute_exact_name_match ( completion, & name) ,
467470 is_local : matches ! ( resolution, ScopeDef :: Local ( _) ) ,
468471 requires_import,
472+ has_local_inherent_impl : compute_has_local_inherent_impl ( db, path_ctx, & ty, module) ,
469473 ..CompletionRelevance :: default ( )
470474 } ) ;
471475
@@ -660,6 +664,18 @@ fn compute_type_match(
660664 match_types ( ctx, expected_type, completion_ty)
661665}
662666
667+ fn compute_has_local_inherent_impl (
668+ db : & RootDatabase ,
669+ path_ctx : & PathCompletionCtx < ' _ > ,
670+ completion_ty : & hir:: Type < ' _ > ,
671+ curr_module : hir:: Module ,
672+ ) -> bool {
673+ matches ! ( path_ctx. kind, PathKind :: Type { location: TypeLocation :: ImplTarget } )
674+ && Impl :: all_for_type ( db, completion_ty. clone ( ) )
675+ . iter ( )
676+ . any ( |imp| imp. trait_ ( db) . is_none ( ) && imp. module ( db) == curr_module)
677+ }
678+
663679fn compute_exact_name_match ( ctx : & CompletionContext < ' _ > , completion_name : & str ) -> bool {
664680 ctx. expected_name . as_ref ( ) . is_some_and ( |name| name. text ( ) == completion_name)
665681}
@@ -832,6 +848,7 @@ mod tests {
832848 ) ,
833849 ( relevance. trait_. is_some_and( |it| it. is_op_method) , "op_method" ) ,
834850 ( relevance. requires_import, "requires_import" ) ,
851+ ( relevance. has_local_inherent_impl, "has_local_inherent_impl" ) ,
835852 ]
836853 . into_iter ( )
837854 . filter_map ( |( cond, desc) | if cond { Some ( desc) } else { None } )
@@ -1214,6 +1231,7 @@ fn main() { Foo::Fo$0 }
12141231 },
12151232 ),
12161233 is_skipping_completion: false,
1234+ has_local_inherent_impl: false,
12171235 },
12181236 trigger_call_info: true,
12191237 },
@@ -1264,6 +1282,7 @@ fn main() { Foo::Fo$0 }
12641282 },
12651283 ),
12661284 is_skipping_completion: false,
1285+ has_local_inherent_impl: false,
12671286 },
12681287 trigger_call_info: true,
12691288 },
@@ -1407,6 +1426,7 @@ fn main() { Foo::Fo$0 }
14071426 },
14081427 ),
14091428 is_skipping_completion: false,
1429+ has_local_inherent_impl: false,
14101430 },
14111431 trigger_call_info: true,
14121432 },
@@ -1490,6 +1510,7 @@ fn main() { let _: m::Spam = S$0 }
14901510 },
14911511 ),
14921512 is_skipping_completion: false,
1513+ has_local_inherent_impl: false,
14931514 },
14941515 trigger_call_info: true,
14951516 },
@@ -1526,6 +1547,7 @@ fn main() { let _: m::Spam = S$0 }
15261547 },
15271548 ),
15281549 is_skipping_completion: false,
1550+ has_local_inherent_impl: false,
15291551 },
15301552 trigger_call_info: true,
15311553 },
@@ -1616,6 +1638,7 @@ fn foo() { A { the$0 } }
16161638 postfix_match: None,
16171639 function: None,
16181640 is_skipping_completion: false,
1641+ has_local_inherent_impl: false,
16191642 },
16201643 },
16211644 ]
@@ -1675,6 +1698,7 @@ impl S {
16751698 },
16761699 ),
16771700 is_skipping_completion: false,
1701+ has_local_inherent_impl: false,
16781702 },
16791703 },
16801704 CompletionItem {
@@ -1766,6 +1790,7 @@ use self::E::*;
17661790 },
17671791 ),
17681792 is_skipping_completion: false,
1793+ has_local_inherent_impl: false,
17691794 },
17701795 trigger_call_info: true,
17711796 },
@@ -1836,6 +1861,7 @@ fn foo(s: S) { s.$0 }
18361861 },
18371862 ),
18381863 is_skipping_completion: false,
1864+ has_local_inherent_impl: false,
18391865 },
18401866 },
18411867 ]
@@ -2048,6 +2074,7 @@ fn f() -> i32 {
20482074 postfix_match: None,
20492075 function: None,
20502076 is_skipping_completion: false,
2077+ has_local_inherent_impl: false,
20512078 },
20522079 },
20532080 ]
@@ -2193,6 +2220,48 @@ fn f() {
21932220 ) ;
21942221 }
21952222
2223+ #[ test]
2224+ fn score_has_local_inherent_impl ( ) {
2225+ check_relevance (
2226+ r#"
2227+ trait Foob {}
2228+ struct Fooa {}
2229+ impl Fooa {}
2230+
2231+ impl Foo$0
2232+ "# ,
2233+ expect ! [ [ r#"
2234+ tt Foob []
2235+ st Fooa Fooa [has_local_inherent_impl]
2236+ "# ] ] ,
2237+ ) ;
2238+
2239+ // inherent impl in different modules, not trigger `has_local_inherent_impl`
2240+ check_relevance (
2241+ r#"
2242+ trait Foob {}
2243+ struct Fooa {}
2244+
2245+ mod a {
2246+ use super::*;
2247+ impl Fooa {}
2248+ }
2249+
2250+ mod b {
2251+ use super::*;
2252+ impl Foo$0
2253+ }
2254+
2255+ "# ,
2256+ expect ! [ [ r#"
2257+ st Fooa Fooa []
2258+ tt Foob []
2259+ md a []
2260+ md b []
2261+ "# ] ] ,
2262+ ) ;
2263+ }
2264+
21962265 #[ test]
21972266 fn test_avoid_redundant_suggestion ( ) {
21982267 check_relevance (
@@ -2861,6 +2930,7 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 }
28612930 },
28622931 ),
28632932 is_skipping_completion: false,
2933+ has_local_inherent_impl: false,
28642934 },
28652935 ref_match: "&@107",
28662936 },
@@ -2948,6 +3018,7 @@ fn foo() {
29483018 postfix_match: None,
29493019 function: None,
29503020 is_skipping_completion: false,
3021+ has_local_inherent_impl: false,
29513022 },
29523023 },
29533024 ]
@@ -3006,6 +3077,7 @@ fn main() {
30063077 },
30073078 ),
30083079 is_skipping_completion: false,
3080+ has_local_inherent_impl: false,
30093081 },
30103082 ref_match: "&@92",
30113083 },
@@ -3476,6 +3548,7 @@ fn main() {
34763548 postfix_match: None,
34773549 function: None,
34783550 is_skipping_completion: false,
3551+ has_local_inherent_impl: false,
34793552 },
34803553 },
34813554 CompletionItem {
@@ -3510,6 +3583,7 @@ fn main() {
35103583 postfix_match: None,
35113584 function: None,
35123585 is_skipping_completion: false,
3586+ has_local_inherent_impl: false,
35133587 },
35143588 },
35153589 ]
0 commit comments