aboutsummaryrefslogtreecommitdiff
path: root/crates/ide
diff options
context:
space:
mode:
authorPaul Daniel Faria <[email protected]>2020-09-06 19:34:01 +0100
committerPaul Daniel Faria <[email protected]>2020-09-06 19:34:01 +0100
commita1a7b07ad33b7dcadedc2af26c3a5f8ef3daca27 (patch)
treec41abbdb6dd82b04a232533e824a6b395ccbd3da /crates/ide
parent7af947a032bd2e6f6df6b903b40f142cd7b8d9e0 (diff)
Fix handling of consuming self, refactor shared logic into a single function
Diffstat (limited to 'crates/ide')
-rw-r--r--crates/ide/src/syntax_highlighting.rs62
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlighting.html2
2 files changed, 34 insertions, 30 deletions
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index 4fa9e638a..d9fc25d88 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -4,7 +4,7 @@ mod injection;
4#[cfg(test)] 4#[cfg(test)]
5mod tests; 5mod tests;
6 6
7use hir::{Name, Semantics, VariantDef}; 7use hir::{Local, Name, Semantics, VariantDef};
8use ide_db::{ 8use ide_db::{
9 defs::{classify_name, classify_name_ref, Definition, NameClass, NameRefClass}, 9 defs::{classify_name, classify_name_ref, Definition, NameClass, NameRefClass},
10 RootDatabase, 10 RootDatabase,
@@ -14,7 +14,7 @@ use syntax::{
14 ast::{self, HasFormatSpecifier}, 14 ast::{self, HasFormatSpecifier},
15 AstNode, AstToken, Direction, NodeOrToken, SyntaxElement, 15 AstNode, AstToken, Direction, NodeOrToken, SyntaxElement,
16 SyntaxKind::{self, *}, 16 SyntaxKind::{self, *},
17 SyntaxNode, TextRange, WalkEvent, T, 17 SyntaxNode, SyntaxToken, TextRange, WalkEvent, T,
18}; 18};
19 19
20use crate::FileId; 20use crate::FileId;
@@ -455,7 +455,7 @@ fn macro_call_range(macro_call: &ast::MacroCall) -> Option<TextRange> {
455} 455}
456 456
457/// Returns true if the parent nodes of `node` all match the `SyntaxKind`s in `kinds` exactly. 457/// Returns true if the parent nodes of `node` all match the `SyntaxKind`s in `kinds` exactly.
458fn parents_match(mut node: SyntaxNode, mut kinds: &[SyntaxKind]) -> bool { 458fn parents_match(mut node: NodeOrToken<SyntaxNode, SyntaxToken>, mut kinds: &[SyntaxKind]) -> bool {
459 while let (Some(parent), [kind, rest @ ..]) = (&node.parent(), kinds) { 459 while let (Some(parent), [kind, rest @ ..]) = (&node.parent(), kinds) {
460 if parent.kind() != *kind { 460 if parent.kind() != *kind {
461 return false; 461 return false;
@@ -463,7 +463,7 @@ fn parents_match(mut node: SyntaxNode, mut kinds: &[SyntaxKind]) -> bool {
463 463
464 // FIXME: Would be nice to get parent out of the match, but binding by-move and by-value 464 // FIXME: Would be nice to get parent out of the match, but binding by-move and by-value
465 // in the same pattern is unstable: rust-lang/rust#68354. 465 // in the same pattern is unstable: rust-lang/rust#68354.
466 node = node.parent().unwrap(); 466 node = node.parent().unwrap().into();
467 kinds = rest; 467 kinds = rest;
468 } 468 }
469 469
@@ -471,6 +471,15 @@ fn parents_match(mut node: SyntaxNode, mut kinds: &[SyntaxKind]) -> bool {
471 kinds.len() == 0 471 kinds.len() == 0
472} 472}
473 473
474fn 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
474fn highlight_element( 483fn highlight_element(
475 sema: &Semantics<RootDatabase>, 484 sema: &Semantics<RootDatabase>,
476 bindings_shadow_count: &mut FxHashMap<Name, u32>, 485 bindings_shadow_count: &mut FxHashMap<Name, u32>,
@@ -539,23 +548,9 @@ fn highlight_element(
539 548
540 let mut h = highlight_def(db, def); 549 let mut h = highlight_def(db, def);
541 550
542 // When lvalues are passed as arguments and they're not Copy, then mark 551 if let Definition::Local(local) = &def {
543 // them as Consuming. 552 if is_consumed_lvalue(name_ref.syntax().clone().into(), local, db) {
544 if parents_match( 553 h |= HighlightModifier::Consuming;
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 }
559 } 554 }
560 } 555 }
561 556
@@ -682,21 +677,30 @@ fn highlight_element(
682 .and_then(ast::SelfParam::cast) 677 .and_then(ast::SelfParam::cast)
683 .and_then(|p| p.mut_token()) 678 .and_then(|p| p.mut_token())
684 .is_some(); 679 .is_some();
685 // closure to enforce lazyness 680 let self_path = &element
686 let self_path = || { 681 .parent()
687 sema.resolve_path(&element.parent()?.parent().and_then(ast::Path::cast)?) 682 .as_ref()
688 }; 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 if self_param_is_mut 687 if self_param_is_mut
690 || matches!(self_path(), 688 || matches!(self_path,
691 Some(hir::PathResolution::Local(local)) 689 Some(hir::PathResolution::Local(local))
692 if local.is_self(db) 690 if local.is_self(db)
693 && (local.is_mut(db) || local.ty(db).is_mutable_reference()) 691 && (local.is_mut(db) || local.ty(db).is_mutable_reference())
694 ) 692 )
695 { 693 {
696 HighlightTag::SelfKeyword | HighlightModifier::Mutable 694 h |= HighlightModifier::Mutable
697 } else { 695 }
698 HighlightTag::SelfKeyword.into() 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 T![ref] => element 705 T![ref] => element
702 .parent() 706 .parent()
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
index cade46348..cde42024c 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
@@ -62,7 +62,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
62 62
63<span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span> 63<span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span>
64 <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">Foo</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> 64 <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">Foo</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
65 <span class="value_param">f</span><span class="punctuation">.</span><span class="function consuming">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">)</span> 65 <span class="value_param">f</span><span class="punctuation">.</span><span class="function consuming">baz</span><span class="punctuation">(</span><span class="self_keyword consuming">self</span><span class="punctuation">)</span>
66 <span class="punctuation">}</span> 66 <span class="punctuation">}</span>
67 67
68 <span class="keyword">fn</span> <span class="function declaration">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span> 68 <span class="keyword">fn</span> <span class="function declaration">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span>