11//! This modules takes care of rendering various definitions as completion items.
22//! It also handles scoring (sorting) completions.
33
4- use hir:: { HasAttrs , HasSource , HirDisplay , ModPath , ScopeDef , StructKind , Type } ;
4+ use hir:: { HasAttrs , HasSource , HirDisplay , ModPath , Mutability , ScopeDef , StructKind , Type } ;
55use itertools:: Itertools ;
66use syntax:: { ast:: NameOwner , display:: * } ;
77use test_utils:: mark;
@@ -107,9 +107,16 @@ impl Completions {
107107 }
108108 } ;
109109
110+ let mut ref_match = None ;
110111 if let ScopeDef :: Local ( local) = resolution {
111- if let Some ( score) = compute_score ( ctx, & local. ty ( ctx. db ) , & local_name) {
112- completion_item = completion_item. set_score ( score) ;
112+ if let Some ( ( active_name, active_type) ) = ctx. active_name_and_type ( ) {
113+ let ty = local. ty ( ctx. db ) ;
114+ if let Some ( score) =
115+ compute_score_from_active ( & active_type, & active_name, & ty, & local_name)
116+ {
117+ completion_item = completion_item. set_score ( score) ;
118+ }
119+ ref_match = refed_type_matches ( & active_type, & active_name, & ty, & local_name) ;
113120 }
114121 }
115122
@@ -131,7 +138,7 @@ impl Completions {
131138 }
132139 }
133140
134- completion_item. kind ( kind) . set_documentation ( docs) . add_to ( self )
141+ completion_item. kind ( kind) . set_documentation ( docs) . set_ref_match ( ref_match ) . add_to ( self )
135142 }
136143
137144 pub ( crate ) fn add_macro (
@@ -342,25 +349,15 @@ impl Completions {
342349 }
343350}
344351
345- pub ( crate ) fn compute_score (
346- ctx : & CompletionContext ,
352+ fn compute_score_from_active (
353+ active_type : & Type ,
354+ active_name : & str ,
347355 ty : & Type ,
348356 name : & str ,
349357) -> Option < CompletionScore > {
350- let ( active_name, active_type) = if let Some ( record_field) = & ctx. record_field_syntax {
351- mark:: hit!( record_field_type_match) ;
352- let ( struct_field, _local) = ctx. sema . resolve_record_field ( record_field) ?;
353- ( struct_field. name ( ctx. db ) . to_string ( ) , struct_field. signature_ty ( ctx. db ) )
354- } else if let Some ( active_parameter) = & ctx. active_parameter {
355- mark:: hit!( active_param_type_match) ;
356- ( active_parameter. name . clone ( ) , active_parameter. ty . clone ( ) )
357- } else {
358- return None ;
359- } ;
360-
361358 // Compute score
362359 // For the same type
363- if & active_type != ty {
360+ if active_type != ty {
364361 return None ;
365362 }
366363
@@ -373,6 +370,24 @@ pub(crate) fn compute_score(
373370
374371 Some ( res)
375372}
373+ fn refed_type_matches (
374+ active_type : & Type ,
375+ active_name : & str ,
376+ ty : & Type ,
377+ name : & str ,
378+ ) -> Option < ( Mutability , CompletionScore ) > {
379+ let derefed_active = active_type. remove_ref ( ) ?;
380+ let score = compute_score_from_active ( & derefed_active, & active_name, & ty, & name) ?;
381+ Some ( (
382+ if active_type. is_mutable_reference ( ) { Mutability :: Mut } else { Mutability :: Shared } ,
383+ score,
384+ ) )
385+ }
386+
387+ fn compute_score ( ctx : & CompletionContext , ty : & Type , name : & str ) -> Option < CompletionScore > {
388+ let ( active_name, active_type) = ctx. active_name_and_type ( ) ?;
389+ compute_score_from_active ( & active_type, & active_name, ty, name)
390+ }
376391
377392enum Params {
378393 Named ( Vec < String > ) ,
0 commit comments