@@ -4,7 +4,7 @@ mod injection;
4
4
#[ cfg( test) ]
5
5
mod tests;
6
6
7
- use hir:: { Name , Semantics , VariantDef } ;
7
+ use hir:: { Local , Name , Semantics , VariantDef } ;
8
8
use ide_db:: {
9
9
defs:: { classify_name, classify_name_ref, Definition , NameClass , NameRefClass } ,
10
10
RootDatabase ,
@@ -14,7 +14,7 @@ use syntax::{
14
14
ast:: { self , HasFormatSpecifier } ,
15
15
AstNode , AstToken , Direction , NodeOrToken , SyntaxElement ,
16
16
SyntaxKind :: { self , * } ,
17
- SyntaxNode , TextRange , WalkEvent , T ,
17
+ SyntaxNode , SyntaxToken , TextRange , WalkEvent , T ,
18
18
} ;
19
19
20
20
use crate :: FileId ;
@@ -455,22 +455,31 @@ fn macro_call_range(macro_call: &ast::MacroCall) -> Option<TextRange> {
455
455
}
456
456
457
457
/// 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 {
459
459
while let ( Some ( parent) , [ kind, rest @ ..] ) = ( & node. parent ( ) , kinds) {
460
460
if parent. kind ( ) != * kind {
461
461
return false ;
462
462
}
463
463
464
464
// FIXME: Would be nice to get parent out of the match, but binding by-move and by-value
465
465
// in the same pattern is unstable: rust-lang/rust#68354.
466
- node = node. parent ( ) . unwrap ( ) ;
466
+ node = node. parent ( ) . unwrap ( ) . into ( ) ;
467
467
kinds = rest;
468
468
}
469
469
470
470
// Only true if we matched all expected kinds
471
471
kinds. len ( ) == 0
472
472
}
473
473
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
+
474
483
fn highlight_element (
475
484
sema : & Semantics < RootDatabase > ,
476
485
bindings_shadow_count : & mut FxHashMap < Name , u32 > ,
@@ -539,23 +548,9 @@ fn highlight_element(
539
548
540
549
let mut h = highlight_def ( db, def) ;
541
550
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 ;
559
554
}
560
555
}
561
556
@@ -682,21 +677,30 @@ fn highlight_element(
682
677
. and_then ( ast:: SelfParam :: cast)
683
678
. and_then ( |p| p. mut_token ( ) )
684
679
. 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 ( ) ;
689
687
if self_param_is_mut
690
- || matches ! ( self_path( ) ,
688
+ || matches ! ( self_path,
691
689
Some ( hir:: PathResolution :: Local ( local) )
692
690
if local. is_self( db)
693
691
&& ( local. is_mut( db) || local. ty( db) . is_mutable_reference( ) )
694
692
)
695
693
{
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
+ }
699
701
}
702
+
703
+ h
700
704
}
701
705
T ! [ ref] => element
702
706
. parent ( )
0 commit comments