about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2022-06-03 20:49:25 +0200
committerLukas Wirth <lukastw97@gmail.com>2022-06-03 20:49:25 +0200
commita2a74bf27889d32a22fff6a0004e0bf471398c47 (patch)
tree49ed2e2eb7d232bdf0d5a6cffa96fbe1021a6636
parenta0c1816e3a59fb7bf334196a3d990b3dafc2b586 (diff)
downloadrust-a2a74bf27889d32a22fff6a0004e0bf471398c47.tar.gz
rust-a2a74bf27889d32a22fff6a0004e0bf471398c47.zip
Remove some of the unnecessary helpfer functions from CompletionContext
-rw-r--r--crates/ide-completion/src/completions/dot.rs14
-rw-r--r--crates/ide-completion/src/completions/expr.rs121
-rw-r--r--crates/ide-completion/src/completions/flyimport.rs44
-rw-r--r--crates/ide-completion/src/completions/item_list.rs37
-rw-r--r--crates/ide-completion/src/completions/keyword.rs6
-rw-r--r--crates/ide-completion/src/completions/record.rs37
-rw-r--r--crates/ide-completion/src/completions/type.rs3
-rw-r--r--crates/ide-completion/src/context.rs40
-rw-r--r--crates/ide-completion/src/lib.rs1
-rw-r--r--crates/ide-completion/src/patterns.rs29
-rw-r--r--crates/ide-completion/src/render.rs10
-rw-r--r--crates/ide-completion/src/render/macro_.rs4
12 files changed, 151 insertions, 195 deletions
diff --git a/crates/ide-completion/src/completions/dot.rs b/crates/ide-completion/src/completions/dot.rs
index 1e0b7711667..a11652ca302 100644
--- a/crates/ide-completion/src/completions/dot.rs
+++ b/crates/ide-completion/src/completions/dot.rs
@@ -46,12 +46,14 @@ fn complete_undotted_self(acc: &mut Completions, ctx: &CompletionContext) {
         return;
     }
     match ctx.path_context() {
-        Some(PathCompletionCtx {
-            is_absolute_path: false,
-            qualifier: None,
-            kind: PathKind::Expr { .. },
-            ..
-        }) if !ctx.is_path_disallowed() => {}
+        Some(
+            path_ctx @ PathCompletionCtx {
+                is_absolute_path: false,
+                qualifier: None,
+                kind: PathKind::Expr { .. },
+                ..
+            },
+        ) if path_ctx.is_trivial_path() && ctx.qualifier_ctx.none() => {}
         _ => return,
     }
 
diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs
index 23f47523d66..7c3296a0b31 100644
--- a/crates/ide-completion/src/completions/expr.rs
+++ b/crates/ide-completion/src/completions/expr.rs
@@ -11,32 +11,38 @@ use crate::{
 
 pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext) {
     let _p = profile::span("complete_expr_path");
-    if ctx.is_path_disallowed() {
-        return;
-    }
 
-    let (is_absolute_path, qualifier, in_block_expr, in_loop_body, is_func_update, after_if_expr) =
-        match ctx.nameref_ctx() {
-            Some(NameRefContext {
-                path_ctx:
-                    Some(PathCompletionCtx {
-                        kind: PathKind::Expr { in_block_expr, in_loop_body, after_if_expr },
-                        is_absolute_path,
-                        qualifier,
-                        ..
-                    }),
-                record_expr,
-                ..
-            }) => (
-                *is_absolute_path,
-                qualifier,
-                *in_block_expr,
-                *in_loop_body,
-                record_expr.as_ref().map_or(false, |&(_, it)| it),
-                *after_if_expr,
-            ),
-            _ => return,
-        };
+    let (
+        is_absolute_path,
+        qualifier,
+        in_block_expr,
+        in_loop_body,
+        is_func_update,
+        after_if_expr,
+        wants_mut_token,
+    ) = match ctx.nameref_ctx() {
+        Some(NameRefContext {
+            path_ctx:
+                Some(PathCompletionCtx {
+                    kind:
+                        PathKind::Expr { in_block_expr, in_loop_body, after_if_expr, ref_expr_parent },
+                    is_absolute_path,
+                    qualifier,
+                    ..
+                }),
+            record_expr,
+            ..
+        }) if ctx.qualifier_ctx.none() => (
+            *is_absolute_path,
+            qualifier,
+            *in_block_expr,
+            *in_loop_body,
+            record_expr.as_ref().map_or(false, |&(_, it)| it),
+            *after_if_expr,
+            ref_expr_parent.as_ref().map(|it| it.mut_token().is_none()).unwrap_or(false),
+        ),
+        _ => return,
+    };
 
     let scope_def_applicable = |def| {
         use hir::{GenericParam::*, ModuleDef::*};
@@ -164,12 +170,43 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
         None if is_absolute_path => acc.add_crate_roots(ctx),
         None => {
             acc.add_nameref_keywords_with_colon(ctx);
-            if let Some(hir::Adt::Enum(e)) =
+            if let Some(adt) =
                 ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
             {
-                super::enum_variants_with_paths(acc, ctx, e, |acc, ctx, variant, path| {
-                    acc.add_qualified_enum_variant(ctx, variant, path)
-                });
+                let self_ty =
+                    (|| ctx.sema.to_def(ctx.impl_def.as_ref()?)?.self_ty(ctx.db).as_adt())();
+                let complete_self = self_ty == Some(adt);
+
+                match adt {
+                    hir::Adt::Struct(strukt) => {
+                        let path = ctx
+                            .module
+                            .find_use_path(ctx.db, hir::ModuleDef::from(strukt))
+                            .filter(|it| it.len() > 1);
+
+                        acc.add_struct_literal(ctx, strukt, path, None);
+
+                        if complete_self {
+                            acc.add_struct_literal(ctx, strukt, None, Some(hir::known::SELF_TYPE));
+                        }
+                    }
+                    hir::Adt::Union(un) => {
+                        let path = ctx
+                            .module
+                            .find_use_path(ctx.db, hir::ModuleDef::from(un))
+                            .filter(|it| it.len() > 1);
+
+                        acc.add_union_literal(ctx, un, path, None);
+                        if complete_self {
+                            acc.add_union_literal(ctx, un, None, Some(hir::known::SELF_TYPE));
+                        }
+                    }
+                    hir::Adt::Enum(e) => {
+                        super::enum_variants_with_paths(acc, ctx, e, |acc, ctx, variant, path| {
+                            acc.add_qualified_enum_variant(ctx, variant, path)
+                        });
+                    }
+                }
             }
             ctx.process_all_names(&mut |name, def| {
                 if scope_def_applicable(def) {
@@ -180,20 +217,18 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
             if !is_func_update {
                 let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
 
-                if ctx.expects_expression() {
-                    if !in_block_expr {
-                        add_keyword("unsafe", "unsafe {\n    $0\n}");
-                    }
-                    add_keyword("match", "match $1 {\n    $0\n}");
-                    add_keyword("while", "while $1 {\n    $0\n}");
-                    add_keyword("while let", "while let $1 = $2 {\n    $0\n}");
-                    add_keyword("loop", "loop {\n    $0\n}");
-                    add_keyword("if", "if $1 {\n    $0\n}");
-                    add_keyword("if let", "if let $1 = $2 {\n    $0\n}");
-                    add_keyword("for", "for $1 in $2 {\n    $0\n}");
-                    add_keyword("true", "true");
-                    add_keyword("false", "false");
+                if !in_block_expr {
+                    add_keyword("unsafe", "unsafe {\n    $0\n}");
                 }
+                add_keyword("match", "match $1 {\n    $0\n}");
+                add_keyword("while", "while $1 {\n    $0\n}");
+                add_keyword("while let", "while let $1 = $2 {\n    $0\n}");
+                add_keyword("loop", "loop {\n    $0\n}");
+                add_keyword("if", "if $1 {\n    $0\n}");
+                add_keyword("if let", "if let $1 = $2 {\n    $0\n}");
+                add_keyword("for", "for $1 in $2 {\n    $0\n}");
+                add_keyword("true", "true");
+                add_keyword("false", "false");
 
                 if ctx.previous_token_is(T![if])
                     || ctx.previous_token_is(T![while])
@@ -207,7 +242,7 @@ pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext)
                     add_keyword("else if", "else if $1 {\n    $0\n}");
                 }
 
-                if ctx.expects_ident_ref_expr() {
+                if wants_mut_token {
                     add_keyword("mut", "mut ");
                 }
 
diff --git a/crates/ide-completion/src/completions/flyimport.rs b/crates/ide-completion/src/completions/flyimport.rs
index 22068096ba0..901f7519d25 100644
--- a/crates/ide-completion/src/completions/flyimport.rs
+++ b/crates/ide-completion/src/completions/flyimport.rs
@@ -8,7 +8,7 @@ use itertools::Itertools;
 use syntax::{AstNode, SyntaxNode, T};
 
 use crate::{
-    context::{CompletionContext, PathKind},
+    context::{CompletionContext, NameRefContext, PathCompletionCtx, PathKind, PatternContext},
     patterns::ImmediateLocation,
     render::{render_resolution_with_import, RenderContext},
 };
@@ -110,16 +110,26 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
     if !ctx.config.enable_imports_on_the_fly {
         return None;
     }
-    if matches!(ctx.path_kind(), Some(PathKind::Vis { .. } | PathKind::Use | PathKind::Item { .. }))
-        || ctx.is_path_disallowed()
-    {
-        return None;
-    }
-    // FIXME: This should be encoded in a different way
-    if ctx.pattern_ctx.is_none() && ctx.path_context().is_none() && !ctx.has_dot_receiver() {
-        // completion inside `ast::Name` of a item declaration
-        return None;
-    }
+    let path_kind = match ctx.nameref_ctx() {
+        Some(NameRefContext { path_ctx: Some(PathCompletionCtx { kind, .. }), .. })
+            if matches!(
+                kind,
+                PathKind::Expr { .. }
+                    | PathKind::Type { .. }
+                    | PathKind::Attr { .. }
+                    | PathKind::Derive
+                    | PathKind::Pat
+            ) =>
+        {
+            Some(kind)
+        }
+        Some(NameRefContext { dot_access: Some(_), .. }) => None,
+        None if matches!(ctx.pattern_ctx, Some(PatternContext { record_pat: None, .. })) => {
+            Some(&PathKind::Pat)
+        }
+        _ => return None,
+    };
+
     let potential_import_name = {
         let token_kind = ctx.token.kind();
         if matches!(token_kind, T![.] | T![::]) {
@@ -138,18 +148,10 @@ pub(crate) fn import_on_the_fly(acc: &mut Completions, ctx: &CompletionContext)
         return None;
     }
 
-    let path_kind = match ctx.path_kind() {
-        Some(kind) => Some(kind),
-        None if ctx.pattern_ctx.is_some() => Some(PathKind::Pat),
-        None => None,
-    };
     let ns_filter = |import: &LocatedImport| {
         let path_kind = match path_kind {
-            Some(path_kind) => path_kind,
-            None => match import.original_item {
-                ItemInNs::Macros(mac) => return mac.is_fn_like(ctx.db),
-                _ => return true,
-            },
+            Some(it) => it,
+            None => return true,
         };
         match (path_kind, import.original_item) {
             // Aren't handled in flyimport
diff --git a/crates/ide-completion/src/completions/item_list.rs b/crates/ide-completion/src/completions/item_list.rs
index 7c6d72a031e..d44bf0a6ab7 100644
--- a/crates/ide-completion/src/completions/item_list.rs
+++ b/crates/ide-completion/src/completions/item_list.rs
@@ -16,19 +16,23 @@ pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext)
         return;
     }
 
-    let (&is_absolute_path, path_qualifier, kind) = match ctx.path_context() {
-        Some(PathCompletionCtx {
-            kind: PathKind::Item { kind },
-            is_absolute_path,
-            qualifier,
-            ..
-        }) => (is_absolute_path, qualifier, Some(kind)),
-        Some(PathCompletionCtx {
-            kind: PathKind::Expr { in_block_expr: true, .. },
-            is_absolute_path,
-            qualifier,
-            ..
-        }) => (is_absolute_path, qualifier, None),
+    let (&is_absolute_path, path_qualifier, kind, is_trivial_path) = match ctx.path_context() {
+        Some(
+            ctx @ PathCompletionCtx {
+                kind: PathKind::Item { kind },
+                is_absolute_path,
+                qualifier,
+                ..
+            },
+        ) => (is_absolute_path, qualifier, Some(kind), ctx.is_trivial_path()),
+        Some(
+            ctx @ PathCompletionCtx {
+                kind: PathKind::Expr { in_block_expr: true, .. },
+                is_absolute_path,
+                qualifier,
+                ..
+            },
+        ) => (is_absolute_path, qualifier, None, ctx.is_trivial_path()),
         _ => return,
     };
 
@@ -36,7 +40,9 @@ pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext)
         trait_impl::complete_trait_impl(acc, ctx);
     }
 
-    add_keywords(acc, ctx, kind);
+    if is_trivial_path {
+        add_keywords(acc, ctx, kind);
+    }
 
     if kind.is_none() {
         // this is already handled by expression
@@ -71,9 +77,6 @@ pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext)
 }
 
 fn add_keywords(acc: &mut Completions, ctx: &CompletionContext, kind: Option<&ItemListKind>) {
-    if ctx.is_non_trivial_path() {
-        return;
-    }
     let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
 
     let in_item_list = matches!(kind, Some(ItemListKind::SourceFile | ItemListKind::Module) | None);
diff --git a/crates/ide-completion/src/completions/keyword.rs b/crates/ide-completion/src/completions/keyword.rs
index e870ecc2295..65fa1191781 100644
--- a/crates/ide-completion/src/completions/keyword.rs
+++ b/crates/ide-completion/src/completions/keyword.rs
@@ -8,11 +8,7 @@ use crate::{context::NameRefContext, CompletionContext, Completions};
 
 pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) {
     let item = match ctx.nameref_ctx() {
-        Some(NameRefContext { keyword: Some(item), record_expr: None, .. })
-            if !ctx.is_non_trivial_path() =>
-        {
-            item
-        }
+        Some(NameRefContext { keyword: Some(item), record_expr: None, .. }) => item,
         _ => return,
     };
 
diff --git a/crates/ide-completion/src/completions/record.rs b/crates/ide-completion/src/completions/record.rs
index 6717ca0a0e2..65805dba1ce 100644
--- a/crates/ide-completion/src/completions/record.rs
+++ b/crates/ide-completion/src/completions/record.rs
@@ -71,43 +71,6 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) ->
     Some(())
 }
 
-pub(crate) fn complete_record_literal(
-    acc: &mut Completions,
-    ctx: &CompletionContext,
-) -> Option<()> {
-    if !ctx.expects_expression() {
-        return None;
-    }
-
-    match ctx.expected_type.as_ref()?.as_adt()? {
-        hir::Adt::Struct(strukt) if ctx.path_qual().is_none() => {
-            let path = ctx
-                .module
-                .find_use_path(ctx.db, hir::ModuleDef::from(strukt))
-                .filter(|it| it.len() > 1);
-
-            acc.add_struct_literal(ctx, strukt, path, None);
-
-            let impl_ = ctx.impl_def.as_ref()?;
-            let impl_adt = ctx.sema.to_def(impl_)?.self_ty(ctx.db).as_adt()?;
-            if hir::Adt::Struct(strukt) == impl_adt {
-                acc.add_struct_literal(ctx, strukt, None, Some(hir::known::SELF_TYPE));
-            }
-        }
-        hir::Adt::Union(un) if ctx.path_qual().is_none() => {
-            let path = ctx
-                .module
-                .find_use_path(ctx.db, hir::ModuleDef::from(un))
-                .filter(|it| it.len() > 1);
-
-            acc.add_union_literal(ctx, un, path, None);
-        }
-        _ => {}
-    };
-
-    Some(())
-}
-
 #[cfg(test)]
 mod tests {
     use crate::tests::check_edit;
diff --git a/crates/ide-completion/src/completions/type.rs b/crates/ide-completion/src/completions/type.rs
index bc8c070c14d..9cf0b87ad6f 100644
--- a/crates/ide-completion/src/completions/type.rs
+++ b/crates/ide-completion/src/completions/type.rs
@@ -13,9 +13,6 @@ use crate::{
 
 pub(crate) fn complete_type_path(acc: &mut Completions, ctx: &CompletionContext) {
     let _p = profile::span("complete_type_path");
-    if ctx.is_path_disallowed() {
-        return;
-    }
 
     let (&is_absolute_path, qualifier) = match ctx.path_context() {
         Some(PathCompletionCtx {
diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs
index d41ca88e890..02307def9e6 100644
--- a/crates/ide-completion/src/context.rs
+++ b/crates/ide-completion/src/context.rs
@@ -43,12 +43,13 @@ pub(crate) enum Visible {
     No,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub(super) enum PathKind {
     Expr {
         in_block_expr: bool,
         in_loop_body: bool,
         after_if_expr: bool,
+        ref_expr_parent: Option<ast::RefExpr>,
     },
     Type {
         in_tuple_struct: bool,
@@ -356,41 +357,14 @@ impl<'a> CompletionContext<'a> {
         matches!(self.completion_location, Some(ImmediateLocation::GenericArgList(_)))
     }
 
-    pub(crate) fn expects_ident_ref_expr(&self) -> bool {
-        matches!(self.completion_location, Some(ImmediateLocation::RefExpr))
-    }
-
-    // FIXME: This shouldn't exist
-    pub(crate) fn is_path_disallowed(&self) -> bool {
-        !self.qualifier_ctx.none()
-            || (matches!(self.name_ctx(), Some(NameContext { .. })) && self.pattern_ctx.is_none())
-            || matches!(self.pattern_ctx, Some(PatternContext { record_pat: Some(_), .. }))
-            || matches!(
-                self.nameref_ctx(),
-                Some(NameRefContext { record_expr: Some((_, false)), .. })
-            )
-    }
-
     pub(crate) fn path_context(&self) -> Option<&PathCompletionCtx> {
         self.nameref_ctx().and_then(|ctx| ctx.path_ctx.as_ref())
     }
 
-    pub(crate) fn expects_expression(&self) -> bool {
-        matches!(self.path_context(), Some(PathCompletionCtx { kind: PathKind::Expr { .. }, .. }))
-    }
-
-    pub(crate) fn is_non_trivial_path(&self) -> bool {
-        self.path_context().as_ref().map_or(false, |it| !it.is_trivial_path())
-    }
-
     pub(crate) fn path_qual(&self) -> Option<&ast::Path> {
         self.path_context().and_then(|it| it.qualifier.as_ref().map(|it| &it.path))
     }
 
-    pub(crate) fn path_kind(&self) -> Option<PathKind> {
-        self.path_context().map(|it| it.kind)
-    }
-
     /// Checks if an item is visible and not `doc(hidden)` at the completion site.
     pub(crate) fn is_visible<I>(&self, item: &I) -> Visible
     where
@@ -1210,8 +1184,10 @@ impl<'a> CompletionContext<'a> {
                         let in_block_expr = is_in_block(it.syntax());
                         let in_loop_body = is_in_loop_body(it.syntax());
                         let after_if_expr = after_if_expr(it.syntax().clone());
+                        let ref_expr_parent = path.as_single_name_ref()
+                            .and_then(|_| it.syntax().parent()).and_then(ast::RefExpr::cast);
 
-                        Some(PathKind::Expr { in_block_expr, in_loop_body, after_if_expr })
+                        Some(PathKind::Expr { in_block_expr, in_loop_body, after_if_expr, ref_expr_parent })
                     },
                     ast::TupleStructPat(it) => {
                         path_ctx.has_call_parens = true;
@@ -1261,7 +1237,9 @@ impl<'a> CompletionContext<'a> {
                                     let in_block_expr = is_in_block(it.syntax());
                                     let after_if_expr = after_if_expr(it.syntax().clone());
                                     fill_record_expr(it.syntax());
-                                    PathKind::Expr { in_block_expr, in_loop_body, after_if_expr }
+                                    let ref_expr_parent = path.as_single_name_ref()
+                                        .and_then(|_| it.syntax().parent()).and_then(ast::RefExpr::cast);
+                                    PathKind::Expr { in_block_expr, in_loop_body, after_if_expr, ref_expr_parent }
                                 });
                             },
                         }
@@ -1368,7 +1346,7 @@ impl<'a> CompletionContext<'a> {
                     }
                 }
 
-                if let Some(PathKind::Item { .. }) = kind {
+                if let PathKind::Item { .. } = path_ctx.kind {
                     if qualifier_ctx.none() {
                         if let Some(t) = top.first_token() {
                             if let Some(prev) = t
diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs
index 3269e4926a7..9dc367b0bcc 100644
--- a/crates/ide-completion/src/lib.rs
+++ b/crates/ide-completion/src/lib.rs
@@ -169,7 +169,6 @@ pub fn completions(
             completions::mod_::complete_mod(acc, ctx);
             completions::pattern::complete_pattern(acc, ctx);
             completions::postfix::complete_postfix(acc, ctx);
-            completions::record::complete_record_literal(acc, ctx);
             completions::record::complete_record(acc, ctx);
             completions::snippet::complete_expr_snippet(acc, ctx);
             completions::snippet::complete_item_snippet(acc, ctx);
diff --git a/crates/ide-completion/src/patterns.rs b/crates/ide-completion/src/patterns.rs
index 9abbfaa4072..761c97b9a96 100644
--- a/crates/ide-completion/src/patterns.rs
+++ b/crates/ide-completion/src/patterns.rs
@@ -30,7 +30,6 @@ pub(crate) enum TypeAnnotation {
 /// from which file the nodes are.
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub(crate) enum ImmediateLocation {
-    RefExpr,
     TypeBound,
     /// Original file ast node
     TypeAnnotation(TypeAnnotation),
@@ -80,7 +79,6 @@ pub(crate) fn determine_location(
 
     let res = match_ast! {
         match parent {
-            ast::RefExpr(_) => ImmediateLocation::RefExpr,
             ast::TypeBound(_) => ImmediateLocation::TypeBound,
             ast::TypeBoundList(_) => ImmediateLocation::TypeBound,
             ast::GenericArgList(_) => sema
@@ -248,30 +246,3 @@ fn next_non_trivia_sibling(ele: SyntaxElement) -> Option<SyntaxElement> {
     }
     None
 }
-
-#[cfg(test)]
-mod tests {
-    use syntax::algo::find_node_at_offset;
-
-    use crate::tests::position;
-
-    use super::*;
-
-    fn check_location(code: &str, loc: impl Into<Option<ImmediateLocation>>) {
-        let (db, pos) = position(code);
-
-        let sema = Semantics::new(&db);
-        let original_file = sema.parse(pos.file_id);
-
-        let name_like = find_node_at_offset(original_file.syntax(), pos.offset).unwrap();
-        assert_eq!(
-            determine_location(&sema, original_file.syntax(), pos.offset, &name_like),
-            loc.into()
-        );
-    }
-
-    #[test]
-    fn test_ref_expr_loc() {
-        check_location(r"fn my_fn() { let x = &m$0 foo; }", ImmediateLocation::RefExpr);
-    }
-}
diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs
index ca2b3ad3435..942dc033687 100644
--- a/crates/ide-completion/src/render.rs
+++ b/crates/ide-completion/src/render.rs
@@ -1099,6 +1099,8 @@ fn go(world: &WorldSnapshot) { go(w$0) }
 "#,
             expect![[r#"
                 lc world [type+name+local]
+                st WorldSnapshot {…} []
+                st &WorldSnapshot {…} [type]
                 st WorldSnapshot []
                 fn go(…) []
             "#]],
@@ -1197,6 +1199,8 @@ fn main() {
                 lc s [name+local]
                 lc &mut s [type+name+local]
                 st S []
+                st &mut S [type]
+                st S []
                 fn main() []
                 fn foo(…) []
             "#]],
@@ -1266,6 +1270,8 @@ fn main() {
                 lc m [local]
                 lc t [local]
                 lc &t [type+local]
+                st S []
+                st &S [type]
                 st T []
                 st S []
                 fn main() []
@@ -1311,6 +1317,8 @@ fn main() {
                 lc m [local]
                 lc t [local]
                 lc &mut t [type+local]
+                st S []
+                st &mut S [type]
                 st T []
                 st S []
                 fn main() []
@@ -1405,6 +1413,8 @@ fn main() {
 }
 "#,
             expect![[r#"
+                st S []
+                st &S [type]
                 st T []
                 st S []
                 fn main() []
diff --git a/crates/ide-completion/src/render/macro_.rs b/crates/ide-completion/src/render/macro_.rs
index 5c862f013a7..de527860d8c 100644
--- a/crates/ide-completion/src/render/macro_.rs
+++ b/crates/ide-completion/src/render/macro_.rs
@@ -34,8 +34,8 @@ fn render(
     let (bra, ket) = if is_fn_like { guess_macro_braces(&name, docs_str) } else { ("", "") };
 
     let needs_bang = match completion.path_context() {
-        Some(&PathCompletionCtx { kind, has_macro_bang, .. }) => {
-            is_fn_like && kind != PathKind::Use && !has_macro_bang
+        Some(PathCompletionCtx { kind, has_macro_bang, .. }) => {
+            is_fn_like && *kind != PathKind::Use && !has_macro_bang
         }
         _ => is_fn_like,
     };