@@ -162,11 +162,52 @@ impl<'a> CompletionContext<'a> {
162162 }
163163
164164 /// Calculate the expected type and name of the cursor position.
165- fn expected_type_and_name ( & self ) -> ( Option < Type > , Option < NameOrNameRef > ) {
165+ fn expected_type_and_name (
166+ & self ,
167+ name_like : & ast:: NameLike ,
168+ ) -> ( Option < Type > , Option < NameOrNameRef > ) {
166169 let mut node = match self . token . parent ( ) {
167170 Some ( it) => it,
168171 None => return ( None , None ) ,
169172 } ;
173+
174+ let strip_refs = |mut ty : Type | match name_like {
175+ ast:: NameLike :: NameRef ( n) => {
176+ let p = match n. syntax ( ) . parent ( ) {
177+ Some ( it) => it,
178+ None => return ty,
179+ } ;
180+ let top_syn = match_ast ! {
181+ match p {
182+ ast:: FieldExpr ( e) => e
183+ . syntax( )
184+ . ancestors( )
185+ . map_while( ast:: FieldExpr :: cast)
186+ . last( )
187+ . map( |it| it. syntax( ) . clone( ) ) ,
188+ ast:: PathSegment ( e) => e
189+ . syntax( )
190+ . ancestors( )
191+ . skip( 1 )
192+ . take_while( |it| ast:: Path :: can_cast( it. kind( ) ) || ast:: PathExpr :: can_cast( it. kind( ) ) )
193+ . find_map( ast:: PathExpr :: cast)
194+ . map( |it| it. syntax( ) . clone( ) ) ,
195+ _ => None
196+ }
197+ } ;
198+ let top_syn = match top_syn {
199+ Some ( it) => it,
200+ None => return ty,
201+ } ;
202+ for _ in top_syn. ancestors ( ) . skip ( 1 ) . map_while ( ast:: RefExpr :: cast) {
203+ cov_mark:: hit!( expected_type_fn_param_ref) ;
204+ ty = ty. strip_reference ( ) ;
205+ }
206+ ty
207+ }
208+ _ => ty,
209+ } ;
210+
170211 loop {
171212 break match_ast ! {
172213 match node {
@@ -199,13 +240,9 @@ impl<'a> CompletionContext<'a> {
199240 self . token. clone( ) ,
200241 ) . map( |ap| {
201242 let name = ap. ident( ) . map( NameOrNameRef :: Name ) ;
202- let ty = if has_ref( & self . token) {
203- cov_mark:: hit!( expected_type_fn_param_ref) ;
204- ap. ty. remove_ref( )
205- } else {
206- Some ( ap. ty)
207- } ;
208- ( ty, name)
243+
244+ let ty = strip_refs( ap. ty) ;
245+ ( Some ( ty) , name)
209246 } )
210247 . unwrap_or( ( None , None ) )
211248 } ,
@@ -330,8 +367,6 @@ impl<'a> CompletionContext<'a> {
330367 return None ;
331368 }
332369
333- ( self . expected_type , self . expected_name ) = self . expected_type_and_name ( ) ;
334-
335370 // Overwrite the path kind for derives
336371 if let Some ( ( original_file, file_with_fake_ident, offset, origin_attr) ) = derive_ctx {
337372 if let Some ( ast:: NameLike :: NameRef ( name_ref) ) =
@@ -389,6 +424,7 @@ impl<'a> CompletionContext<'a> {
389424 return Some ( analysis) ;
390425 }
391426 } ;
427+ ( self . expected_type , self . expected_name ) = self . expected_type_and_name ( & name_like) ;
392428 let analysis = match name_like {
393429 ast:: NameLike :: Lifetime ( lifetime) => CompletionAnalysis :: Lifetime (
394430 Self :: classify_lifetime ( & self . sema , original_file, lifetime) ?,
@@ -1141,19 +1177,6 @@ fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<(ast::Path, bool)> {
11411177 Some ( ( use_tree. path ( ) ?, true ) )
11421178}
11431179
1144- fn has_ref ( token : & SyntaxToken ) -> bool {
1145- let mut token = token. clone ( ) ;
1146- for skip in [ SyntaxKind :: IDENT , SyntaxKind :: WHITESPACE , T ! [ mut ] ] {
1147- if token. kind ( ) == skip {
1148- token = match token. prev_token ( ) {
1149- Some ( it) => it,
1150- None => return false ,
1151- }
1152- }
1153- }
1154- token. kind ( ) == T ! [ & ]
1155- }
1156-
11571180pub ( crate ) fn is_in_token_of_for_loop ( element : SyntaxElement ) -> bool {
11581181 // oh my ...
11591182 ( || {
0 commit comments