about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/source_analyzer.rs54
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlighting.html1
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs1
3 files changed, 23 insertions, 33 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 2d779393f09..233c814809a 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -290,9 +290,7 @@ impl SourceAnalyzer {
                 return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
             }
             prefer_value_ns = true;
-        }
-
-        if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
+        } else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
             let pat_id = self.pat_id(&path_pat.into())?;
             if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) {
                 return Some(PathResolution::AssocItem(assoc.into()));
@@ -302,9 +300,7 @@ impl SourceAnalyzer {
             {
                 return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
             }
-        }
-
-        if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) {
+        } else if let Some(rec_lit) = parent().and_then(ast::RecordExpr::cast) {
             let expr_id = self.expr_id(db, &rec_lit.into())?;
             if let Some(VariantId::EnumVariantId(variant)) =
                 self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
@@ -331,32 +327,34 @@ impl SourceAnalyzer {
         // Case where path is a qualifier of a use tree, e.g. foo::bar::{Baz, Qux} where we are
         // trying to resolve foo::bar.
         if let Some(use_tree) = parent().and_then(ast::UseTree::cast) {
-            if let Some(qualifier) = use_tree.path() {
-                if path == &qualifier && use_tree.coloncolon_token().is_some() {
-                    return resolve_hir_path_qualifier(db, &self.resolver, &hir_path);
-                }
+            if use_tree.coloncolon_token().is_some() {
+                return resolve_hir_path_qualifier(db, &self.resolver, &hir_path);
             }
         }
 
         let is_path_of_attr = path
-            .top_path()
             .syntax()
             .ancestors()
-            .nth(2) // Path -> Meta -> Attr
-            .map_or(false, |it| ast::Attr::can_cast(it.kind()));
+            .map(|it| it.kind())
+            .take_while(|&kind| ast::Path::can_cast(kind) || ast::Meta::can_cast(kind))
+            .last()
+            .map_or(false, ast::Meta::can_cast);
 
         // Case where path is a qualifier of another path, e.g. foo::bar::Baz where we are
         // trying to resolve foo::bar.
-        if let Some(outer_path) = path.parent_path() {
-            if let Some(qualifier) = outer_path.qualifier() {
-                if path == &qualifier {
-                    return resolve_hir_path_qualifier(db, &self.resolver, &hir_path);
+        if path.parent_path().is_some() {
+            return match resolve_hir_path_qualifier(db, &self.resolver, &hir_path) {
+                None if is_path_of_attr => {
+                    path.first_segment().and_then(|it| it.name_ref()).and_then(|name_ref| {
+                        ToolModule::by_name(&name_ref.text()).map(PathResolution::ToolModule)
+                    })
                 }
-            }
+                res => res,
+            };
         } else if is_path_of_attr {
             // Case where we are resolving the final path segment of a path in an attribute
             // in this case we have to check for inert/builtin attributes and tools and prioritize
-            // resolution of attributes over other namesapces
+            // resolution of attributes over other namespaces
             let name_ref = path.as_single_name_ref();
             let builtin =
                 name_ref.as_ref().map(ast::NameRef::text).as_deref().and_then(BuiltinAttr::by_name);
@@ -365,27 +363,17 @@ impl SourceAnalyzer {
             }
             return match resolve_hir_path_as_macro(db, &self.resolver, &hir_path) {
                 res @ Some(m) if m.is_attr() => res.map(PathResolution::Macro),
-                _ => name_ref.and_then(|name_ref| {
+                // this labels any path that starts with a tool module as the tool itself, this is technically wrong
+                // but there is no benefit in differentiating these two cases for the time being
+                _ => path.first_segment().and_then(|it| it.name_ref()).and_then(|name_ref| {
                     ToolModule::by_name(&name_ref.text()).map(PathResolution::ToolModule)
                 }),
             };
         }
-
-        let res = if parent().map_or(false, |it| ast::Visibility::can_cast(it.kind())) {
+        if parent().map_or(false, |it| ast::Visibility::can_cast(it.kind())) {
             resolve_hir_path_qualifier(db, &self.resolver, &hir_path)
         } else {
             resolve_hir_path_(db, &self.resolver, &hir_path, prefer_value_ns)
-        };
-        match res {
-            Some(_) => res,
-            // this labels any path that starts with a tool module as the tool itself, this is technically wrong
-            // but there is no benefit in differentiating these two cases for the time being
-            None if is_path_of_attr => path
-                .first_segment()
-                .and_then(|seg| seg.name_ref())
-                .and_then(|name_ref| ToolModule::by_name(&name_ref.text()))
-                .map(PathResolution::ToolModule),
-            None => None,
         }
     }
 
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
index 1ae07a125f7..3ec6b6a77d3 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
@@ -44,6 +44,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="brace">{</span><span class="brace">}</span>
 
 <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">allow</span><span class="parenthesis attribute">(</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="tool_module attribute library">rustfmt</span><span class="operator attribute">::</span><span class="tool_module attribute library">skip</span><span class="attribute_bracket attribute">]</span>
 <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="module attribute crate_root library">proc_macros</span><span class="operator attribute">::</span><span class="attribute attribute library">identity</span><span class="attribute_bracket attribute">]</span>
 <span class="keyword">pub</span> <span class="keyword">mod</span> <span class="module declaration public">ops</span> <span class="brace">{</span>
     <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">lang</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"fn_once"</span><span class="attribute_bracket attribute">]</span>
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index c5834e19421..4e62edc7c16 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -17,6 +17,7 @@ use inner::{self as inner_mod};
 mod inner {}
 
 #[allow()]
+#[rustfmt::skip]
 #[proc_macros::identity]
 pub mod ops {
     #[lang = "fn_once"]