mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 05:53:45 +00:00
Fix associated item visibility in block-local impls
This commit is contained in:
parent
443801755c
commit
83e24fec98
5 changed files with 52 additions and 8 deletions
|
@ -666,8 +666,10 @@ impl DefCollector<'_> {
|
||||||
macro_: Macro2Id,
|
macro_: Macro2Id,
|
||||||
vis: &RawVisibility,
|
vis: &RawVisibility,
|
||||||
) {
|
) {
|
||||||
let vis =
|
let vis = self
|
||||||
self.def_map.resolve_visibility(self.db, module_id, vis).unwrap_or(Visibility::Public);
|
.def_map
|
||||||
|
.resolve_visibility(self.db, module_id, vis, false)
|
||||||
|
.unwrap_or(Visibility::Public);
|
||||||
self.def_map.modules[module_id].scope.declare(macro_.into());
|
self.def_map.modules[module_id].scope.declare(macro_.into());
|
||||||
self.update(
|
self.update(
|
||||||
module_id,
|
module_id,
|
||||||
|
@ -831,7 +833,7 @@ impl DefCollector<'_> {
|
||||||
let mut def = directive.status.namespaces();
|
let mut def = directive.status.namespaces();
|
||||||
let vis = self
|
let vis = self
|
||||||
.def_map
|
.def_map
|
||||||
.resolve_visibility(self.db, module_id, &directive.import.visibility)
|
.resolve_visibility(self.db, module_id, &directive.import.visibility, false)
|
||||||
.unwrap_or(Visibility::Public);
|
.unwrap_or(Visibility::Public);
|
||||||
|
|
||||||
match import.kind {
|
match import.kind {
|
||||||
|
@ -1547,7 +1549,7 @@ impl ModCollector<'_, '_> {
|
||||||
};
|
};
|
||||||
let resolve_vis = |def_map: &DefMap, visibility| {
|
let resolve_vis = |def_map: &DefMap, visibility| {
|
||||||
def_map
|
def_map
|
||||||
.resolve_visibility(db, self.module_id, visibility)
|
.resolve_visibility(db, self.module_id, visibility, false)
|
||||||
.unwrap_or(Visibility::Public)
|
.unwrap_or(Visibility::Public)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1823,7 +1825,7 @@ impl ModCollector<'_, '_> {
|
||||||
) -> LocalModuleId {
|
) -> LocalModuleId {
|
||||||
let def_map = &mut self.def_collector.def_map;
|
let def_map = &mut self.def_collector.def_map;
|
||||||
let vis = def_map
|
let vis = def_map
|
||||||
.resolve_visibility(self.def_collector.db, self.module_id, visibility)
|
.resolve_visibility(self.def_collector.db, self.module_id, visibility, false)
|
||||||
.unwrap_or(Visibility::Public);
|
.unwrap_or(Visibility::Public);
|
||||||
let modules = &mut def_map.modules;
|
let modules = &mut def_map.modules;
|
||||||
let origin = match definition {
|
let origin = match definition {
|
||||||
|
|
|
@ -78,6 +78,7 @@ impl DefMap {
|
||||||
// pub(path)
|
// pub(path)
|
||||||
// ^^^^ this
|
// ^^^^ this
|
||||||
visibility: &RawVisibility,
|
visibility: &RawVisibility,
|
||||||
|
within_impl: bool,
|
||||||
) -> Option<Visibility> {
|
) -> Option<Visibility> {
|
||||||
let mut vis = match visibility {
|
let mut vis = match visibility {
|
||||||
RawVisibility::Module(path) => {
|
RawVisibility::Module(path) => {
|
||||||
|
@ -102,7 +103,8 @@ impl DefMap {
|
||||||
// `super` to its parent (etc.). However, visibilities must only refer to a module in the
|
// `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.
|
// DefMap they're written in, so we restrict them when that happens.
|
||||||
if let Visibility::Module(m) = vis {
|
if let Visibility::Module(m) = vis {
|
||||||
if self.block_id() != m.block {
|
// ...unless we're resolving visibility for an associated item in an impl.
|
||||||
|
if self.block_id() != m.block && !within_impl {
|
||||||
cov_mark::hit!(adjust_vis_in_block_def_map);
|
cov_mark::hit!(adjust_vis_in_block_def_map);
|
||||||
vis = Visibility::Module(self.module_id(self.root()));
|
vis = Visibility::Module(self.module_id(self.root()));
|
||||||
tracing::debug!("visibility {:?} points outside DefMap, adjusting to {:?}", m, vis);
|
tracing::debug!("visibility {:?} points outside DefMap, adjusting to {:?}", m, vis);
|
||||||
|
|
|
@ -214,10 +214,12 @@ impl Resolver {
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
visibility: &RawVisibility,
|
visibility: &RawVisibility,
|
||||||
) -> Option<Visibility> {
|
) -> Option<Visibility> {
|
||||||
|
let within_impl =
|
||||||
|
self.scopes().find(|scope| matches!(scope, Scope::ImplDefScope(_))).is_some();
|
||||||
match visibility {
|
match visibility {
|
||||||
RawVisibility::Module(_) => {
|
RawVisibility::Module(_) => {
|
||||||
let (item_map, module) = self.item_scope();
|
let (item_map, module) = self.item_scope();
|
||||||
item_map.resolve_visibility(db, module, visibility)
|
item_map.resolve_visibility(db, module, visibility, within_impl)
|
||||||
}
|
}
|
||||||
RawVisibility::Public => Some(Visibility::Public),
|
RawVisibility::Public => Some(Visibility::Public),
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ impl Visibility {
|
||||||
self,
|
self,
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
def_map: &DefMap,
|
def_map: &DefMap,
|
||||||
mut from_module: crate::LocalModuleId,
|
mut from_module: LocalModuleId,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut to_module = match self {
|
let mut to_module = match self {
|
||||||
Visibility::Module(m) => m,
|
Visibility::Module(m) => m,
|
||||||
|
|
|
@ -115,6 +115,44 @@ mod module {
|
||||||
fn main(s: module::Struct) {
|
fn main(s: module::Struct) {
|
||||||
s.method();
|
s.method();
|
||||||
}
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_see_through_top_level_anonymous_const() {
|
||||||
|
// regression test for #14046.
|
||||||
|
check_diagnostics(
|
||||||
|
r#"
|
||||||
|
struct S;
|
||||||
|
mod m {
|
||||||
|
const _: () = {
|
||||||
|
impl crate::S {
|
||||||
|
pub(crate) fn method(self) {}
|
||||||
|
pub(crate) const A: usize = 42;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mod inner {
|
||||||
|
const _: () = {
|
||||||
|
impl crate::S {
|
||||||
|
pub(crate) fn method2(self) {}
|
||||||
|
pub(crate) const B: usize = 42;
|
||||||
|
pub(super) fn private(self) {}
|
||||||
|
pub(super) const PRIVATE: usize = 42;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
S.method();
|
||||||
|
S::A;
|
||||||
|
S.method2();
|
||||||
|
S::B;
|
||||||
|
S.private();
|
||||||
|
//^^^^^^^^^^^ error: function `private` is private
|
||||||
|
S::PRIVATE;
|
||||||
|
//^^^^^^^^^^ error: const `PRIVATE` is private
|
||||||
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue