diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs
index 88fb3959203..2a89bd29fad 100644
--- a/crates/ide_completion/src/completions/qualified_path.rs
+++ b/crates/ide_completion/src/completions/qualified_path.rs
@@ -2,7 +2,7 @@
 
 use std::iter;
 
-use hir::ScopeDef;
+use hir::{ScopeDef, Trait};
 use rustc_hash::FxHashSet;
 use syntax::{ast, AstNode};
 
@@ -27,6 +27,25 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
         _ => return,
     };
 
+    // special case `<_>::$0` as this doesn't resolve to anything.
+    if path.qualifier().is_none() {
+        if matches!(
+            path.segment().and_then(|it| it.kind()),
+            Some(ast::PathSegmentKind::Type {
+                type_ref: Some(ast::Type::InferType(_)),
+                trait_ref: None,
+            })
+        ) {
+            cov_mark::hit!(completion_type_anchor_empty);
+            ctx.scope
+                .visible_traits()
+                .into_iter()
+                .flat_map(|it| Trait::from(it).items(ctx.sema.db))
+                .for_each(|item| add_assoc_item(acc, ctx, item));
+            return;
+        }
+    }
+
     let resolution = match ctx.sema.resolve_path(path) {
         Some(res) => res,
         None => return,
@@ -707,4 +726,28 @@ pub mod m {}
             expect![[r#""#]],
         )
     }
+
+    #[test]
+    fn type_anchor_empty() {
+        cov_mark::check!(completion_type_anchor_empty);
+        check(
+            r#"
+trait Foo {
+    fn foo() -> Self;
+}
+struct Bar;
+impl Foo for Bar {
+    fn foo() -> {
+        Bar
+    }
+}
+fn bar() -> Bar {
+    <_>::$0
+}
+"#,
+            expect![[r#"
+                fn foo() (as Foo) fn() -> Self
+            "#]],
+        )
+    }
 }