Repository: rust-lang/rust-analyzer (Rust)

Issue:
Renamed self module is marked as unresolved reference in semantic highlighting
RA marks `inner_mod` in the following code as an `unresolved_reference`, when it should be `module`.
```rust
use crate::inner::{self as inner_mod};
mod inner {}
```


Discussion:

Patch:
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs
index 66c0487141b4..b51000b03fb9 100644
--- a/crates/ra_ide_db/src/defs.rs
+++ b/crates/ra_ide_db/src/defs.rs
@@ -12,7 +12,7 @@ use hir::{
 use ra_prof::profile;
 use ra_syntax::{
     ast::{self, AstNode},
-    match_ast,
+    match_ast, SyntaxNode,
 };
 
 use crate::RootDatabase;
@@ -123,8 +123,27 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option
                 let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?;
                 let path = use_tree.path()?;
                 let path_segment = path.segment()?;
-                let name_ref = path_segment.name_ref()?;
-                let name_ref_class = classify_name_ref(sema, &name_ref)?;
+                let name_ref_class = path_segment
+                    .name_ref()
+                    // The rename might be from a `self` token, so fallback to the name higher
+                    // in the use tree.
+                    .or_else(||{
+                        if path_segment.self_token().is_none() {
+                            return None;
+                        }
+
+                        let use_tree = use_tree
+                            .syntax()
+                            .parent()
+                            .as_ref()
+                            // Skip over UseTreeList
+                            .and_then(SyntaxNode::parent)
+                            .and_then(ast::UseTree::cast)?;
+                        let path = use_tree.path()?;
+                        let path_segment = path.segment()?;
+                        path_segment.name_ref()
+                    })
+                    .and_then(|name_ref| classify_name_ref(sema, &name_ref))?;
 
                 Some(NameClass::Definition(name_ref_class.definition()))
             },


Test patch:
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs
index 87a6e2523b88..2deee404ccc4 100644
--- a/crates/ra_ide/src/syntax_highlighting/tests.rs
+++ b/crates/ra_ide/src/syntax_highlighting/tests.rs
@@ -9,6 +9,9 @@ use crate::{mock_analysis::single_file, FileRange, TextRange};
 fn test_highlighting() {
     check_highlighting(
         r#"
+use inner::{self as inner_mod};
+mod inner {}
+
 #[derive(Clone, Debug)]
 struct Foo {
     pub x: i32,
diff --git a/crates/ra_ide/test_data/highlighting.html b/crates/ra_ide/test_data/highlighting.html
index 345a2f0231f2..23c25ad8cee6 100644
--- a/crates/ra_ide/test_data/highlighting.html
+++ b/crates/ra_ide/test_data/highlighting.html
@@ -35,7 +35,10 @@
 
 .unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
 </style>
-<pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Clone</span><span class="punctuation">,</span><span class="attribute"> Debug</span><span class="punctuation">)</span><span class="attribute">]</span>
+<pre><code><span class="keyword">use</span> <span class="module">inner</span><span class="operator">::</span><span class="punctuation">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="module declaration">inner_mod</span><span class="punctuation">}</span><span class="punctuation">;</span>
+<span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="punctuation">{</span><span class="punctuation">}</span>
+
+<span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Clone</span><span class="punctuation">,</span><span class="attribute"> Debug</span><span class="punctuation">)</span><span class="attribute">]</span>
 <span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span>
     <span class="keyword">pub</span> <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span>
     <span class="keyword">pub</span> <span class="field declaration">y</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span>