@@ -7,10 +7,12 @@ use stdx::{format_to, to_lower_snake_case};
77use syntax:: { AstNode , SmolStr } ;
88
99use crate :: {
10- context:: { CompletionContext , DotAccess , DotAccessKind , PathCompletionCtx , PathKind } ,
10+ context:: {
11+ CompletionContext , DotAccess , DotAccessKind , PathCompletionCtx , PathKind , Qualified ,
12+ } ,
1113 item:: {
1214 Builder , CompletionItem , CompletionItemKind , CompletionRelevance ,
13- CompletionRelevanceAssociatedFnType ,
15+ CompletionRelevanceAssociatedFn , CompletionRelevanceAssociatedFnType ,
1416 } ,
1517 render:: { compute_exact_name_match, compute_ref_match, compute_type_match, RenderContext } ,
1618 CallableSnippets ,
@@ -110,9 +112,9 @@ fn render(
110112 compute_type_match ( completion, & func. ty ( db) )
111113 } ,
112114 exact_name_match : compute_exact_name_match ( completion, & call) ,
115+ associated_fn : compute_associated_fn ( & ctx, func, & func_kind, db) ,
113116 is_op_method,
114117 is_item_from_notable_trait,
115- associated_fn_type : compute_constructor_type ( & ctx, func, db) ,
116118 ..ctx. completion_relevance ( )
117119 } ) ;
118120
@@ -161,36 +163,50 @@ fn render(
161163 item
162164}
163165
164- fn compute_constructor_type (
166+ fn compute_associated_fn (
165167 ctx : & RenderContext < ' _ > ,
166168 func : hir:: Function ,
169+ func_kind : & FuncKind < ' _ > ,
167170 db : & dyn HirDatabase ,
168- ) -> Option < CompletionRelevanceAssociatedFnType > {
171+ ) -> Option < CompletionRelevanceAssociatedFn > {
169172 if func. as_assoc_item ( ctx. db ( ) ) . is_none ( ) {
170173 return None ;
171174 }
172175
173- let has_args = !func. assoc_fn_params ( db) . is_empty ( ) ;
174176 let ret_type = func. ret_type ( db) ;
177+ let self_ty = match func_kind {
178+ FuncKind :: Function ( PathCompletionCtx {
179+ qualified : Qualified :: With { path, .. } , ..
180+ } ) => path. segment ( ) . map ( |s| s. to_string ( ) ) ,
181+ _ => None ,
182+ } ;
183+ let ( returns_self, returns_self_wrapped) = self_ty
184+ . map ( |self_ty| {
185+ let ret_ty = ret_type. display ( db) . to_string ( ) ;
186+ let ret_self_wrapped = ret_ty. contains ( & format ! ( "<{self_ty}>" ) ) ;
175187
176- dbg ! ( & ret_type, & func, & ctx) ;
188+ ( ret_ty == self_ty || ret_self_wrapped, ret_self_wrapped)
189+ } )
190+ . unwrap_or_else ( || ( false , false ) ) ;
177191
178- if ctx. completion . expected_type . as_ref ( ) == Some ( & ret_type) {
192+ let ty = if !returns_self && ctx. completion . expected_type . as_ref ( ) == Some ( & ret_type) {
179193 // impl Foo { fn baz(&self) -> u32 { 0 } }
180194 // let _: u32 = foo.$0; // baz is preffered as it returns expected u32
181- Some ( CompletionRelevanceAssociatedFnType :: ReturnsExpectedType )
182- } else if !has_args && !ret_type. is_unit ( ) {
183- // fn() -> A
184- Some ( CompletionRelevanceAssociatedFnType :: DirectConstructor )
185- } else if has_args && !ret_type. is_unit ( ) {
186- // fn(..) -> A
187- Some ( CompletionRelevanceAssociatedFnType :: DirectConstructorWithArgs )
188- } else if !has_args && ret_type. display ( db) . to_string ( ) . ends_with ( "Builder" ) {
195+ CompletionRelevanceAssociatedFnType :: ReturnsExpectedType
196+ } else if ret_type. display ( db) . to_string ( ) . ends_with ( "Builder" ) {
189197 // -> [..]Builder
190- Some ( CompletionRelevanceAssociatedFnType :: Builder )
198+ CompletionRelevanceAssociatedFnType :: Builder
199+ } else if returns_self_wrapped {
200+ // fn() -> Result<A>
201+ CompletionRelevanceAssociatedFnType :: Constructor
202+ } else if returns_self {
203+ // fn() -> A
204+ CompletionRelevanceAssociatedFnType :: DirectConstructor
191205 } else {
192- None
193- }
206+ CompletionRelevanceAssociatedFnType :: Unknown
207+ } ;
208+
209+ Some ( CompletionRelevanceAssociatedFn { ty, has_args : !func. assoc_fn_params ( db) . is_empty ( ) } )
194210}
195211
196212pub ( super ) fn add_call_parens < ' b > (
0 commit comments