Repository: rust-analyzer/rust-analyzer
Pull request #10726 (2021-11-08 18:41:56)

minor: Add some completion profile spans
bors r+


Patch:
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index f781e0987a..9c0f3093e1 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -132,8 +132,5 @@ jobs:
         run: npm --prefix ./editors/code test
         # working-directory: ./editors/code  # does not work: https://github.com/GabrielBB/xvfb-action/issues/8
 
-    - run: npm run pretest
-      working-directory: ./editors/code
-
     - run: npm run package --scripts-prepend-node-path
       working-directory: ./editors/code
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index b09c0e753b..0f63de9e72 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -329,10 +329,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
         self.imp.resolve_path(path)
     }
 
-    pub fn resolve_path_as_macro(&self, path: &ast::Path) -> Option<MacroDef> {
-        self.imp.resolve_path_as_macro(path)
-    }
-
     pub fn resolve_extern_crate(&self, extern_crate: &ast::ExternCrate) -> Option<Crate> {
         self.imp.resolve_extern_crate(extern_crate)
     }
@@ -849,12 +845,6 @@ impl<'db> SemanticsImpl<'db> {
         self.analyze(path.syntax()).resolve_path(self.db, path)
     }
 
-    // FIXME: This shouldn't exist, but is currently required to always resolve attribute paths in
-    // the IDE layer due to namespace collisions
-    fn resolve_path_as_macro(&self, path: &ast::Path) -> Option<MacroDef> {
-        self.analyze(path.syntax()).resolve_path_as_macro(self.db, path)
-    }
-
     fn resolve_extern_crate(&self, extern_crate: &ast::ExternCrate) -> Option<Crate> {
         let krate = self.scope(extern_crate.syntax()).krate()?;
         krate.dependencies(self.db).into_iter().find_map(|dep| {
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index b12461818e..08d0a02d79 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -246,18 +246,6 @@ impl SourceAnalyzer {
         }
     }
 
-    pub(crate) fn resolve_path_as_macro(
-        &self,
-        db: &dyn HirDatabase,
-        path: &ast::Path,
-    ) -> Option<MacroDef> {
-        // This must be a normal source file rather than macro file.
-        let hygiene = Hygiene::new(db.upcast(), self.file_id);
-        let ctx = body::LowerCtx::with_hygiene(db.upcast(), &hygiene);
-        let hir_path = Path::from_src(path.clone(), &ctx)?;
-        resolve_hir_path_as_macro(db, &self.resolver, &hir_path)
-    }
-
     pub(crate) fn resolve_path(
         &self,
         db: &dyn HirDatabase,
diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs
index 825fae587b..a84f0b334b 100644
--- a/crates/ide_completion/src/completions/unqualified_path.rs
+++ b/crates/ide_completion/src/completions/unqualified_path.rs
@@ -6,6 +6,7 @@ use syntax::{ast, AstNode};
 use crate::{patterns::ImmediateLocation, CompletionContext, Completions};
 
 pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
+    let _p = profile::span("complete_unqualified_path");
     if ctx.is_path_disallowed() || !ctx.is_trivial_path() || ctx.has_impl_or_trait_prev_sibling() {
         return;
     }
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index ac01968126..3f40260d33 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -353,6 +353,7 @@ impl<'a> CompletionContext<'a> {
         position: FilePosition,
         config: &'a CompletionConfig,
     ) -> Option<CompletionContext<'a>> {
+        let _p = profile::span("CompletionContext::new");
         let sema = Semantics::new(db);
 
         let original_file = sema.parse(position.file_id);
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 5ae52f3cc9..a1d4eb998f 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -16,7 +16,7 @@ use ide_db::{
     helpers::{item_name, SnippetCap},
     RootDatabase, SymbolKind,
 };
-use syntax::{SyntaxKind, TextRange};
+use syntax::{SmolStr, SyntaxKind, TextRange};
 
 use crate::{
     context::{PathCompletionContext, PathKind},
@@ -243,7 +243,7 @@ fn render_resolution_(
             if has_non_default_type_params {
                 cov_mark::hit!(inserts_angle_brackets_for_generics);
                 item.lookup_by(local_name.clone())
-                    .label(format!("{}<…>", local_name))
+                    .label(SmolStr::from_iter([&local_name, "<…>"]))
                     .insert_snippet(cap, format!("{}<$0>", local_name));
             }
         }
diff --git a/crates/ide_completion/src/render/const_.rs b/crates/ide_completion/src/render/const_.rs
index 707b6533b5..c40490ac0b 100644
--- a/crates/ide_completion/src/render/const_.rs
+++ b/crates/ide_completion/src/render/const_.rs
@@ -7,6 +7,7 @@ use syntax::{ast::Const, display::const_label};
 use crate::{item::CompletionItem, render::RenderContext};
 
 pub(crate) fn render_const(ctx: RenderContext<'_>, const_: hir::Const) -> Option<CompletionItem> {
+    let _p = profile::span("render_const");
     ConstRender::new(ctx, const_)?.render()
 }
 
diff --git a/crates/ide_completion/src/render/macro_.rs b/crates/ide_completion/src/render/macro_.rs
index 1f76583adb..090bb5a715 100644
--- a/crates/ide_completion/src/render/macro_.rs
+++ b/crates/ide_completion/src/render/macro_.rs
@@ -40,7 +40,7 @@ impl<'a> MacroRender<'a> {
         MacroRender { ctx, name, macro_, docs, bra, ket }
     }
 
-    fn render(&self, import_to_add: Option<ImportEdit>) -> Option<CompletionItem> {
+    fn render(self, import_to_add: Option<ImportEdit>) -> Option<CompletionItem> {
         let source_range = if self.ctx.completion.is_immediately_after_macro_bang() {
             cov_mark::hit!(completes_macro_call_if_cursor_at_bang_token);
             self.ctx.completion.token.parent().map(|it| it.text_range())
@@ -48,9 +48,7 @@ impl<'a> MacroRender<'a> {
             Some(self.ctx.source_range())
         }?;
         let mut item = CompletionItem::new(SymbolKind::Macro, source_range, self.label());
-        item.set_documentation(self.docs.clone())
-            .set_deprecated(self.ctx.is_deprecated(self.macro_))
-            .set_detail(self.detail());
+        item.set_deprecated(self.ctx.is_deprecated(self.macro_)).set_detail(self.detail());
 
         if let Some(import_to_add) = import_to_add {
             item.add_import(import_to_add);
@@ -76,6 +74,7 @@ impl<'a> MacroRender<'a> {
             }
         };
 
+        item.set_documentation(self.docs);
         Some(item.build())
     }
 
diff --git a/crates/ide_completion/src/render/type_alias.rs b/crates/ide_completion/src/render/type_alias.rs
index 6e6c1204b2..259fe25a6c 100644
--- a/crates/ide_completion/src/render/type_alias.rs
+++ b/crates/ide_completion/src/render/type_alias.rs
@@ -13,6 +13,7 @@ pub(crate) fn render_type_alias(
     ctx: RenderContext<'_>,
     type_alias: hir::TypeAlias,
 ) -> Option<CompletionItem> {
+    let _p = profile::span("render_type_alias");
     TypeAliasRender::new(ctx, type_alias)?.render(false)
 }
 
@@ -20,6 +21,7 @@ pub(crate) fn render_type_alias_with_eq(
     ctx: RenderContext<'_>,
     type_alias: hir::TypeAlias,
 ) -> Option<CompletionItem> {
+    let _p = profile::span("render_type_alias_with_eq");
     TypeAliasRender::new(ctx, type_alias)?.render(true)
 }
 
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs
index e4874c7c48..d95bca515f 100644
--- a/crates/ide_db/src/defs.rs
+++ b/crates/ide_db/src/defs.rs
@@ -433,20 +433,20 @@ impl NameRefClass {
                 .find_map(ast::Attr::cast)
                 .map(|attr| attr.path().as_ref() == Some(&top_path));
             return match is_attribute_path {
-                Some(true) if path == top_path => sema
-                    .resolve_path_as_macro(&path)
-                    .filter(|mac| mac.kind() == hir::MacroKind::Attr)
-                    .map(Definition::Macro)
-                    .map(NameRefClass::Definition),
-                // in case of the path being a qualifier, don't resolve to anything but a module
-                Some(true) => match sema.resolve_path(&path)? {
-                    PathResolution::Def(module @ ModuleDef::Module(_)) => {
-                        cov_mark::hit!(name_ref_classify_attr_path_qualifier);
-                        Some(NameRefClass::Definition(Definition::ModuleDef(module)))
+                Some(true) => sema.resolve_path(&path).and_then(|resolved| {
+                    match resolved {
+                        // Don't wanna collide with builtin attributes here like `test` hence guard
+                        // so only resolve to modules that aren't the last segment
+                        PathResolution::Def(module @ ModuleDef::Module(_)) if path != top_path => {
+                            cov_mark::hit!(name_ref_classify_attr_path_qualifier);
+                            Some(NameRefClass::Definition(Definition::ModuleDef(module)))
+                        }
+                        PathResolution::Macro(mac) if mac.kind() == hir::MacroKind::Attr => {
+                            Some(NameRefClass::Definition(Definition::Macro(mac)))
+                        }
+                        _ => None,
                     }
-                    _ => None,
-                },
-                // inside attribute, but our path isn't part of the attribute's path(might be in its expression only)
+                }),
                 Some(false) => None,
                 None => sema.resolve_path(&path).map(Into::into).map(NameRefClass::Definition),
             };
diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json
index e3372574b3..0b226a985d 100644
--- a/editors/code/package-lock.json
+++ b/editors/code/package-lock.json
@@ -28,7 +28,7 @@
                 "glob": "^7.1.6",
                 "mocha": "^9.0.2",
                 "tslib": "^2.3.0",
-                "typescript": "^4.4.4",
+                "typescript": "^4.3.5",
                 "typescript-formatter": "^7.2.2",
                 "vsce": "^1.95.1",
                 "vscode-test": "^1.5.1"
@@ -3541,9 +3541,9 @@
             }
         },
         "node_modules/typescript": {
-            "version": "4.4.4",
-            "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz",
-            "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==",
+            "version": "4.3.5",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
+            "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
             "dev": true,
             "bin": {
                 "tsc": "bin/tsc",
@@ -6647,9 +6647,9 @@
             }
         },
         "typescript": {
-            "version": "4.4.4",
-            "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz",
-            "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==",
+            "version": "4.3.5",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
+            "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
             "dev": true
         },
         "typescript-formatter": {
diff --git a/editors/code/package.json b/editors/code/package.json
index 4c718f0b79..336081e88c 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -32,7 +32,7 @@
         "watch": "npm run build-base -- --sourcemap --watch",
         "lint": "tsfmt --verify && eslint -c .eslintrc.js --ext ts ./src ./tests",
         "fix": " tsfmt -r       && eslint -c .eslintrc.js --ext ts ./src ./tests --fix",
-        "pretest": "tsc --noEmit && npm run build",
+        "pretest": "tsc && npm run build",
         "test": "node ./out/tests/runTests.js"
     },
     "dependencies": {
diff --git a/editors/code/tsconfig.json b/editors/code/tsconfig.json
index 7c4fbd21eb..c9f348241a 100644
--- a/editors/code/tsconfig.json
+++ b/editors/code/tsconfig.json
@@ -9,7 +9,6 @@
         "sourceMap": true,
         "rootDir": ".",
         "strict": true,
-        "useUnknownInCatchVariables": false,
         "noUnusedLocals": true,
         "noUnusedParameters": true,
         "noImplicitReturns": true,


Test patch:
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
index ab810aceca..1a10a78d24 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
@@ -43,7 +43,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <pre><code><span class="keyword">use</span> <span class="module">inner</span><span class="operator">::</span><span class="brace">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="module declaration">inner_mod</span><span class="brace">}</span><span class="semicolon">;</span>
 <span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="brace">{</span><span class="brace">}</span>
 
-<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="module attribute">proc_macros</span><span class="operator attribute">::</span><span class="macro attribute">identity</span><span class="attribute attribute">]</span>
+<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="module attribute">proc_macros</span><span class="operator attribute">::</span><span class="builtin_attr attribute">identity</span><span class="attribute 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 attribute">#</span><span class="attribute attribute">[</span><span class="builtin_attr attribute">lang</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"fn_once"</span><span class="attribute attribute">]</span>
     <span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration public">FnOnce</span><span class="angle">&lt;</span><span class="type_param declaration">Args</span><span class="angle">&gt;</span> <span class="brace">{</span><span class="brace">}</span>