Skip to content

Commit 83e24fe

Browse files
committed
Fix associated item visibility in block-local impls
1 parent 4438017 commit 83e24fe

File tree

5 files changed

+52
-8
lines changed

5 files changed

+52
-8
lines changed

crates/hir-def/src/nameres/collector.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -666,8 +666,10 @@ impl DefCollector<'_> {
666666
macro_: Macro2Id,
667667
vis: &RawVisibility,
668668
) {
669-
let vis =
670-
self.def_map.resolve_visibility(self.db, module_id, vis).unwrap_or(Visibility::Public);
669+
let vis = self
670+
.def_map
671+
.resolve_visibility(self.db, module_id, vis, false)
672+
.unwrap_or(Visibility::Public);
671673
self.def_map.modules[module_id].scope.declare(macro_.into());
672674
self.update(
673675
module_id,
@@ -831,7 +833,7 @@ impl DefCollector<'_> {
831833
let mut def = directive.status.namespaces();
832834
let vis = self
833835
.def_map
834-
.resolve_visibility(self.db, module_id, &directive.import.visibility)
836+
.resolve_visibility(self.db, module_id, &directive.import.visibility, false)
835837
.unwrap_or(Visibility::Public);
836838

837839
match import.kind {
@@ -1547,7 +1549,7 @@ impl ModCollector<'_, '_> {
15471549
};
15481550
let resolve_vis = |def_map: &DefMap, visibility| {
15491551
def_map
1550-
.resolve_visibility(db, self.module_id, visibility)
1552+
.resolve_visibility(db, self.module_id, visibility, false)
15511553
.unwrap_or(Visibility::Public)
15521554
};
15531555

@@ -1823,7 +1825,7 @@ impl ModCollector<'_, '_> {
18231825
) -> LocalModuleId {
18241826
let def_map = &mut self.def_collector.def_map;
18251827
let vis = def_map
1826-
.resolve_visibility(self.def_collector.db, self.module_id, visibility)
1828+
.resolve_visibility(self.def_collector.db, self.module_id, visibility, false)
18271829
.unwrap_or(Visibility::Public);
18281830
let modules = &mut def_map.modules;
18291831
let origin = match definition {

crates/hir-def/src/nameres/path_resolution.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ impl DefMap {
7878
// pub(path)
7979
// ^^^^ this
8080
visibility: &RawVisibility,
81+
within_impl: bool,
8182
) -> Option<Visibility> {
8283
let mut vis = match visibility {
8384
RawVisibility::Module(path) => {
@@ -102,7 +103,8 @@ impl DefMap {
102103
// `super` to its parent (etc.). However, visibilities must only refer to a module in the
103104
// DefMap they're written in, so we restrict them when that happens.
104105
if let Visibility::Module(m) = vis {
105-
if self.block_id() != m.block {
106+
// ...unless we're resolving visibility for an associated item in an impl.
107+
if self.block_id() != m.block && !within_impl {
106108
cov_mark::hit!(adjust_vis_in_block_def_map);
107109
vis = Visibility::Module(self.module_id(self.root()));
108110
tracing::debug!("visibility {:?} points outside DefMap, adjusting to {:?}", m, vis);

crates/hir-def/src/resolver.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,12 @@ impl Resolver {
214214
db: &dyn DefDatabase,
215215
visibility: &RawVisibility,
216216
) -> Option<Visibility> {
217+
let within_impl =
218+
self.scopes().find(|scope| matches!(scope, Scope::ImplDefScope(_))).is_some();
217219
match visibility {
218220
RawVisibility::Module(_) => {
219221
let (item_map, module) = self.item_scope();
220-
item_map.resolve_visibility(db, module, visibility)
222+
item_map.resolve_visibility(db, module, visibility, within_impl)
221223
}
222224
RawVisibility::Public => Some(Visibility::Public),
223225
}

crates/hir-def/src/visibility.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ impl Visibility {
120120
self,
121121
db: &dyn DefDatabase,
122122
def_map: &DefMap,
123-
mut from_module: crate::LocalModuleId,
123+
mut from_module: LocalModuleId,
124124
) -> bool {
125125
let mut to_module = match self {
126126
Visibility::Module(m) => m,

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,44 @@ mod module {
115115
fn main(s: module::Struct) {
116116
s.method();
117117
}
118+
"#,
119+
);
120+
}
121+
122+
#[test]
123+
fn can_see_through_top_level_anonymous_const() {
124+
// regression test for #14046.
125+
check_diagnostics(
126+
r#"
127+
struct S;
128+
mod m {
129+
const _: () = {
130+
impl crate::S {
131+
pub(crate) fn method(self) {}
132+
pub(crate) const A: usize = 42;
133+
}
134+
};
135+
mod inner {
136+
const _: () = {
137+
impl crate::S {
138+
pub(crate) fn method2(self) {}
139+
pub(crate) const B: usize = 42;
140+
pub(super) fn private(self) {}
141+
pub(super) const PRIVATE: usize = 42;
142+
}
143+
};
144+
}
145+
}
146+
fn main() {
147+
S.method();
148+
S::A;
149+
S.method2();
150+
S::B;
151+
S.private();
152+
//^^^^^^^^^^^ error: function `private` is private
153+
S::PRIVATE;
154+
//^^^^^^^^^^ error: const `PRIVATE` is private
155+
}
118156
"#,
119157
);
120158
}

0 commit comments

Comments
 (0)