1
Fork 0

remove Visitor impl for PrivateItemsInPublicInterfacesChecker

Signed-off-by: Miguel Guarniz <mi9uel9@gmail.com>
This commit is contained in:
Miguel Guarniz 2022-05-05 13:34:27 -04:00
parent e8ef5bf464
commit e166409f0d

View file

@ -14,8 +14,8 @@ use rustc_errors::struct_span_err;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID};
use rustc_hir::intravisit::{self, DeepVisitor, Visitor}; use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{AssocItemKind, HirIdSet, Node, PatKind}; use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind};
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::middle::privacy::{AccessLevel, AccessLevels}; use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
@ -1802,12 +1802,12 @@ impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
} }
} }
struct PrivateItemsInPublicInterfacesVisitor<'tcx> { struct PrivateItemsInPublicInterfacesChecker<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
old_error_set_ancestry: LocalDefIdSet, old_error_set_ancestry: LocalDefIdSet,
} }
impl<'tcx> PrivateItemsInPublicInterfacesVisitor<'tcx> { impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
fn check( fn check(
&self, &self,
def_id: LocalDefId, def_id: LocalDefId,
@ -1841,110 +1841,121 @@ impl<'tcx> PrivateItemsInPublicInterfacesVisitor<'tcx> {
check.ty(); check.ty();
} }
} }
}
impl<'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'tcx> { pub fn check_item(&mut self, id: ItemId) {
type NestedFilter = nested_filter::OnlyBodies;
fn nested_visit_map(&mut self) -> Self::Map {
self.tcx.hir()
}
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
let tcx = self.tcx; let tcx = self.tcx;
let item_visibility = tcx.visibility(item.def_id); let item_visibility = tcx.visibility(id.def_id);
let def_kind = tcx.def_kind(id.def_id);
match item.kind { if matches!(
// Crates are always public. def_kind,
hir::ItemKind::ExternCrate(..) => {} DefKind::ExternCrate
// All nested items are checked by `visit_item`. | DefKind::Mod
hir::ItemKind::Mod(..) => {} | DefKind::Use
// Checked in resolve. | DefKind::Macro(_)
hir::ItemKind::Use(..) => {} | DefKind::GlobalAsm
// No subitems. ) {
hir::ItemKind::Macro(..) | hir::ItemKind::GlobalAsm(..) => {} return;
// Subitems of these items have inherited publicity. }
hir::ItemKind::Const(..)
| hir::ItemKind::Static(..) match def_kind {
| hir::ItemKind::Fn(..) DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias => {
| hir::ItemKind::TyAlias(..) => { self.check(id.def_id, item_visibility).generics().predicates().ty();
self.check(item.def_id, item_visibility).generics().predicates().ty();
} }
hir::ItemKind::OpaqueTy(..) => { DefKind::OpaqueTy => {
// `ty()` for opaque types is the underlying type, // `ty()` for opaque types is the underlying type,
// it's not a part of interface, so we skip it. // it's not a part of interface, so we skip it.
self.check(item.def_id, item_visibility).generics().bounds(); self.check(id.def_id, item_visibility).generics().bounds();
} }
hir::ItemKind::Trait(.., trait_item_refs) => { DefKind::Trait => {
self.check(item.def_id, item_visibility).generics().predicates(); let item = tcx.hir().item(id);
if let hir::ItemKind::Trait(.., trait_item_refs) = item.kind {
self.check(item.def_id, item_visibility).generics().predicates();
for trait_item_ref in trait_item_refs { for trait_item_ref in trait_item_refs {
self.check_assoc_item( self.check_assoc_item(
trait_item_ref.id.def_id, trait_item_ref.id.def_id,
trait_item_ref.kind, trait_item_ref.kind,
trait_item_ref.defaultness, trait_item_ref.defaultness,
item_visibility, item_visibility,
); );
if let AssocItemKind::Type = trait_item_ref.kind { if let AssocItemKind::Type = trait_item_ref.kind {
self.check(trait_item_ref.id.def_id, item_visibility).bounds(); self.check(trait_item_ref.id.def_id, item_visibility).bounds();
}
} }
} }
} }
hir::ItemKind::TraitAlias(..) => { DefKind::TraitAlias => {
self.check(item.def_id, item_visibility).generics().predicates(); self.check(id.def_id, item_visibility).generics().predicates();
} }
hir::ItemKind::Enum(ref def, _) => { DefKind::Enum => {
self.check(item.def_id, item_visibility).generics().predicates(); let item = tcx.hir().item(id);
if let hir::ItemKind::Enum(ref def, _) = item.kind {
self.check(item.def_id, item_visibility).generics().predicates();
for variant in def.variants { for variant in def.variants {
for field in variant.data.fields() { for field in variant.data.fields() {
self.check(self.tcx.hir().local_def_id(field.hir_id), item_visibility).ty(); self.check(self.tcx.hir().local_def_id(field.hir_id), item_visibility)
.ty();
}
} }
} }
} }
// Subitems of foreign modules have their own publicity. // Subitems of foreign modules have their own publicity.
hir::ItemKind::ForeignMod { items, .. } => { DefKind::ForeignMod => {
for foreign_item in items { let item = tcx.hir().item(id);
let vis = tcx.visibility(foreign_item.id.def_id); if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
self.check(foreign_item.id.def_id, vis).generics().predicates().ty(); for foreign_item in items {
let vis = tcx.visibility(foreign_item.id.def_id);
self.check(foreign_item.id.def_id, vis).generics().predicates().ty();
}
} }
} }
// Subitems of structs and unions have their own publicity. // Subitems of structs and unions have their own publicity.
hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Union(ref struct_def, _) => { DefKind::Struct | DefKind::Union => {
self.check(item.def_id, item_visibility).generics().predicates(); let item = tcx.hir().item(id);
if let hir::ItemKind::Struct(ref struct_def, _)
| hir::ItemKind::Union(ref struct_def, _) = item.kind
{
self.check(item.def_id, item_visibility).generics().predicates();
for field in struct_def.fields() { for field in struct_def.fields() {
let def_id = tcx.hir().local_def_id(field.hir_id); let def_id = tcx.hir().local_def_id(field.hir_id);
let field_visibility = tcx.visibility(def_id); let field_visibility = tcx.visibility(def_id);
self.check(def_id, min(item_visibility, field_visibility, tcx)).ty(); self.check(def_id, min(item_visibility, field_visibility, tcx)).ty();
}
} }
} }
// An inherent impl is public when its type is public // An inherent impl is public when its type is public
// Subitems of inherent impls have their own publicity. // Subitems of inherent impls have their own publicity.
// A trait impl is public when both its type and its trait are public // A trait impl is public when both its type and its trait are public
// Subitems of trait impls have inherited publicity. // Subitems of trait impls have inherited publicity.
hir::ItemKind::Impl(ref impl_) => { DefKind::Impl => {
let impl_vis = ty::Visibility::of_impl(item.def_id, tcx, &Default::default()); let item = tcx.hir().item(id);
// check that private components do not appear in the generics or predicates of inherent impls if let hir::ItemKind::Impl(ref impl_) = item.kind {
// this check is intentionally NOT performed for impls of traits, per #90586 let impl_vis = ty::Visibility::of_impl(item.def_id, tcx, &Default::default());
if impl_.of_trait.is_none() { // check that private components do not appear in the generics or predicates of inherent impls
self.check(item.def_id, impl_vis).generics().predicates(); // this check is intentionally NOT performed for impls of traits, per #90586
} if impl_.of_trait.is_none() {
for impl_item_ref in impl_.items { self.check(item.def_id, impl_vis).generics().predicates();
let impl_item_vis = if impl_.of_trait.is_none() { }
min(tcx.visibility(impl_item_ref.id.def_id), impl_vis, tcx) for impl_item_ref in impl_.items {
} else { let impl_item_vis = if impl_.of_trait.is_none() {
impl_vis min(tcx.visibility(impl_item_ref.id.def_id), impl_vis, tcx)
}; } else {
self.check_assoc_item( impl_vis
impl_item_ref.id.def_id, };
impl_item_ref.kind, self.check_assoc_item(
impl_item_ref.defaultness, impl_item_ref.id.def_id,
impl_item_vis, impl_item_ref.kind,
); impl_item_ref.defaultness,
impl_item_vis,
);
}
} }
} }
_ => {}
} }
} }
} }
@ -2069,7 +2080,7 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
} }
// Check for private types and traits in public interfaces. // Check for private types and traits in public interfaces.
let mut visitor = PrivateItemsInPublicInterfacesVisitor { let mut checker = PrivateItemsInPublicInterfacesChecker {
tcx, tcx,
// Only definition IDs are ever searched in `old_error_set_ancestry`, // Only definition IDs are ever searched in `old_error_set_ancestry`,
// so we can filter away all non-definition IDs at this point. // so we can filter away all non-definition IDs at this point.
@ -2078,5 +2089,8 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
.filter_map(|hir_id| tcx.hir().opt_local_def_id(hir_id)) .filter_map(|hir_id| tcx.hir().opt_local_def_id(hir_id))
.collect(), .collect(),
}; };
tcx.hir().visit_all_item_likes(&mut DeepVisitor::new(&mut visitor));
for id in tcx.hir().items() {
checker.check_item(id);
}
} }