diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 2514dda7c70..09a27de7141 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -10,10 +10,8 @@ pub(crate) mod type_alias;
 
 mod builder_ext;
 
-use base_db::Upcast;
 use hir::{
-    db::HirDatabase, AsAssocItem, Documentation, HasAttrs, HirDisplay, ModuleDef, Mutability,
-    ScopeDef, Type,
+    AsAssocItem, Documentation, HasAttrs, HirDisplay, ModuleDef, Mutability, ScopeDef, Type,
 };
 use ide_db::{
     helpers::{item_name, SnippetCap},
@@ -22,8 +20,8 @@ use ide_db::{
 use syntax::TextRange;
 
 use crate::{
-    item::{CompletionRelevance, ImportEdit},
-    CompletionContext, CompletionItem, CompletionItemKind, CompletionKind,
+    item::ImportEdit, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind,
+    CompletionRelevance,
 };
 
 use crate::render::{enum_variant::render_variant, function::render_fn, macro_::render_macro};
@@ -144,7 +142,15 @@ impl<'a> Render<'a> {
             .set_documentation(field.docs(self.ctx.db()))
             .set_deprecated(is_deprecated);
 
-        item.set_relevance(compute_relevance(&self.ctx, &ty, &name.to_string()));
+        item.set_relevance(CompletionRelevance {
+            exact_type_match: compute_exact_type_match(self.ctx.completion, ty),
+            exact_name_match: compute_exact_name_match(self.ctx.completion, name.to_string()),
+            ..CompletionRelevance::default()
+        });
+
+        if let Some(ref_match) = compute_ref_match(self.ctx.completion, ty) {
+            item.ref_match(ref_match);
+        }
 
         item.build()
     }
@@ -234,31 +240,18 @@ impl<'a> Render<'a> {
             if !ty.is_unknown() {
                 item.detail(ty.display(self.ctx.db()).to_string());
             }
-        };
 
-        if let ScopeDef::Local(local) = resolution {
-            let ty = local.ty(self.ctx.db());
+            item.set_relevance(CompletionRelevance {
+                exact_type_match: compute_exact_type_match(self.ctx.completion, &ty),
+                exact_name_match: compute_exact_name_match(self.ctx.completion, local_name.clone()),
+                is_local: true,
+                ..CompletionRelevance::default()
+            });
 
-            let mut relevance = compute_relevance(&self.ctx, &ty, &local_name);
-            relevance.is_local = true;
-            item.set_relevance(relevance);
-
-            if let Some(expected_type) = self.ctx.completion.expected_type.as_ref() {
-                if &ty != expected_type {
-                    if let Some(ty_without_ref) = expected_type.remove_ref() {
-                        if relevance_type_match(self.ctx.db().upcast(), &ty, &ty_without_ref) {
-                            cov_mark::hit!(suggest_ref);
-                            let mutability = if expected_type.is_mutable_reference() {
-                                Mutability::Mut
-                            } else {
-                                Mutability::Shared
-                            };
-                            item.ref_match(mutability);
-                        }
-                    }
-                }
+            if let Some(ref_match) = compute_ref_match(self.ctx.completion, &ty) {
+                item.ref_match(ref_match);
             }
-        }
+        };
 
         // Add `<>` for generic types
         if self.ctx.completion.is_path_type
@@ -313,17 +306,44 @@ impl<'a> Render<'a> {
     }
 }
 
-fn compute_relevance(ctx: &RenderContext, ty: &Type, name: &str) -> CompletionRelevance {
-    let mut res = CompletionRelevance::default();
-
-    res.exact_type_match = Some(ty) == ctx.completion.expected_type.as_ref();
-    res.exact_name_match = Some(name) == ctx.completion.expected_name.as_deref();
-
-    res
+fn compute_exact_type_match(ctx: &CompletionContext, completion_ty: &hir::Type) -> bool {
+    if let Some(expected_type) = ctx.expected_type.as_ref() {
+        // We don't ever consider unit type to be an exact type match, since
+        // nearly always this is not meaningful to the user.
+        completion_ty == expected_type && !expected_type.is_unit()
+    } else {
+        false
+    }
 }
 
-fn relevance_type_match(db: &dyn HirDatabase, ty: &Type, expected_type: &Type) -> bool {
-    ty == expected_type || ty.autoderef(db).any(|deref_ty| &deref_ty == expected_type)
+fn compute_exact_name_match(ctx: &CompletionContext, completion_name: impl Into<String>) -> bool {
+    let completion_name = completion_name.into();
+
+    Some(&completion_name) == ctx.expected_name.as_ref()
+}
+
+fn compute_ref_match(ctx: &CompletionContext, completion_ty: &hir::Type) -> Option<Mutability> {
+    let mut ref_match = None;
+    if let Some(expected_type) = &ctx.expected_type {
+        if completion_ty != expected_type {
+            if let Some(expected_type_without_ref) = expected_type.remove_ref() {
+                if completion_ty == &expected_type_without_ref
+                    || completion_ty
+                        .autoderef(ctx.db)
+                        .any(|deref_ty| deref_ty == expected_type_without_ref)
+                {
+                    cov_mark::hit!(suggest_ref);
+                    let mutability = if expected_type.is_mutable_reference() {
+                        Mutability::Mut
+                    } else {
+                        Mutability::Shared
+                    };
+                    ref_match = Some(mutability);
+                }
+            }
+        }
+    };
+    ref_match
 }
 
 #[cfg(test)]
@@ -477,6 +497,11 @@ fn main() { let _: m::Spam = S$0 }
                         ),
                         lookup: "Spam::Bar",
                         detail: "(i32)",
+                        relevance: CompletionRelevance {
+                            exact_name_match: false,
+                            exact_type_match: true,
+                            is_local: false,
+                        },
                         trigger_call_info: true,
                     },
                     CompletionItem {
@@ -498,6 +523,11 @@ fn main() { let _: m::Spam = S$0 }
                         ),
                         lookup: "Spam::Foo",
                         detail: "()",
+                        relevance: CompletionRelevance {
+                            exact_name_match: false,
+                            exact_type_match: true,
+                            is_local: false,
+                        },
                     },
                     CompletionItem {
                         label: "main()",
@@ -1169,4 +1199,86 @@ fn foo(bar: u32) {
             "#]],
         );
     }
+
+    #[test]
+    fn enum_owned() {
+        check_relevance(
+            r#"
+enum Foo { A, B }
+fn foo() {
+    bar($0);
+}
+fn bar(t: Foo) {}
+"#,
+            expect![[r#"
+                ev Foo::A [type]
+                ev Foo::B [type]
+                en Foo []
+                fn bar(…) []
+                fn foo() []
+            "#]],
+        );
+    }
+
+    #[test]
+    fn enum_ref() {
+        check_relevance(
+            r#"
+enum Foo { A, B }
+fn foo() {
+    bar($0);
+}
+fn bar(t: &Foo) {}
+"#,
+            expect![[r#"
+                ev Foo::A []
+                ev &Foo::A [type]
+                ev Foo::B []
+                ev &Foo::B [type]
+                en Foo []
+                fn bar(…) []
+                fn foo() []
+            "#]],
+        );
+    }
+
+    #[test]
+    fn suggest_deref_fn_ret() {
+        check_relevance(
+            r#"
+#[lang = "deref"]
+trait Deref {
+    type Target;
+    fn deref(&self) -> &Self::Target;
+}
+
+struct S;
+struct T(S);
+
+impl Deref for T {
+    type Target = S;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+fn foo(s: &S) {}
+fn bar() -> T {}
+
+fn main() {
+    foo($0);
+}
+            "#,
+            expect![[r#"
+                tt Deref []
+                fn bar() []
+                fn &bar() [type]
+                fn foo(…) []
+                st T []
+                st S []
+                fn main() []
+            "#]],
+        )
+    }
 }
diff --git a/crates/ide_completion/src/render/enum_variant.rs b/crates/ide_completion/src/render/enum_variant.rs
index e8cfcc0c7b4..374247b0569 100644
--- a/crates/ide_completion/src/render/enum_variant.rs
+++ b/crates/ide_completion/src/render/enum_variant.rs
@@ -6,7 +6,8 @@ use itertools::Itertools;
 
 use crate::{
     item::{CompletionItem, CompletionKind, ImportEdit},
-    render::{builder_ext::Params, RenderContext},
+    render::{builder_ext::Params, compute_exact_type_match, compute_ref_match, RenderContext},
+    CompletionRelevance,
 };
 
 pub(crate) fn render_variant<'a>(
@@ -74,6 +75,16 @@ impl<'a> EnumRender<'a> {
             item.lookup_by(self.short_qualified_name);
         }
 
+        let ty = self.variant.parent_enum(self.ctx.completion.db).ty(self.ctx.completion.db);
+        item.set_relevance(CompletionRelevance {
+            exact_type_match: compute_exact_type_match(self.ctx.completion, &ty),
+            ..CompletionRelevance::default()
+        });
+
+        if let Some(ref_match) = compute_ref_match(self.ctx.completion, &ty) {
+            item.ref_match(ref_match);
+        }
+
         item.build()
     }
 
diff --git a/crates/ide_completion/src/render/function.rs b/crates/ide_completion/src/render/function.rs
index 47e26a5d8d4..194ea135e98 100644
--- a/crates/ide_completion/src/render/function.rs
+++ b/crates/ide_completion/src/render/function.rs
@@ -6,7 +6,10 @@ use syntax::ast::Fn;
 
 use crate::{
     item::{CompletionItem, CompletionItemKind, CompletionKind, CompletionRelevance, ImportEdit},
-    render::{builder_ext::Params, RenderContext},
+    render::{
+        builder_ext::Params, compute_exact_name_match, compute_exact_type_match, compute_ref_match,
+        RenderContext,
+    },
 };
 
 pub(crate) fn render_fn<'a>(
@@ -52,23 +55,19 @@ impl<'a> FunctionRender<'a> {
                 self.ctx.is_deprecated(self.func) || self.ctx.is_deprecated_assoc_item(self.func),
             )
             .detail(self.detail())
-            .add_call_parens(self.ctx.completion, self.name, params)
+            .add_call_parens(self.ctx.completion, self.name.clone(), params)
             .add_import(import_to_add);
 
-        let mut relevance = CompletionRelevance::default();
-        if let Some(expected_type) = &self.ctx.completion.expected_type {
-            let ret_ty = self.func.ret_type(self.ctx.db());
+        let ret_type = self.func.ret_type(self.ctx.db());
+        item.set_relevance(CompletionRelevance {
+            exact_type_match: compute_exact_type_match(self.ctx.completion, &ret_type),
+            exact_name_match: compute_exact_name_match(self.ctx.completion, self.name.clone()),
+            ..CompletionRelevance::default()
+        });
 
-            // We don't ever consider a function which returns unit type to be an
-            // exact type match, since nearly always this is not meaningful to the
-            // user.
-            relevance.exact_type_match = &ret_ty == expected_type && !ret_ty.is_unit();
+        if let Some(ref_match) = compute_ref_match(self.ctx.completion, &ret_type) {
+            item.ref_match(ref_match);
         }
-        if let Some(expected_name) = &self.ctx.completion.expected_name {
-            relevance.exact_name_match =
-                expected_name == &self.func.name(self.ctx.db()).to_string();
-        }
-        item.set_relevance(relevance);
 
         item.build()
     }