Skip to content

Commit 74303a3

Browse files
committed
Auto merge of rust-lang#14349 - Veykril:vis-res, r=Veykril
fix: Fix visibility resolution not respecting parent blocks Fixes rust-lang/rust-analyzer#14047
2 parents 6f297b9 + 1a9fbf0 commit 74303a3

File tree

3 files changed

+37
-15
lines changed

3 files changed

+37
-15
lines changed

crates/hir-def/src/nameres.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ pub struct ModuleData {
215215
pub origin: ModuleOrigin,
216216
/// Declared visibility of this module.
217217
pub visibility: Visibility,
218-
218+
/// Always [`None`] for block modules
219219
pub parent: Option<LocalModuleId>,
220220
pub children: FxHashMap<Name, LocalModuleId>,
221221
pub scope: ItemScope,
@@ -429,7 +429,7 @@ impl DefMap {
429429
Some(self.block?.parent)
430430
}
431431

432-
/// Returns the module containing `local_mod`, either the parent `mod`, or the module containing
432+
/// Returns the module containing `local_mod`, either the parent `mod`, or the module (or block) containing
433433
/// the block, if `self` corresponds to a block expression.
434434
pub fn containing_module(&self, local_mod: LocalModuleId) -> Option<ModuleId> {
435435
match self[local_mod].parent {

crates/hir-def/src/visibility.rs

+15-13
Original file line numberDiff line numberDiff line change
@@ -131,21 +131,23 @@ impl Visibility {
131131
// visibility as the containing module (even though no items are directly nameable from
132132
// there, getting this right is important for method resolution).
133133
// In that case, we adjust the visibility of `to_module` to point to the containing module.
134+
134135
// Additional complication: `to_module` might be in `from_module`'s `DefMap`, which we're
135136
// currently computing, so we must not call the `def_map` query for it.
136-
let arc;
137-
let to_module_def_map =
138-
if to_module.krate == def_map.krate() && to_module.block == def_map.block_id() {
139-
cov_mark::hit!(is_visible_from_same_block_def_map);
140-
def_map
141-
} else {
142-
arc = to_module.def_map(db);
143-
&arc
144-
};
145-
let is_block_root =
146-
to_module.block.is_some() && to_module_def_map[to_module.local_id].parent.is_none();
147-
if is_block_root {
148-
to_module = to_module_def_map.containing_module(to_module.local_id).unwrap();
137+
let mut arc;
138+
loop {
139+
let to_module_def_map =
140+
if to_module.krate == def_map.krate() && to_module.block == def_map.block_id() {
141+
cov_mark::hit!(is_visible_from_same_block_def_map);
142+
def_map
143+
} else {
144+
arc = to_module.def_map(db);
145+
&arc
146+
};
147+
match to_module_def_map.parent() {
148+
Some(parent) => to_module = parent,
149+
None => break,
150+
}
149151
}
150152

151153
// from_module needs to be a descendant of to_module

crates/ide-diagnostics/src/handlers/private_field.rs

+20
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,26 @@ mod module {
6262
fn main(s: module::Struct) {
6363
s.field;
6464
}
65+
"#,
66+
);
67+
}
68+
69+
#[test]
70+
fn block_module_madness() {
71+
check_diagnostics(
72+
r#"
73+
fn main() {
74+
let strukt = {
75+
use crate as ForceParentBlockDefMap;
76+
{
77+
pub struct Struct {
78+
field: (),
79+
}
80+
Struct { field: () }
81+
}
82+
};
83+
strukt.field;
84+
}
6585
"#,
6686
);
6787
}

0 commit comments

Comments
 (0)