Skip to content

Commit 86f7f78

Browse files
committed
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
2 parents f312a5e + 1b2c64d commit 86f7f78

File tree

3 files changed

+91
-20
lines changed

3 files changed

+91
-20
lines changed

compiler/rustc_privacy/src/lib.rs

+64-20
Original file line numberDiff line numberDiff line change
@@ -652,12 +652,73 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
652652
_ => self.get(item.def_id),
653653
};
654654

655+
// Update levels of nested things.
656+
match item.kind {
657+
hir::ItemKind::Enum(ref def, _) => {
658+
for variant in def.variants {
659+
let variant_level = self.update_with_hir_id(variant.id, item_level);
660+
if let Some(ctor_hir_id) = variant.data.ctor_hir_id() {
661+
self.update_with_hir_id(ctor_hir_id, item_level);
662+
}
663+
for field in variant.data.fields() {
664+
self.update_with_hir_id(field.hir_id, variant_level);
665+
}
666+
}
667+
}
668+
hir::ItemKind::Impl(ref impl_) => {
669+
for impl_item_ref in impl_.items {
670+
if impl_.of_trait.is_some()
671+
|| self.tcx.visibility(impl_item_ref.id.def_id) == ty::Visibility::Public
672+
{
673+
self.update(impl_item_ref.id.def_id, item_level);
674+
}
675+
}
676+
}
677+
hir::ItemKind::Trait(.., trait_item_refs) => {
678+
for trait_item_ref in trait_item_refs {
679+
self.update(trait_item_ref.id.def_id, item_level);
680+
}
681+
}
682+
hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => {
683+
if let Some(ctor_hir_id) = def.ctor_hir_id() {
684+
self.update_with_hir_id(ctor_hir_id, item_level);
685+
}
686+
for field in def.fields() {
687+
if field.vis.node.is_pub() {
688+
self.update_with_hir_id(field.hir_id, item_level);
689+
}
690+
}
691+
}
692+
hir::ItemKind::Macro(ref macro_def) => {
693+
self.update_reachability_from_macro(item.def_id, macro_def);
694+
}
695+
hir::ItemKind::ForeignMod { items, .. } => {
696+
for foreign_item in items {
697+
if self.tcx.visibility(foreign_item.id.def_id) == ty::Visibility::Public {
698+
self.update(foreign_item.id.def_id, item_level);
699+
}
700+
}
701+
}
702+
703+
hir::ItemKind::OpaqueTy(..)
704+
| hir::ItemKind::Use(..)
705+
| hir::ItemKind::Static(..)
706+
| hir::ItemKind::Const(..)
707+
| hir::ItemKind::GlobalAsm(..)
708+
| hir::ItemKind::TyAlias(..)
709+
| hir::ItemKind::Mod(..)
710+
| hir::ItemKind::TraitAlias(..)
711+
| hir::ItemKind::Fn(..)
712+
| hir::ItemKind::ExternCrate(..) => {}
713+
}
714+
655715
// Mark all items in interfaces of reachable items as reachable.
656716
match item.kind {
657717
// The interface is empty.
658-
hir::ItemKind::ExternCrate(..) => {}
718+
hir::ItemKind::Macro(..) | hir::ItemKind::ExternCrate(..) => {}
659719
// All nested items are checked by `visit_item`.
660720
hir::ItemKind::Mod(..) => {}
721+
// Handled in the access level of in rustc_resolve
661722
hir::ItemKind::Use(..) => {}
662723
// The interface is empty.
663724
hir::ItemKind::GlobalAsm(..) => {}
@@ -709,14 +770,6 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
709770
}
710771
// Visit everything except for private impl items.
711772
hir::ItemKind::Impl(ref impl_) => {
712-
for impl_item_ref in impl_.items {
713-
if impl_.of_trait.is_some()
714-
|| self.tcx.visibility(impl_item_ref.id.def_id) == ty::Visibility::Public
715-
{
716-
self.update(impl_item_ref.id.def_id, item_level);
717-
}
718-
}
719-
720773
if item_level.is_some() {
721774
self.reach(item.def_id, item_level).generics().predicates().ty().trait_ref();
722775

@@ -731,21 +784,15 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
731784
}
732785
}
733786
}
787+
734788
// Visit everything, but enum variants have their own levels.
735789
hir::ItemKind::Enum(ref def, _) => {
736790
if item_level.is_some() {
737791
self.reach(item.def_id, item_level).generics().predicates();
738792
}
739-
740-
let enum_level = self.get(item.def_id);
741793
for variant in def.variants {
742-
let variant_level = self.update_with_hir_id(variant.id, enum_level);
743-
794+
let variant_level = self.get(self.tcx.hir().local_def_id(variant.id));
744795
if variant_level.is_some() {
745-
if let Some(ctor_id) = variant.data.ctor_hir_id() {
746-
self.update_with_hir_id(ctor_id, variant_level);
747-
}
748-
749796
for field in variant.data.fields() {
750797
self.reach(self.tcx.hir().local_def_id(field.hir_id), variant_level)
751798
.ty();
@@ -756,9 +803,6 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
756803
}
757804
}
758805
}
759-
hir::ItemKind::Macro(ref macro_def) => {
760-
self.update_reachability_from_macro(item.def_id, macro_def);
761-
}
762806
// Visit everything, but foreign items have their own levels.
763807
hir::ItemKind::ForeignMod { items, .. } => {
764808
for foreign_item in items {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
mod machine {
2+
pub struct A {
3+
pub b: B,
4+
}
5+
pub struct B {}
6+
impl B {
7+
pub fn f(&self) {}
8+
}
9+
}
10+
11+
pub struct Context {
12+
pub a: machine::A,
13+
}
14+
15+
pub fn ctx() -> Context {
16+
todo!();
17+
}

src/test/ui/privacy/issue-92755.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// aux-build:issue-92755.rs
2+
// build-pass
3+
4+
// Thank you @tmiasko for providing the content of this test!
5+
6+
extern crate issue_92755;
7+
8+
fn main() {
9+
issue_92755::ctx().a.b.f();
10+
}

0 commit comments

Comments
 (0)