about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/ide-completion/src/completions.rs52
-rw-r--r--crates/ide-completion/src/completions/attribute.rs8
-rw-r--r--crates/ide-completion/src/completions/attribute/derive.rs8
-rw-r--r--crates/ide-completion/src/completions/expr.rs2
-rw-r--r--crates/ide-completion/src/completions/flyimport.rs66
-rw-r--r--crates/ide-completion/src/completions/item_list.rs8
-rw-r--r--crates/ide-completion/src/completions/pattern.rs21
-rw-r--r--crates/ide-completion/src/completions/type.rs2
-rw-r--r--crates/ide-completion/src/completions/use_.rs4
-rw-r--r--crates/ide-completion/src/completions/vis.rs4
-rw-r--r--crates/ide-completion/src/render.rs159
-rw-r--r--crates/ide-completion/src/render/macro_.rs23
12 files changed, 235 insertions, 122 deletions
diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs
index 4f522ee7613..750b0222593 100644
--- a/crates/ide-completion/src/completions.rs
+++ b/crates/ide-completion/src/completions.rs
@@ -36,9 +36,9 @@ use crate::{
         const_::render_const,
         function::{render_fn, render_method},
         literal::{render_struct_literal, render_variant_lit},
-        macro_::render_macro,
+        macro_::{render_macro, render_macro_pat},
         pattern::{render_struct_pat, render_variant_pat},
-        render_field, render_path_resolution, render_resolution_simple, render_tuple_field,
+        render_field, render_path_resolution, render_pattern_resolution, render_tuple_field,
         type_alias::{render_type_alias, render_type_alias_with_eq},
         union_literal::render_union_literal,
         RenderContext,
@@ -134,10 +134,14 @@ impl Completions {
         item.add_to(self);
     }
 
-    pub(crate) fn add_crate_roots(&mut self, ctx: &CompletionContext) {
+    pub(crate) fn add_crate_roots(
+        &mut self,
+        ctx: &CompletionContext,
+        path_ctx: &PathCompletionCtx,
+    ) {
         ctx.process_all_names(&mut |name, res| match res {
             ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root(ctx.db) => {
-                self.add_module(ctx, m, name);
+                self.add_module(ctx, path_ctx, m, name);
             }
             _ => (),
         });
@@ -160,25 +164,36 @@ impl Completions {
         );
     }
 
-    pub(crate) fn add_resolution_simple(
+    pub(crate) fn add_pattern_resolution(
         &mut self,
         ctx: &CompletionContext,
+        pattern_ctx: &PatternContext,
         local_name: hir::Name,
         resolution: hir::ScopeDef,
     ) {
         if ctx.is_scope_def_hidden(resolution) {
+            cov_mark::hit!(qualified_path_doc_hidden);
             return;
         }
-        self.add(render_resolution_simple(RenderContext::new(ctx), local_name, resolution).build());
+        self.add(
+            render_pattern_resolution(RenderContext::new(ctx), pattern_ctx, local_name, resolution)
+                .build(),
+        );
     }
 
     pub(crate) fn add_module(
         &mut self,
         ctx: &CompletionContext,
+        path_ctx: &PathCompletionCtx,
         module: hir::Module,
         local_name: hir::Name,
     ) {
-        self.add_resolution_simple(ctx, local_name, hir::ScopeDef::ModuleDef(module.into()));
+        self.add_path_resolution(
+            ctx,
+            path_ctx,
+            local_name,
+            hir::ScopeDef::ModuleDef(module.into()),
+        );
     }
 
     pub(crate) fn add_macro(
@@ -204,6 +219,29 @@ impl Completions {
         );
     }
 
+    pub(crate) fn add_macro_pat(
+        &mut self,
+        ctx: &CompletionContext,
+        pattern_ctx: &PatternContext,
+        mac: hir::Macro,
+        local_name: hir::Name,
+    ) {
+        let is_private_editable = match ctx.is_visible(&mac) {
+            Visible::Yes => false,
+            Visible::Editable => true,
+            Visible::No => return,
+        };
+        self.add(
+            render_macro_pat(
+                RenderContext::new(ctx).private_editable(is_private_editable),
+                pattern_ctx,
+                local_name,
+                mac,
+            )
+            .build(),
+        );
+    }
+
     pub(crate) fn add_function(
         &mut self,
         ctx: &CompletionContext,
diff --git a/crates/ide-completion/src/completions/attribute.rs b/crates/ide-completion/src/completions/attribute.rs
index 1c4f9a3113d..154c096f4d5 100644
--- a/crates/ide-completion/src/completions/attribute.rs
+++ b/crates/ide-completion/src/completions/attribute.rs
@@ -95,7 +95,7 @@ pub(crate) fn complete_attribute_path(
                         acc.add_macro(ctx, path_ctx, m, name)
                     }
                     hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
-                        acc.add_module(ctx, m, name)
+                        acc.add_module(ctx, path_ctx, m, name)
                     }
                     _ => (),
                 }
@@ -103,14 +103,16 @@ pub(crate) fn complete_attribute_path(
             return;
         }
         // fresh use tree with leading colon2, only show crate roots
-        Qualified::Absolute => acc.add_crate_roots(ctx),
+        Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
         // only show modules in a fresh UseTree
         Qualified::No => {
             ctx.process_all_names(&mut |name, def| match def {
                 hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_attr(ctx.db) => {
                     acc.add_macro(ctx, path_ctx, m, name)
                 }
-                hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => acc.add_module(ctx, m, name),
+                hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
+                    acc.add_module(ctx, path_ctx, m, name)
+                }
                 _ => (),
             });
             acc.add_nameref_keywords_with_colon(ctx);
diff --git a/crates/ide-completion/src/completions/attribute/derive.rs b/crates/ide-completion/src/completions/attribute/derive.rs
index 21298b6ca5d..48eb76029ff 100644
--- a/crates/ide-completion/src/completions/attribute/derive.rs
+++ b/crates/ide-completion/src/completions/attribute/derive.rs
@@ -35,12 +35,14 @@ pub(crate) fn complete_derive_path(
                     {
                         acc.add_macro(ctx, path_ctx, mac, name)
                     }
-                    ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => acc.add_module(ctx, m, name),
+                    ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
+                        acc.add_module(ctx, path_ctx, m, name)
+                    }
                     _ => (),
                 }
             }
         }
-        Qualified::Absolute => acc.add_crate_roots(ctx),
+        Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
         // only show modules in a fresh UseTree
         Qualified::No => {
             ctx.process_all_names(&mut |name, def| {
@@ -51,7 +53,7 @@ pub(crate) fn complete_derive_path(
                         mac
                     }
                     ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
-                        return acc.add_module(ctx, m, name);
+                        return acc.add_module(ctx, path_ctx, m, name);
                     }
                     _ => return,
                 };
diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs
index 9c003be6af4..6b36801205a 100644
--- a/crates/ide-completion/src/completions/expr.rs
+++ b/crates/ide-completion/src/completions/expr.rs
@@ -152,7 +152,7 @@ pub(crate) fn complete_expr_path(
                 _ => (),
             }
         }
-        Qualified::Absolute => acc.add_crate_roots(ctx),
+        Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
         Qualified::No => {
             acc.add_nameref_keywords_with_colon(ctx);
             if let Some(adt) =
diff --git a/crates/ide-completion/src/completions/flyimport.rs b/crates/ide-completion/src/completions/flyimport.rs
index 101784fc14c..fa8c0eb77ac 100644
--- a/crates/ide-completion/src/completions/flyimport.rs
+++ b/crates/ide-completion/src/completions/flyimport.rs
@@ -12,7 +12,7 @@ use crate::{
         CompletionContext, DotAccess, PathCompletionCtx, PathKind, PatternContext, Qualified,
         TypeLocation,
     },
-    render::{render_resolution_with_import, RenderContext},
+    render::{render_resolution_with_import, render_resolution_with_import_pat, RenderContext},
 };
 
 use super::Completions;
@@ -149,32 +149,22 @@ pub(crate) fn import_on_the_fly_path(
 pub(crate) fn import_on_the_fly_pat(
     acc: &mut Completions,
     ctx: &CompletionContext,
-    pat_ctx: &PatternContext,
+    pattern_ctx: &PatternContext,
 ) -> Option<()> {
     if !ctx.config.enable_imports_on_the_fly {
         return None;
     }
-    if let PatternContext { record_pat: Some(_), .. } = pat_ctx {
+    if let PatternContext { record_pat: Some(_), .. } = pattern_ctx {
         return None;
     }
 
     let potential_import_name = import_name(ctx);
     let import_assets = import_assets_for_path(ctx, &potential_import_name, None)?;
 
-    import_on_the_fly(
+    import_on_the_fly_pat2(
         acc,
         ctx,
-        &PathCompletionCtx {
-            has_call_parens: false,
-            has_macro_bang: false,
-            qualified: Qualified::No,
-            parent: None,
-            // FIXME
-            path: syntax::ast::make::ext::ident_path("dummy__"),
-            kind: crate::context::PathKind::Pat { pat_ctx: pat_ctx.clone() },
-            has_type_args: false,
-            use_tree_parent: false,
-        },
+        pattern_ctx,
         import_assets,
         ctx.original_token.parent()?,
         potential_import_name,
@@ -289,6 +279,50 @@ fn import_on_the_fly(
     Some(())
 }
 
+fn import_on_the_fly_pat2(
+    acc: &mut Completions,
+    ctx: &CompletionContext,
+    pattern_ctx: &PatternContext,
+    import_assets: ImportAssets,
+    position: SyntaxNode,
+    potential_import_name: String,
+) -> Option<()> {
+    let _p = profile::span("import_on_the_fly_pat").detail(|| potential_import_name.clone());
+
+    if ImportScope::find_insert_use_container(&position, &ctx.sema).is_none() {
+        return None;
+    }
+
+    let ns_filter = |import: &LocatedImport| match import.original_item {
+        ItemInNs::Macros(mac) => mac.is_fn_like(ctx.db),
+        ItemInNs::Types(_) => true,
+        ItemInNs::Values(def) => matches!(def, hir::ModuleDef::Const(_)),
+    };
+    let user_input_lowercased = potential_import_name.to_lowercase();
+
+    acc.add_all(
+        import_assets
+            .search_for_imports(&ctx.sema, ctx.config.insert_use.prefix_kind)
+            .into_iter()
+            .filter(ns_filter)
+            .filter(|import| {
+                !ctx.is_item_hidden(&import.item_to_import)
+                    && !ctx.is_item_hidden(&import.original_item)
+            })
+            .sorted_by_key(|located_import| {
+                compute_fuzzy_completion_order_key(
+                    &located_import.import_path,
+                    &user_input_lowercased,
+                )
+            })
+            .filter_map(|import| {
+                render_resolution_with_import_pat(RenderContext::new(ctx), pattern_ctx, import)
+            })
+            .map(|builder| builder.build()),
+    );
+    Some(())
+}
+
 fn import_on_the_fly_method(
     acc: &mut Completions,
     ctx: &CompletionContext,
@@ -297,7 +331,7 @@ fn import_on_the_fly_method(
     position: SyntaxNode,
     potential_import_name: String,
 ) -> Option<()> {
-    let _p = profile::span("import_on_the_fly").detail(|| potential_import_name.clone());
+    let _p = profile::span("import_on_the_fly_method").detail(|| potential_import_name.clone());
 
     if ImportScope::find_insert_use_container(&position, &ctx.sema).is_none() {
         return None;
diff --git a/crates/ide-completion/src/completions/item_list.rs b/crates/ide-completion/src/completions/item_list.rs
index 329d08a9e76..4a32e0ebf58 100644
--- a/crates/ide-completion/src/completions/item_list.rs
+++ b/crates/ide-completion/src/completions/item_list.rs
@@ -45,7 +45,7 @@ pub(crate) fn complete_item_list(
                         acc.add_macro(ctx, path_ctx, m, name)
                     }
                     hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
-                        acc.add_module(ctx, m, name)
+                        acc.add_module(ctx, path_ctx, m, name)
                     }
                     _ => (),
                 }
@@ -55,13 +55,15 @@ pub(crate) fn complete_item_list(
                 acc.add_keyword(ctx, "super::");
             }
         }
-        Qualified::Absolute => acc.add_crate_roots(ctx),
+        Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
         Qualified::No if ctx.qualifier_ctx.none() => {
             ctx.process_all_names(&mut |name, def| match def {
                 hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_fn_like(ctx.db) => {
                     acc.add_macro(ctx, path_ctx, m, name)
                 }
-                hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => acc.add_module(ctx, m, name),
+                hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
+                    acc.add_module(ctx, path_ctx, m, name)
+                }
                 _ => (),
             });
             acc.add_nameref_keywords_with_colon(ctx);
diff --git a/crates/ide-completion/src/completions/pattern.rs b/crates/ide-completion/src/completions/pattern.rs
index 67dbbf2a29c..4ea80a50777 100644
--- a/crates/ide-completion/src/completions/pattern.rs
+++ b/crates/ide-completion/src/completions/pattern.rs
@@ -82,22 +82,7 @@ pub(crate) fn complete_pattern(
                 hir::ModuleDef::Const(..) => refutable,
                 hir::ModuleDef::Module(..) => true,
                 hir::ModuleDef::Macro(mac) if mac.is_fn_like(ctx.db) => {
-                    return acc.add_macro(
-                        ctx,
-                        &PathCompletionCtx {
-                            has_call_parens: false,
-                            has_macro_bang: false,
-                            qualified: Qualified::No,
-                            // FIXME
-                            path: syntax::ast::make::ext::ident_path("dummy__"),
-                            parent: None,
-                            kind: crate::context::PathKind::Pat { pat_ctx: pattern_ctx.clone() },
-                            has_type_args: false,
-                            use_tree_parent: false,
-                        },
-                        mac,
-                        name,
-                    );
+                    return acc.add_macro_pat(ctx, pattern_ctx, mac, name);
                 }
                 _ => false,
             },
@@ -118,7 +103,7 @@ pub(crate) fn complete_pattern(
             | ScopeDef::Unknown => false,
         };
         if add_simple_path {
-            acc.add_resolution_simple(ctx, name, res);
+            acc.add_pattern_resolution(ctx, pattern_ctx, name, res);
         }
     });
 }
@@ -207,7 +192,7 @@ pub(crate) fn complete_pattern_path(
             }
         }
         // qualifier can only be none here if we are in a TuplePat or RecordPat in which case special characters have to follow the path
-        Qualified::Absolute => acc.add_crate_roots(ctx),
+        Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
         Qualified::No => {
             ctx.process_all_names(&mut |name, res| {
                 // FIXME: properly filter here
diff --git a/crates/ide-completion/src/completions/type.rs b/crates/ide-completion/src/completions/type.rs
index dea0c701b84..c5b65d36ae8 100644
--- a/crates/ide-completion/src/completions/type.rs
+++ b/crates/ide-completion/src/completions/type.rs
@@ -141,7 +141,7 @@ pub(crate) fn complete_type_path(
                 _ => (),
             }
         }
-        Qualified::Absolute => acc.add_crate_roots(ctx),
+        Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
         Qualified::No => {
             acc.add_nameref_keywords_with_colon(ctx);
             if let TypeLocation::TypeBound = location {
diff --git a/crates/ide-completion/src/completions/use_.rs b/crates/ide-completion/src/completions/use_.rs
index 2c039d50189..c98590f1361 100644
--- a/crates/ide-completion/src/completions/use_.rs
+++ b/crates/ide-completion/src/completions/use_.rs
@@ -89,7 +89,7 @@ pub(crate) fn complete_use_path(
         // fresh use tree with leading colon2, only show crate roots
         Qualified::Absolute => {
             cov_mark::hit!(use_tree_crate_roots_only);
-            acc.add_crate_roots(ctx);
+            acc.add_crate_roots(ctx, path_ctx);
         }
         // only show modules and non-std enum in a fresh UseTree
         Qualified::No => {
@@ -97,7 +97,7 @@ pub(crate) fn complete_use_path(
             ctx.process_all_names(&mut |name, res| {
                 match res {
                     ScopeDef::ModuleDef(hir::ModuleDef::Module(module)) => {
-                        acc.add_module(ctx, module, name);
+                        acc.add_module(ctx, path_ctx, module, name);
                     }
                     ScopeDef::ModuleDef(hir::ModuleDef::Adt(hir::Adt::Enum(e))) => {
                         // exclude prelude enum
diff --git a/crates/ide-completion/src/completions/vis.rs b/crates/ide-completion/src/completions/vis.rs
index 30de0e94f7a..6621aafe4bd 100644
--- a/crates/ide-completion/src/completions/vis.rs
+++ b/crates/ide-completion/src/completions/vis.rs
@@ -8,7 +8,7 @@ use crate::{
 pub(crate) fn complete_vis_path(
     acc: &mut Completions,
     ctx: &CompletionContext,
-    PathCompletionCtx { qualified, .. }: &PathCompletionCtx,
+    path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx,
     &has_in_token: &bool,
 ) {
     match qualified {
@@ -23,7 +23,7 @@ pub(crate) fn complete_vis_path(
             if let Some(next) = next_towards_current {
                 if let Some(name) = next.name(ctx.db) {
                     cov_mark::hit!(visibility_qualified);
-                    acc.add_module(ctx, next, name);
+                    acc.add_module(ctx, path_ctx, next, name);
                 }
             }
 
diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs
index 643f34b22e5..c29a50dd632 100644
--- a/crates/ide-completion/src/render.rs
+++ b/crates/ide-completion/src/render.rs
@@ -17,9 +17,13 @@ use ide_db::{
 use syntax::{AstNode, SmolStr, SyntaxKind, TextRange};
 
 use crate::{
-    context::{PathCompletionCtx, PathKind},
+    context::{PathCompletionCtx, PathKind, PatternContext},
     item::{Builder, CompletionRelevanceTypeMatch},
-    render::{function::render_fn, literal::render_variant_lit, macro_::render_macro},
+    render::{
+        function::render_fn,
+        literal::render_variant_lit,
+        macro_::{render_macro, render_macro_pat},
+    },
     CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance,
 };
 /// Interface for data and methods required for items rendering.
@@ -153,21 +157,29 @@ pub(crate) fn render_tuple_field(
     item.build()
 }
 
+pub(crate) fn render_type_inference(ty_string: String, ctx: &CompletionContext) -> CompletionItem {
+    let mut builder =
+        CompletionItem::new(CompletionItemKind::InferredType, ctx.source_range(), ty_string);
+    builder.set_relevance(CompletionRelevance { is_definite: true, ..Default::default() });
+    builder.build()
+}
+
 pub(crate) fn render_path_resolution(
     ctx: RenderContext<'_>,
     path_ctx: &PathCompletionCtx,
     local_name: hir::Name,
     resolution: ScopeDef,
 ) -> Builder {
-    render_resolution_(ctx, path_ctx, local_name, None, resolution)
+    render_resolution_path(ctx, path_ctx, local_name, None, resolution)
 }
 
-pub(crate) fn render_resolution_simple(
+pub(crate) fn render_pattern_resolution(
     ctx: RenderContext<'_>,
+    pattern_ctx: &PatternContext,
     local_name: hir::Name,
     resolution: ScopeDef,
 ) -> Builder {
-    render_resolution_simple_(ctx, None, local_name, None, resolution)
+    render_resolution_pat(ctx, pattern_ctx, local_name, None, resolution)
 }
 
 pub(crate) fn render_resolution_with_import(
@@ -176,23 +188,56 @@ pub(crate) fn render_resolution_with_import(
     import_edit: LocatedImport,
 ) -> Option<Builder> {
     let resolution = ScopeDef::from(import_edit.original_item);
-    let local_name = match resolution {
+    let local_name = scope_def_to_name(resolution, &ctx, &import_edit)?;
+
+    Some(render_resolution_path(ctx, path_ctx, local_name, Some(import_edit), resolution))
+}
+
+pub(crate) fn render_resolution_with_import_pat(
+    ctx: RenderContext<'_>,
+    pattern_ctx: &PatternContext,
+    import_edit: LocatedImport,
+) -> Option<Builder> {
+    let resolution = ScopeDef::from(import_edit.original_item);
+    let local_name = scope_def_to_name(resolution, &ctx, &import_edit)?;
+    Some(render_resolution_pat(ctx, pattern_ctx, local_name, Some(import_edit), resolution))
+}
+
+fn scope_def_to_name(
+    resolution: ScopeDef,
+    ctx: &RenderContext,
+    import_edit: &LocatedImport,
+) -> Option<hir::Name> {
+    Some(match resolution {
         ScopeDef::ModuleDef(hir::ModuleDef::Function(f)) => f.name(ctx.completion.db),
         ScopeDef::ModuleDef(hir::ModuleDef::Const(c)) => c.name(ctx.completion.db)?,
         ScopeDef::ModuleDef(hir::ModuleDef::TypeAlias(t)) => t.name(ctx.completion.db),
         _ => item_name(ctx.db(), import_edit.original_item)?,
-    };
-    Some(render_resolution_(ctx, path_ctx, local_name, Some(import_edit), resolution))
+    })
 }
 
-pub(crate) fn render_type_inference(ty_string: String, ctx: &CompletionContext) -> CompletionItem {
-    let mut builder =
-        CompletionItem::new(CompletionItemKind::InferredType, ctx.source_range(), ty_string);
-    builder.set_relevance(CompletionRelevance { is_definite: true, ..Default::default() });
-    builder.build()
+fn render_resolution_pat(
+    ctx: RenderContext<'_>,
+    pattern_ctx: &PatternContext,
+    local_name: hir::Name,
+    import_to_add: Option<LocatedImport>,
+    resolution: ScopeDef,
+) -> Builder {
+    let _p = profile::span("render_resolution");
+    use hir::ModuleDef::*;
+
+    match resolution {
+        ScopeDef::ModuleDef(Macro(mac)) => {
+            let ctx = ctx.import_to_add(import_to_add);
+            return render_macro_pat(ctx, pattern_ctx, local_name, mac);
+        }
+        _ => (),
+    }
+
+    render_resolution_simple_(ctx, local_name, import_to_add, resolution)
 }
 
-fn render_resolution_(
+fn render_resolution_path(
     ctx: RenderContext<'_>,
     path_ctx: &PathCompletionCtx,
     local_name: hir::Name,
@@ -221,22 +266,14 @@ fn render_resolution_(
         }
         _ => (),
     }
-    render_resolution_simple_type(ctx, path_ctx, local_name, import_to_add, resolution)
-}
 
-fn render_resolution_simple_type(
-    ctx: RenderContext<'_>,
-    path_ctx: &PathCompletionCtx,
-    local_name: hir::Name,
-    import_to_add: Option<LocatedImport>,
-    resolution: ScopeDef,
-) -> Builder {
+    let completion = ctx.completion;
     let cap = ctx.snippet_cap();
-    let db = ctx.completion.db;
-    let config = ctx.completion.config;
+    let db = completion.db;
+    let config = completion.config;
+
     let name = local_name.to_smol_str();
-    let mut item =
-        render_resolution_simple_(ctx, Some(path_ctx), local_name, import_to_add, resolution);
+    let mut item = render_resolution_simple_(ctx, local_name, import_to_add, resolution);
     // Add `<>` for generic types
     let type_path_no_ty_args = matches!(
         path_ctx,
@@ -251,6 +288,7 @@ fn render_resolution_simple_type(
                 }
                 _ => false,
             };
+
             if has_non_default_type_params {
                 cov_mark::hit!(inserts_angle_brackets_for_generics);
                 item.lookup_by(name.clone())
@@ -260,22 +298,52 @@ fn render_resolution_simple_type(
             }
         }
     }
+    if let ScopeDef::Local(local) = resolution {
+        let ty = local.ty(db);
+        if !ty.is_unknown() {
+            item.detail(ty.display(db).to_string());
+        }
+
+        item.set_relevance(CompletionRelevance {
+            type_match: compute_type_match(completion, &ty),
+            exact_name_match: compute_exact_name_match(completion, &name),
+            is_local: true,
+            ..CompletionRelevance::default()
+        });
+
+        if let Some(ref_match) = compute_ref_match(completion, &ty) {
+            item.ref_match(ref_match, path_ctx.path.syntax().text_range().start());
+        }
+    };
     item
 }
 
 fn render_resolution_simple_(
     ctx: RenderContext<'_>,
-    path_ctx: Option<&PathCompletionCtx>,
     local_name: hir::Name,
     import_to_add: Option<LocatedImport>,
     resolution: ScopeDef,
 ) -> Builder {
     let _p = profile::span("render_resolution");
-    use hir::ModuleDef::*;
 
     let db = ctx.db();
     let ctx = ctx.import_to_add(import_to_add);
-    let kind = match resolution {
+    let kind = res_to_kind(resolution);
+
+    let mut item = CompletionItem::new(kind, ctx.source_range(), local_name.to_smol_str());
+    item.set_relevance(ctx.completion_relevance())
+        .set_documentation(scope_def_docs(db, resolution))
+        .set_deprecated(scope_def_is_deprecated(&ctx, resolution));
+
+    if let Some(import_to_add) = ctx.import_to_add {
+        item.add_import(import_to_add);
+    }
+    item
+}
+
+fn res_to_kind(resolution: ScopeDef) -> CompletionItemKind {
+    use hir::ModuleDef::*;
+    match resolution {
         ScopeDef::Unknown => CompletionItemKind::UnresolvedReference,
         ScopeDef::ModuleDef(Function(_)) => CompletionItemKind::SymbolKind(SymbolKind::Function),
         ScopeDef::ModuleDef(Variant(_)) => CompletionItemKind::SymbolKind(SymbolKind::Variant),
@@ -301,38 +369,7 @@ fn render_resolution_simple_(
         ScopeDef::AdtSelfType(..) | ScopeDef::ImplSelfType(..) => {
             CompletionItemKind::SymbolKind(SymbolKind::SelfParam)
         }
-    };
-
-    let local_name = local_name.to_smol_str();
-    let mut item = CompletionItem::new(kind, ctx.source_range(), local_name.clone());
-    item.set_relevance(ctx.completion_relevance());
-    if let ScopeDef::Local(local) = resolution {
-        let ty = local.ty(db);
-        if !ty.is_unknown() {
-            item.detail(ty.display(db).to_string());
-        }
-
-        item.set_relevance(CompletionRelevance {
-            type_match: compute_type_match(ctx.completion, &ty),
-            exact_name_match: compute_exact_name_match(ctx.completion, &local_name),
-            is_local: true,
-            ..CompletionRelevance::default()
-        });
-
-        if let Some(path_ctx) = path_ctx {
-            if let Some(ref_match) = compute_ref_match(ctx.completion, &ty) {
-                item.ref_match(ref_match, path_ctx.path.syntax().text_range().start());
-            }
-        }
-    };
-
-    item.set_documentation(scope_def_docs(db, resolution))
-        .set_deprecated(scope_def_is_deprecated(&ctx, resolution));
-
-    if let Some(import_to_add) = ctx.import_to_add {
-        item.add_import(import_to_add);
     }
-    item
 }
 
 fn scope_def_docs(db: &RootDatabase, resolution: ScopeDef) -> Option<hir::Documentation> {
diff --git a/crates/ide-completion/src/render/macro_.rs b/crates/ide-completion/src/render/macro_.rs
index 6da7bb3193b..ac2091eca98 100644
--- a/crates/ide-completion/src/render/macro_.rs
+++ b/crates/ide-completion/src/render/macro_.rs
@@ -5,24 +5,37 @@ use ide_db::SymbolKind;
 use syntax::SmolStr;
 
 use crate::{
-    context::{PathCompletionCtx, PathKind},
+    context::{PathCompletionCtx, PathKind, PatternContext},
     item::{Builder, CompletionItem},
     render::RenderContext,
 };
 
 pub(crate) fn render_macro(
     ctx: RenderContext<'_>,
-    path_ctx: &PathCompletionCtx,
+    PathCompletionCtx { kind, has_macro_bang, has_call_parens, .. }: &PathCompletionCtx,
+
+    name: hir::Name,
+    macro_: hir::Macro,
+) -> Builder {
+    let _p = profile::span("render_macro");
+    render(ctx, *kind == PathKind::Use, *has_macro_bang, *has_call_parens, name, macro_)
+}
+
+pub(crate) fn render_macro_pat(
+    ctx: RenderContext<'_>,
+    _pattern_ctx: &PatternContext,
     name: hir::Name,
     macro_: hir::Macro,
 ) -> Builder {
     let _p = profile::span("render_macro");
-    render(ctx, path_ctx, name, macro_)
+    render(ctx, false, false, false, name, macro_)
 }
 
 fn render(
     ctx @ RenderContext { completion, .. }: RenderContext<'_>,
-    PathCompletionCtx { kind, has_macro_bang, has_call_parens, .. }: &PathCompletionCtx,
+    is_use_path: bool,
+    has_macro_bang: bool,
+    has_call_parens: bool,
     name: hir::Name,
     macro_: hir::Macro,
 ) -> Builder {
@@ -39,7 +52,7 @@ fn render(
     let is_fn_like = macro_.is_fn_like(completion.db);
     let (bra, ket) = if is_fn_like { guess_macro_braces(&name, docs_str) } else { ("", "") };
 
-    let needs_bang = is_fn_like && *kind != PathKind::Use && !has_macro_bang;
+    let needs_bang = is_fn_like && !is_use_path && !has_macro_bang;
 
     let mut item = CompletionItem::new(
         SymbolKind::from(macro_.kind(completion.db)),