Auto merge of #14176 - lowr:fix/assoc-func-vis-in-local-impl, r=Veykril

Fix associated item visibility in block-local impls

Fixes #14046

When we're resolving visibility of block-local items...

> `self` normally refers to the containing non-block module, and `super` to its parent (etc.). However, visibilities must only refer to a module in the DefMap they're written in, so we restrict them when that happens. ([link])

 ...unless we're resolving visibility of associated items in block-local impls, because that impl is semantically "hoisted" to the nearest (non-block) module. With this PR, we skip the adjustment for such items.

Since visibility representation of those items is modified, this PR also adjusts visibility rendering in `HirDisplay`.

[link]: a6603fc21d/crates/hir-def/src/nameres/path_resolution.rs (L101-L103)
This commit is contained in:
bors 2023-03-01 12:40:55 +00:00
commit 32424d0aba
10 changed files with 282 additions and 30 deletions

View file

@ -46,7 +46,7 @@ use hir_def::{
item_tree::ItemTreeNode,
lang_item::{LangItem, LangItemTarget},
layout::{Layout, LayoutError, ReprOptions},
nameres::{self, diagnostics::DefDiagnostic},
nameres::{self, diagnostics::DefDiagnostic, ModuleOrigin},
per_ns::PerNs,
resolver::{HasResolver, Resolver},
src::HasSource as _,
@ -488,6 +488,20 @@ impl Module {
Some(Module { id: def_map.module_id(parent_id) })
}
/// Finds nearest non-block ancestor `Module` (`self` included).
fn nearest_non_block_module(self, db: &dyn HirDatabase) -> Module {
let mut id = self.id;
loop {
let def_map = id.def_map(db.upcast());
let origin = def_map[id.local_id].origin;
if matches!(origin, ModuleOrigin::BlockExpr { .. }) {
id = id.containing_module(db.upcast()).expect("block without parent module")
} else {
return Module { id };
}
}
}
pub fn path_to_root(self, db: &dyn HirDatabase) -> Vec<Module> {
let mut res = vec![self];
let mut curr = self;