Fix handling of blocks modules that are not the root module
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs
index 454e063..db50e65 100644
--- a/crates/hir-def/src/item_tree/lower.rs
+++ b/crates/hir-def/src/item_tree/lower.rs
@@ -370,18 +370,13 @@
         });
         match &vis {
             RawVisibility::Public => RawVisibilityId::PUB,
-            RawVisibility::Module(path, explicitness) if path.segments().is_empty() => {
-                match (path.kind, explicitness) {
-                    (PathKind::SELF, VisibilityExplicitness::Explicit) => {
-                        RawVisibilityId::PRIV_EXPLICIT
-                    }
-                    (PathKind::SELF, VisibilityExplicitness::Implicit) => {
-                        RawVisibilityId::PRIV_IMPLICIT
-                    }
-                    (PathKind::Crate, _) => RawVisibilityId::PUB_CRATE,
-                    _ => RawVisibilityId(self.visibilities.insert_full(vis).0 as u32),
-                }
+            RawVisibility::PubSelf(VisibilityExplicitness::Explicit) => {
+                RawVisibilityId::PRIV_EXPLICIT
             }
+            RawVisibility::PubSelf(VisibilityExplicitness::Implicit) => {
+                RawVisibilityId::PRIV_IMPLICIT
+            }
+            RawVisibility::PubCrate => RawVisibilityId::PUB_CRATE,
             _ => RawVisibilityId(self.visibilities.insert_full(vis).0 as u32),
         }
     }
@@ -466,10 +461,7 @@
 }
 
 fn private_vis() -> RawVisibility {
-    RawVisibility::Module(
-        Interned::new(ModPath::from_kind(PathKind::SELF)),
-        VisibilityExplicitness::Implicit,
-    )
+    RawVisibility::PubSelf(VisibilityExplicitness::Implicit)
 }
 
 pub(crate) fn visibility_from_ast(
@@ -486,9 +478,11 @@
                 Some(path) => path,
             }
         }
-        ast::VisibilityKind::PubCrate => ModPath::from_kind(PathKind::Crate),
+        ast::VisibilityKind::PubCrate => return RawVisibility::PubCrate,
         ast::VisibilityKind::PubSuper => ModPath::from_kind(PathKind::Super(1)),
-        ast::VisibilityKind::PubSelf => ModPath::from_kind(PathKind::SELF),
+        ast::VisibilityKind::PubSelf => {
+            return RawVisibility::PubSelf(VisibilityExplicitness::Explicit);
+        }
         ast::VisibilityKind::Pub => return RawVisibility::Public,
     };
     RawVisibility::Module(Interned::new(path), VisibilityExplicitness::Explicit)
diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs
index 698292c..abcf0a3 100644
--- a/crates/hir-def/src/resolver.rs
+++ b/crates/hir-def/src/resolver.rs
@@ -1075,7 +1075,9 @@
         if let Some(block) = scopes.block(scope) {
             let def_map = block_def_map(db, block);
             let local_def_map = block.lookup(db).module.only_local_def_map(db);
-            r = r.push_block_scope(def_map, local_def_map);
+            // Using `DefMap::ROOT` is okay here since inside modules other than the root,
+            // there can't directly be expressions.
+            r = r.push_block_scope(def_map, local_def_map, DefMap::ROOT);
             // FIXME: This adds as many module scopes as there are blocks, but resolving in each
             // already traverses all parents, so this is O(n²). I think we could only store the
             // innermost module scope instead?
@@ -1108,12 +1110,9 @@
         self,
         def_map: &'db DefMap,
         local_def_map: &'db LocalDefMap,
+        module_id: LocalModuleId,
     ) -> Resolver<'db> {
-        self.push_scope(Scope::BlockScope(ModuleItemMap {
-            def_map,
-            local_def_map,
-            module_id: DefMap::ROOT,
-        }))
+        self.push_scope(Scope::BlockScope(ModuleItemMap { def_map, local_def_map, module_id }))
     }
 
     fn push_expr_scope(
@@ -1273,7 +1272,7 @@
         let (mut def_map, local_def_map) = self.local_def_map(db);
         let mut module_id = self.local_id;
 
-        if !self.is_block_module() {
+        if !self.is_within_block() {
             return Resolver {
                 scopes: vec![],
                 module_scope: ModuleItemMap { def_map, local_def_map, module_id },
@@ -1283,9 +1282,9 @@
         let mut modules: SmallVec<[_; 1]> = smallvec![];
         while let Some(parent) = def_map.parent() {
             let block_def_map = mem::replace(&mut def_map, parent.def_map(db));
-            modules.push(block_def_map);
-            if !parent.is_block_module() {
-                module_id = parent.local_id;
+            let block_module_id = mem::replace(&mut module_id, parent.local_id);
+            modules.push((block_def_map, block_module_id));
+            if !parent.is_within_block() {
                 break;
             }
         }
@@ -1293,8 +1292,8 @@
             scopes: Vec::with_capacity(modules.len()),
             module_scope: ModuleItemMap { def_map, local_def_map, module_id },
         };
-        for def_map in modules.into_iter().rev() {
-            resolver = resolver.push_block_scope(def_map, local_def_map);
+        for (def_map, module_id) in modules.into_iter().rev() {
+            resolver = resolver.push_block_scope(def_map, local_def_map, module_id);
         }
         resolver
     }
diff --git a/crates/hir-def/src/visibility.rs b/crates/hir-def/src/visibility.rs
index b5eb84c..948f6ed 100644
--- a/crates/hir-def/src/visibility.rs
+++ b/crates/hir-def/src/visibility.rs
@@ -289,18 +289,21 @@
 
 pub fn visibility_from_ast(
     db: &dyn DefDatabase,
-    has_resolver: impl HasResolver,
+    has_resolver: impl HasResolver + HasModule,
     ast_vis: InFile<Option<ast::Visibility>>,
 ) -> Visibility {
     let mut span_map = None;
     let raw_vis = crate::item_tree::visibility_from_ast(db, ast_vis.value, &mut |range| {
         span_map.get_or_insert_with(|| db.span_map(ast_vis.file_id)).span_for_range(range).ctx
     });
-    if raw_vis == RawVisibility::Public {
-        return Visibility::Public;
+    match raw_vis {
+        RawVisibility::PubSelf(explicitness) => {
+            Visibility::Module(has_resolver.module(db), explicitness)
+        }
+        RawVisibility::PubCrate => Visibility::PubCrate(has_resolver.krate(db)),
+        RawVisibility::Public => Visibility::Public,
+        RawVisibility::Module(..) => Visibility::resolve(db, &has_resolver.resolver(db), &raw_vis),
     }
-
-    Visibility::resolve(db, &has_resolver.resolver(db), &raw_vis)
 }
 
 /// Resolve visibility of a type alias.
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index dd1b212..0a37966 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -2078,9 +2078,10 @@
             if vis_id == module_id {
                 // pub(self) or omitted
                 Ok(())
-            } else if root_module_id == vis_id {
+            } else if root_module_id == vis_id && !root_module_id.is_within_block() {
                 write!(f, "pub(crate) ")
-            } else if module_id.containing_module(f.db) == Some(vis_id) {
+            } else if module_id.containing_module(f.db) == Some(vis_id) && !vis_id.is_block_module()
+            {
                 write!(f, "pub(super) ")
             } else {
                 write!(f, "pub(in ...) ")
diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index 7c79393..118ea88 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/crates/hir-ty/src/tests/regression.rs
@@ -2506,3 +2506,19 @@
 "#,
     );
 }
+
+#[test]
+fn foo() {
+    check_types(
+        r#"
+fn foo() {
+    mod my_mod {
+        pub type Bool = bool;
+    }
+
+    let _: my_mod::Bool;
+     // ^ bool
+}
+    "#,
+    );
+}
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 15eab14..f994ed2 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -1594,14 +1594,12 @@
             Some(unresolved) => resolver
                 .generic_def()
                 .and_then(|def| {
-                    hir_ty::attach_db(db, || {
-                        hir_ty::associated_type_shorthand_candidates(
-                            db,
-                            def,
-                            res.in_type_ns()?,
-                            |name, _| name == unresolved.name,
-                        )
-                    })
+                    hir_ty::associated_type_shorthand_candidates(
+                        db,
+                        def,
+                        res.in_type_ns()?,
+                        |name, _| name == unresolved.name,
+                    )
                 })
                 .map(TypeAlias::from)
                 .map(Into::into)
diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs
index f1d076e..018c841 100644
--- a/crates/ide-db/src/search.rs
+++ b/crates/ide-db/src/search.rs
@@ -387,12 +387,14 @@
             return SearchScope::reverse_dependencies(db, module.krate());
         }
 
-        let vis = self.visibility(db);
-        if let Some(Visibility::Public) = vis {
-            return SearchScope::reverse_dependencies(db, module.krate());
-        }
-        if let Some(Visibility::Module(module, _)) = vis {
-            return SearchScope::module_and_children(db, module.into());
+        if let Some(vis) = self.visibility(db) {
+            return match vis {
+                Visibility::Module(module, _) => {
+                    SearchScope::module_and_children(db, module.into())
+                }
+                Visibility::PubCrate(krate) => SearchScope::krate(db, krate.into()),
+                Visibility::Public => SearchScope::reverse_dependencies(db, module.krate()),
+            };
         }
 
         let range = match module_source {
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html b/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html
index 3beda39..711f534 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html
@@ -53,7 +53,7 @@
         <span class="macro public">foo</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="struct declaration macro public">Bar</span><span class="parenthesis">)</span><span class="semicolon">;</span>
         <span class="keyword">fn</span> <span class="function declaration">func</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="module">y</span><span class="operator">::</span><span class="struct public">Bar</span><span class="parenthesis">)</span> <span class="brace">{</span>
             <span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="brace">{</span>
-                <span class="keyword">struct</span> <span class="struct declaration">Innerest</span><span class="angle">&lt;</span><span class="keyword const">const</span> <span class="const_param const declaration">C</span><span class="colon">:</span> <span class="unresolved_reference">usize</span><span class="angle">&gt;</span> <span class="brace">{</span> <span class="field declaration">field</span><span class="colon">:</span> <span class="bracket">[</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="brace">{</span><span class="const_param const">C</span><span class="brace">}</span><span class="bracket">]</span> <span class="brace">}</span>
+                <span class="keyword">struct</span> <span class="struct declaration">Innerest</span><span class="angle">&lt;</span><span class="keyword const">const</span> <span class="const_param const declaration">C</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="angle">&gt;</span> <span class="brace">{</span> <span class="field declaration">field</span><span class="colon">:</span> <span class="bracket">[</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="brace">{</span><span class="const_param const">C</span><span class="brace">}</span><span class="bracket">]</span> <span class="brace">}</span>
             <span class="brace">}</span>
         <span class="brace">}</span>
     <span class="brace">}</span>