@@ -4,7 +4,7 @@ mod injection;
44#[ cfg( test) ]
55mod tests;
66
7- use hir:: { Name , Semantics , VariantDef } ;
7+ use hir:: { Local , Name , Semantics , VariantDef } ;
88use ide_db:: {
99 defs:: { classify_name, classify_name_ref, Definition , NameClass , NameRefClass } ,
1010 RootDatabase ,
@@ -14,7 +14,7 @@ use syntax::{
1414 ast:: { self , HasFormatSpecifier } ,
1515 AstNode , AstToken , Direction , NodeOrToken , SyntaxElement ,
1616 SyntaxKind :: { self , * } ,
17- SyntaxNode , TextRange , WalkEvent , T ,
17+ SyntaxNode , SyntaxToken , TextRange , WalkEvent , T ,
1818} ;
1919
2020use crate :: FileId ;
@@ -455,22 +455,31 @@ fn macro_call_range(macro_call: &ast::MacroCall) -> Option<TextRange> {
455455}
456456
457457/// Returns true if the parent nodes of `node` all match the `SyntaxKind`s in `kinds` exactly.
458- fn parents_match ( mut node : SyntaxNode , mut kinds : & [ SyntaxKind ] ) -> bool {
458+ fn parents_match ( mut node : NodeOrToken < SyntaxNode , SyntaxToken > , mut kinds : & [ SyntaxKind ] ) -> bool {
459459 while let ( Some ( parent) , [ kind, rest @ ..] ) = ( & node. parent ( ) , kinds) {
460460 if parent. kind ( ) != * kind {
461461 return false ;
462462 }
463463
464464 // FIXME: Would be nice to get parent out of the match, but binding by-move and by-value
465465 // in the same pattern is unstable: rust-lang/rust#68354.
466- node = node. parent ( ) . unwrap ( ) ;
466+ node = node. parent ( ) . unwrap ( ) . into ( ) ;
467467 kinds = rest;
468468 }
469469
470470 // Only true if we matched all expected kinds
471471 kinds. len ( ) == 0
472472}
473473
474+ fn is_consumed_lvalue (
475+ node : NodeOrToken < SyntaxNode , SyntaxToken > ,
476+ local : & Local ,
477+ db : & RootDatabase ,
478+ ) -> bool {
479+ // When lvalues are passed as arguments and they're not Copy, then mark them as Consuming.
480+ parents_match ( node, & [ PATH_SEGMENT , PATH , PATH_EXPR , ARG_LIST ] ) && !local. ty ( db) . is_copy ( db)
481+ }
482+
474483fn highlight_element (
475484 sema : & Semantics < RootDatabase > ,
476485 bindings_shadow_count : & mut FxHashMap < Name , u32 > ,
@@ -539,23 +548,9 @@ fn highlight_element(
539548
540549 let mut h = highlight_def ( db, def) ;
541550
542- // When lvalues are passed as arguments and they're not Copy, then mark
543- // them as Consuming.
544- if parents_match (
545- name_ref. syntax ( ) . clone ( ) ,
546- & [ PATH_SEGMENT , PATH , PATH_EXPR , ARG_LIST ] ,
547- ) {
548- let lvalue_ty = if let Definition :: Local ( local) = & def {
549- Some ( local. ty ( db) )
550- } else if let Definition :: SelfType ( impl_def) = & def {
551- Some ( impl_def. target_ty ( db) )
552- } else {
553- None
554- } ;
555- if let Some ( lvalue_ty) = lvalue_ty {
556- if !lvalue_ty. is_copy ( db) {
557- h |= HighlightModifier :: Consuming ;
558- }
551+ if let Definition :: Local ( local) = & def {
552+ if is_consumed_lvalue ( name_ref. syntax ( ) . clone ( ) . into ( ) , local, db) {
553+ h |= HighlightModifier :: Consuming ;
559554 }
560555 }
561556
@@ -682,21 +677,30 @@ fn highlight_element(
682677 . and_then ( ast:: SelfParam :: cast)
683678 . and_then ( |p| p. mut_token ( ) )
684679 . is_some ( ) ;
685- // closure to enforce lazyness
686- let self_path = || {
687- sema. resolve_path ( & element. parent ( ) ?. parent ( ) . and_then ( ast:: Path :: cast) ?)
688- } ;
680+ let self_path = & element
681+ . parent ( )
682+ . as_ref ( )
683+ . and_then ( SyntaxNode :: parent)
684+ . and_then ( ast:: Path :: cast)
685+ . and_then ( |p| sema. resolve_path ( & p) ) ;
686+ let mut h = HighlightTag :: SelfKeyword . into ( ) ;
689687 if self_param_is_mut
690- || matches ! ( self_path( ) ,
688+ || matches ! ( self_path,
691689 Some ( hir:: PathResolution :: Local ( local) )
692690 if local. is_self( db)
693691 && ( local. is_mut( db) || local. ty( db) . is_mutable_reference( ) )
694692 )
695693 {
696- HighlightTag :: SelfKeyword | HighlightModifier :: Mutable
697- } else {
698- HighlightTag :: SelfKeyword . into ( )
694+ h |= HighlightModifier :: Mutable
695+ }
696+
697+ if let Some ( hir:: PathResolution :: Local ( local) ) = self_path {
698+ if is_consumed_lvalue ( element, & local, db) {
699+ h |= HighlightModifier :: Consuming ;
700+ }
699701 }
702+
703+ h
700704 }
701705 T ! [ ref] => element
702706 . parent ( )
0 commit comments