@@ -4,8 +4,11 @@ use hir::{Local, ScopeDef, Semantics, SemanticsScope, Type};
44use ide_db:: base_db:: { FilePosition , SourceDatabase } ;
55use ide_db:: { call_info:: ActiveParameter , RootDatabase } ;
66use syntax:: {
7- algo:: find_node_at_offset, ast, match_ast, AstNode , NodeOrToken , SyntaxKind :: * , SyntaxNode ,
8- SyntaxToken , TextRange , TextSize ,
7+ algo:: find_node_at_offset,
8+ ast:: { self , NameOrNameRef , NameOwner } ,
9+ match_ast, AstNode , NodeOrToken ,
10+ SyntaxKind :: * ,
11+ SyntaxNode , SyntaxToken , TextRange , TextSize ,
912} ;
1013
1114use text_edit:: Indel ;
@@ -35,7 +38,7 @@ pub(crate) struct CompletionContext<'a> {
3538 /// The token before the cursor, in the macro-expanded file.
3639 pub ( super ) token : SyntaxToken ,
3740 pub ( super ) krate : Option < hir:: Crate > ,
38- pub ( super ) expected_name : Option < String > ,
41+ pub ( super ) expected_name : Option < NameOrNameRef > ,
3942 pub ( super ) expected_type : Option < Type > ,
4043 pub ( super ) name_ref_syntax : Option < ast:: NameRef > ,
4144 pub ( super ) function_syntax : Option < ast:: Fn > ,
@@ -292,21 +295,21 @@ impl<'a> CompletionContext<'a> {
292295 file_with_fake_ident : SyntaxNode ,
293296 offset : TextSize ,
294297 ) {
295- let expected = {
298+ let ( expected_type , expected_name ) = {
296299 let mut node = match self . token . parent ( ) {
297300 Some ( it) => it,
298301 None => return ,
299302 } ;
300303 loop {
301- let ret = match_ast ! {
304+ break match_ast ! {
302305 match node {
303306 ast:: LetStmt ( it) => {
304307 cov_mark:: hit!( expected_type_let_with_leading_char) ;
305308 cov_mark:: hit!( expected_type_let_without_leading_char) ;
306309 let ty = it. pat( )
307310 . and_then( |pat| self . sema. type_of_pat( & pat) ) ;
308311 let name = if let Some ( ast:: Pat :: IdentPat ( ident) ) = it. pat( ) {
309- Some ( ident. syntax ( ) . text ( ) . to_string ( ) )
312+ ident. name ( ) . map ( NameOrNameRef :: Name )
310313 } else {
311314 None
312315 } ;
@@ -319,18 +322,21 @@ impl<'a> CompletionContext<'a> {
319322 ActiveParameter :: at_token(
320323 & self . sema,
321324 self . token. clone( ) ,
322- ) . map( |ap| ( Some ( ap. ty) , Some ( ap. name) ) )
325+ ) . map( |ap| {
326+ let name = ap. ident( ) . map( NameOrNameRef :: Name ) ;
327+ ( Some ( ap. ty) , name)
328+ } )
323329 . unwrap_or( ( None , None ) )
324330 } ,
325331 ast:: RecordExprFieldList ( _it) => {
326332 cov_mark:: hit!( expected_type_struct_field_without_leading_char) ;
327333 self . token. prev_sibling_or_token( )
328334 . and_then( |se| se. into_node( ) )
329335 . and_then( |node| ast:: RecordExprField :: cast( node) )
330- . and_then( |rf| self . sema. resolve_record_field( & rf) )
331- . map( |f |(
336+ . and_then( |rf| self . sema. resolve_record_field( & rf) . zip ( Some ( rf ) ) )
337+ . map( |( f , rf ) |(
332338 Some ( f. 0 . signature_ty( self . db) ) ,
333- Some ( f . 0 . name ( self . db ) . to_string ( ) ) ,
339+ rf . field_name ( ) . map ( NameOrNameRef :: NameRef ) ,
334340 ) )
335341 . unwrap_or( ( None , None ) )
336342 } ,
@@ -340,7 +346,7 @@ impl<'a> CompletionContext<'a> {
340346 . resolve_record_field( & it)
341347 . map( |f|(
342348 Some ( f. 0 . signature_ty( self . db) ) ,
343- Some ( f . 0 . name ( self . db ) . to_string ( ) ) ,
349+ it . field_name ( ) . map ( NameOrNameRef :: NameRef ) ,
344350 ) )
345351 . unwrap_or( ( None , None ) )
346352 } ,
@@ -378,12 +384,10 @@ impl<'a> CompletionContext<'a> {
378384 } ,
379385 }
380386 } ;
381-
382- break ret;
383387 }
384388 } ;
385- self . expected_type = expected . 0 ;
386- self . expected_name = expected . 1 ;
389+ self . expected_type = expected_type ;
390+ self . expected_name = expected_name ;
387391 self . attribute_under_caret = find_node_at_offset ( & file_with_fake_ident, offset) ;
388392
389393 // First, let's try to complete a reference to some declaration.
@@ -631,7 +635,9 @@ mod tests {
631635 . map ( |t| t. display_test ( & db) . to_string ( ) )
632636 . unwrap_or ( "?" . to_owned ( ) ) ;
633637
634- let name = completion_context. expected_name . unwrap_or ( "?" . to_owned ( ) ) ;
638+ let name = completion_context
639+ . expected_name
640+ . map_or_else ( || "?" . to_owned ( ) , |name| name. to_string ( ) ) ;
635641
636642 expect. assert_eq ( & format ! ( "ty: {}, name: {}" , ty, name) ) ;
637643 }
0 commit comments