Auto merge of #92781 - lambinoo:I-92755-no-mir-missing-reachable, r=petrochenkov
Set struct/union/enum fields/variants as reachable when item is Fixes #92755
This commit is contained in:
commit
86f7f78f05
@ -652,12 +652,73 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||
_ => self.get(item.def_id),
|
||||
};
|
||||
|
||||
// Update levels of nested things.
|
||||
match item.kind {
|
||||
hir::ItemKind::Enum(ref def, _) => {
|
||||
for variant in def.variants {
|
||||
let variant_level = self.update_with_hir_id(variant.id, item_level);
|
||||
if let Some(ctor_hir_id) = variant.data.ctor_hir_id() {
|
||||
self.update_with_hir_id(ctor_hir_id, item_level);
|
||||
}
|
||||
for field in variant.data.fields() {
|
||||
self.update_with_hir_id(field.hir_id, variant_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ItemKind::Impl(ref impl_) => {
|
||||
for impl_item_ref in impl_.items {
|
||||
if impl_.of_trait.is_some()
|
||||
|| self.tcx.visibility(impl_item_ref.id.def_id) == ty::Visibility::Public
|
||||
{
|
||||
self.update(impl_item_ref.id.def_id, item_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ItemKind::Trait(.., trait_item_refs) => {
|
||||
for trait_item_ref in trait_item_refs {
|
||||
self.update(trait_item_ref.id.def_id, item_level);
|
||||
}
|
||||
}
|
||||
hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => {
|
||||
if let Some(ctor_hir_id) = def.ctor_hir_id() {
|
||||
self.update_with_hir_id(ctor_hir_id, item_level);
|
||||
}
|
||||
for field in def.fields() {
|
||||
if field.vis.node.is_pub() {
|
||||
self.update_with_hir_id(field.hir_id, item_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ItemKind::Macro(ref macro_def) => {
|
||||
self.update_reachability_from_macro(item.def_id, macro_def);
|
||||
}
|
||||
hir::ItemKind::ForeignMod { items, .. } => {
|
||||
for foreign_item in items {
|
||||
if self.tcx.visibility(foreign_item.id.def_id) == ty::Visibility::Public {
|
||||
self.update(foreign_item.id.def_id, item_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hir::ItemKind::OpaqueTy(..)
|
||||
| hir::ItemKind::Use(..)
|
||||
| hir::ItemKind::Static(..)
|
||||
| hir::ItemKind::Const(..)
|
||||
| hir::ItemKind::GlobalAsm(..)
|
||||
| hir::ItemKind::TyAlias(..)
|
||||
| hir::ItemKind::Mod(..)
|
||||
| hir::ItemKind::TraitAlias(..)
|
||||
| hir::ItemKind::Fn(..)
|
||||
| hir::ItemKind::ExternCrate(..) => {}
|
||||
}
|
||||
|
||||
// Mark all items in interfaces of reachable items as reachable.
|
||||
match item.kind {
|
||||
// The interface is empty.
|
||||
hir::ItemKind::ExternCrate(..) => {}
|
||||
hir::ItemKind::Macro(..) | hir::ItemKind::ExternCrate(..) => {}
|
||||
// All nested items are checked by `visit_item`.
|
||||
hir::ItemKind::Mod(..) => {}
|
||||
// Handled in the access level of in rustc_resolve
|
||||
hir::ItemKind::Use(..) => {}
|
||||
// The interface is empty.
|
||||
hir::ItemKind::GlobalAsm(..) => {}
|
||||
@ -709,14 +770,6 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||
}
|
||||
// Visit everything except for private impl items.
|
||||
hir::ItemKind::Impl(ref impl_) => {
|
||||
for impl_item_ref in impl_.items {
|
||||
if impl_.of_trait.is_some()
|
||||
|| self.tcx.visibility(impl_item_ref.id.def_id) == ty::Visibility::Public
|
||||
{
|
||||
self.update(impl_item_ref.id.def_id, item_level);
|
||||
}
|
||||
}
|
||||
|
||||
if item_level.is_some() {
|
||||
self.reach(item.def_id, item_level).generics().predicates().ty().trait_ref();
|
||||
|
||||
@ -731,21 +784,15 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Visit everything, but enum variants have their own levels.
|
||||
hir::ItemKind::Enum(ref def, _) => {
|
||||
if item_level.is_some() {
|
||||
self.reach(item.def_id, item_level).generics().predicates();
|
||||
}
|
||||
|
||||
let enum_level = self.get(item.def_id);
|
||||
for variant in def.variants {
|
||||
let variant_level = self.update_with_hir_id(variant.id, enum_level);
|
||||
|
||||
let variant_level = self.get(self.tcx.hir().local_def_id(variant.id));
|
||||
if variant_level.is_some() {
|
||||
if let Some(ctor_id) = variant.data.ctor_hir_id() {
|
||||
self.update_with_hir_id(ctor_id, variant_level);
|
||||
}
|
||||
|
||||
for field in variant.data.fields() {
|
||||
self.reach(self.tcx.hir().local_def_id(field.hir_id), variant_level)
|
||||
.ty();
|
||||
@ -756,9 +803,6 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ItemKind::Macro(ref macro_def) => {
|
||||
self.update_reachability_from_macro(item.def_id, macro_def);
|
||||
}
|
||||
// Visit everything, but foreign items have their own levels.
|
||||
hir::ItemKind::ForeignMod { items, .. } => {
|
||||
for foreign_item in items {
|
||||
|
17
src/test/ui/privacy/auxiliary/issue-92755.rs
Normal file
17
src/test/ui/privacy/auxiliary/issue-92755.rs
Normal file
@ -0,0 +1,17 @@
|
||||
mod machine {
|
||||
pub struct A {
|
||||
pub b: B,
|
||||
}
|
||||
pub struct B {}
|
||||
impl B {
|
||||
pub fn f(&self) {}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
pub a: machine::A,
|
||||
}
|
||||
|
||||
pub fn ctx() -> Context {
|
||||
todo!();
|
||||
}
|
10
src/test/ui/privacy/issue-92755.rs
Normal file
10
src/test/ui/privacy/issue-92755.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// aux-build:issue-92755.rs
|
||||
// build-pass
|
||||
|
||||
// Thank you @tmiasko for providing the content of this test!
|
||||
|
||||
extern crate issue_92755;
|
||||
|
||||
fn main() {
|
||||
issue_92755::ctx().a.b.f();
|
||||
}
|
Loading…
Reference in New Issue
Block a user