diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs
index a469546c13d..505493a7483 100644
--- a/crates/hir_def/src/path/lower.rs
+++ b/crates/hir_def/src/path/lower.rs
@@ -101,8 +101,12 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
                 break;
             }
             ast::PathSegmentKind::SelfKw => {
-                kind = PathKind::Super(0);
-                break;
+                // don't break out if `self` is the last segment of a path, this mean we got an
+                // use tree like `foo::{self}` which we want to resolve as `foo`
+                if !segments.is_empty() {
+                    kind = PathKind::Super(0);
+                    break;
+                }
             }
             ast::PathSegmentKind::SuperKw => {
                 let nested_super_count = if let PathKind::Super(n) = kind { n } else { 0 };
@@ -117,6 +121,11 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
     segments.reverse();
     generic_args.reverse();
 
+    if segments.is_empty() && kind == PathKind::Plain && type_anchor.is_none() {
+        // plain empty paths don't exist, this means we got a single `self` segment as our path
+        kind = PathKind::Super(0);
+    }
+
     // handle local_inner_macros :
     // Basically, even in rustc it is quite hacky:
     // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 9a605b09d08..20b799490e1 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -3496,4 +3496,33 @@ mod foo$0;
             "#]],
         );
     }
+
+    #[test]
+    fn hover_self_in_use() {
+        check(
+            r#"
+//! This should not appear
+mod foo {
+    /// But this should appear
+    pub mod bar {}
+}
+use foo::bar::{self$0};
+"#,
+            expect![[r#"
+                *self*
+
+                ```rust
+                test::foo
+                ```
+
+                ```rust
+                pub mod bar
+                ```
+
+                ---
+
+                But this should appear
+            "#]],
+        );
+    }
 }