diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs index 454e063995..db50e6585d 100644 --- a/crates/hir-def/src/item_tree/lower.rs +++ b/crates/hir-def/src/item_tree/lower.rs @@ -370,18 +370,13 @@ impl<'a> Ctx<'a> { }); 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 @@ pub(crate) fn lower_use_tree( } 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 @@ pub(crate) fn visibility_from_ast( 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 698292c2fb..abcf0a397c 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -1075,7 +1075,9 @@ fn resolver_for_scope_<'db>( 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 @@ impl<'db> Resolver<'db> { 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 @@ impl HasResolver for ModuleId { 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 @@ impl HasResolver for ModuleId { 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 @@ impl HasResolver for ModuleId { 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 b5eb84c25f..948f6ed8c3 100644 --- a/crates/hir-def/src/visibility.rs +++ b/crates/hir-def/src/visibility.rs @@ -289,18 +289,21 @@ pub(crate) fn field_visibilities_query( pub fn visibility_from_ast( db: &dyn DefDatabase, - has_resolver: impl HasResolver, + has_resolver: impl HasResolver + HasModule, ast_vis: InFile>, ) -> 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 dd1b212d4c..0a3796687f 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -2078,9 +2078,10 @@ pub fn write_visibility<'db>( 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 7c79393e65..118ea88f7b 100644 --- a/crates/hir-ty/src/tests/regression.rs +++ b/crates/hir-ty/src/tests/regression.rs @@ -2506,3 +2506,19 @@ fn main() { "#, ); } + +#[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 15eab14b88..f994ed26ca 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -1594,14 +1594,12 @@ fn resolve_hir_path_( 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 f1d076e874..018c841897 100644 --- a/crates/ide-db/src/search.rs +++ b/crates/ide-db/src/search.rs @@ -387,12 +387,14 @@ impl Definition { 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 3beda396da..711f5344ae 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 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd foo!(Bar); fn func(_: y::Bar) { mod inner { - struct Innerest<const C: usize> { field: [(); {C}] } + struct Innerest<const C: usize> { field: [(); {C}] } } } }