about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs27
-rw-r--r--crates/ra_ide/src/syntax_highlighting/tests.rs10
-rw-r--r--crates/ra_ide/test_data/highlighting.html10
3 files changed, 44 insertions, 3 deletions
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index 5bb6f96422c..b3236e82107 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -566,10 +566,31 @@ fn highlight_element(
                 | T![return]
                 | T![while]
                 | T![in] => h | HighlightModifier::ControlFlow,
-                T![for] if !is_child_of_impl(element) => h | HighlightModifier::ControlFlow,
+                T![for] if !is_child_of_impl(&element) => h | HighlightModifier::ControlFlow,
                 T![unsafe] => h | HighlightModifier::Unsafe,
                 T![true] | T![false] => HighlightTag::BoolLiteral.into(),
-                T![self] => HighlightTag::SelfKeyword.into(),
+                T![self] => {
+                    let self_param_is_mut = element
+                        .parent()
+                        .and_then(ast::SelfParam::cast)
+                        .and_then(|p| p.mut_token())
+                        .is_some();
+                    // closure to enforce lazyness
+                    let self_path = || {
+                        sema.resolve_path(&element.parent()?.parent().and_then(ast::Path::cast)?)
+                    };
+                    if self_param_is_mut
+                        || matches!(self_path(),
+                            Some(hir::PathResolution::Local(local))
+                                if local.is_self(db)
+                                    && (local.is_mut(db) || local.ty(db).is_mutable_reference())
+                        )
+                    {
+                        HighlightTag::SelfKeyword | HighlightModifier::Mutable
+                    } else {
+                        HighlightTag::SelfKeyword.into()
+                    }
+                }
                 _ => h,
             }
         }
@@ -592,7 +613,7 @@ fn highlight_element(
     }
 }
 
-fn is_child_of_impl(element: SyntaxElement) -> bool {
+fn is_child_of_impl(element: &SyntaxElement) -> bool {
     match element.parent() {
         Some(e) => e.kind() == IMPL_DEF,
         _ => false,
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs
index aa7c887d674..87a6e2523b8 100644
--- a/crates/ra_ide/src/syntax_highlighting/tests.rs
+++ b/crates/ra_ide/src/syntax_highlighting/tests.rs
@@ -25,6 +25,16 @@ impl Bar for Foo {
     }
 }
 
+impl Foo {
+    fn baz(mut self) -> i32 {
+        self.x
+    }
+
+    fn qux(&mut self) {
+        self.x = 0;
+    }
+}
+
 static mut STATIC_MUT: i32 = 0;
 
 fn foo<'a, T>() -> T {
diff --git a/crates/ra_ide/test_data/highlighting.html b/crates/ra_ide/test_data/highlighting.html
index 134743c72c8..553811a2f2e 100644
--- a/crates/ra_ide/test_data/highlighting.html
+++ b/crates/ra_ide/test_data/highlighting.html
@@ -51,6 +51,16 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     }
 }
 
+<span class="keyword">impl</span> <span class="struct">Foo</span> {
+    <span class="keyword">fn</span> <span class="function declaration">baz</span>(<span class="keyword">mut</span> <span class="self_keyword mutable">self</span>) -&gt; <span class="builtin_type">i32</span> {
+        <span class="self_keyword">self</span>.<span class="field">x</span>
+    }
+
+    <span class="keyword">fn</span> <span class="function declaration">qux</span>(&<span class="keyword">mut</span> <span class="self_keyword mutable">self</span>) {
+        <span class="self_keyword mutable">self</span>.<span class="field">x</span> = <span class="numeric_literal">0</span>;
+    }
+}
+
 <span class="keyword">static</span> <span class="keyword">mut</span> <span class="static declaration mutable">STATIC_MUT</span>: <span class="builtin_type">i32</span> = <span class="numeric_literal">0</span>;
 
 <span class="keyword">fn</span> <span class="function declaration">foo</span>&lt;<span class="lifetime declaration">'a</span>, <span class="type_param declaration">T</span>&gt;() -&gt; <span class="type_param">T</span> {