Rollup merge of #144276 - cjgillot:no-hir-privacy, r=petrochenkov

Use less HIR in check_private_in_public.

r? ````````@petrochenkov````````
This commit is contained in:
León Orell Valerian Liehr 2025-07-24 15:08:25 +02:00 committed by GitHub
commit ac4ffdce9a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 92 additions and 124 deletions

View file

@ -26,7 +26,7 @@ use rustc_errors::{MultiSpan, listify};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId, LocalModDefId};
use rustc_hir::intravisit::{self, InferKind, Visitor};
use rustc_hir::{AmbigArg, ForeignItemKind, ItemId, ItemKind, PatKind};
use rustc_hir::{AmbigArg, ForeignItemId, ItemId, PatKind};
use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
use rustc_middle::query::Providers;
use rustc_middle::ty::print::PrintTraitRefExt as _;
@ -599,18 +599,13 @@ impl<'tcx> EmbargoVisitor<'tcx> {
DefKind::Struct | DefKind::Union => {
// While structs and unions have type privacy, their fields do not.
let item = self.tcx.hir_expect_item(def_id);
if let hir::ItemKind::Struct(_, _, ref struct_def)
| hir::ItemKind::Union(_, _, ref struct_def) = item.kind
{
for field in struct_def.fields() {
let field_vis = self.tcx.local_visibility(field.def_id);
if field_vis.is_accessible_from(module, self.tcx) {
self.reach(field.def_id, macro_ev).ty();
}
let struct_def = self.tcx.adt_def(def_id);
for field in struct_def.non_enum_variant().fields.iter() {
let def_id = field.did.expect_local();
let field_vis = self.tcx.local_visibility(def_id);
if field_vis.is_accessible_from(module, self.tcx) {
self.reach(def_id, macro_ev).ty();
}
} else {
bug!("item {:?} with DefKind {:?}", item, def_kind);
}
}
@ -1644,66 +1639,29 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
self.check(def_id, item_visibility, effective_vis).generics().predicates();
}
DefKind::Enum => {
let item = tcx.hir_item(id);
if let hir::ItemKind::Enum(_, _, ref def) = item.kind {
self.check_unnameable(item.owner_id.def_id, effective_vis);
self.check_unnameable(def_id, effective_vis);
self.check(def_id, item_visibility, effective_vis).generics().predicates();
self.check(item.owner_id.def_id, item_visibility, effective_vis)
.generics()
.predicates();
for variant in def.variants {
for field in variant.data.fields() {
self.check(field.def_id, item_visibility, effective_vis).ty();
}
}
}
}
// Subitems of foreign modules have their own publicity.
DefKind::ForeignMod => {
let item = tcx.hir_item(id);
if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
for &foreign_item in items {
let foreign_item = tcx.hir_foreign_item(foreign_item);
let ev = self.get(foreign_item.owner_id.def_id);
let vis = tcx.local_visibility(foreign_item.owner_id.def_id);
if let ForeignItemKind::Type = foreign_item.kind {
self.check_unnameable(foreign_item.owner_id.def_id, ev);
}
self.check(foreign_item.owner_id.def_id, vis, ev)
.generics()
.predicates()
.ty();
}
let adt = tcx.adt_def(id.owner_id);
for field in adt.all_fields() {
self.check(field.did.expect_local(), item_visibility, effective_vis).ty();
}
}
// Subitems of structs and unions have their own publicity.
DefKind::Struct | DefKind::Union => {
let item = tcx.hir_item(id);
if let hir::ItemKind::Struct(_, _, ref struct_def)
| hir::ItemKind::Union(_, _, ref struct_def) = item.kind
{
self.check_unnameable(item.owner_id.def_id, effective_vis);
self.check(item.owner_id.def_id, item_visibility, effective_vis)
.generics()
.predicates();
self.check_unnameable(def_id, effective_vis);
self.check(def_id, item_visibility, effective_vis).generics().predicates();
for field in struct_def.fields() {
let field_visibility = tcx.local_visibility(field.def_id);
let field_ev = self.get(field.def_id);
let adt = tcx.adt_def(id.owner_id);
for field in adt.all_fields() {
let visibility = min(item_visibility, field.vis.expect_local(), tcx);
let field_ev = self.get(field.did.expect_local());
self.check(
field.def_id,
min(item_visibility, field_visibility, tcx),
field_ev,
)
.ty();
}
self.check(field.did.expect_local(), visibility, field_ev).ty();
}
}
// Subitems of foreign modules have their own publicity.
DefKind::ForeignMod => {}
// An inherent impl is public when its type is public
// Subitems of inherent impls have their own publicity.
// A trait impl is public when both its type and its trait are public
@ -1763,6 +1721,19 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
_ => {}
}
}
fn check_foreign_item(&mut self, id: ForeignItemId) {
let tcx = self.tcx;
let def_id = id.owner_id.def_id;
let item_visibility = tcx.local_visibility(def_id);
let effective_vis = self.get(def_id);
if let DefKind::ForeignTy = self.tcx.def_kind(def_id) {
self.check_unnameable(def_id, effective_vis);
}
self.check(def_id, item_visibility, effective_vis).generics().predicates().ty();
}
}
pub fn provide(providers: &mut Providers) {
@ -1791,20 +1762,13 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
if let Some(body_id) = tcx.hir_maybe_body_owned_by(def_id) {
visitor.visit_nested_body(body_id.id());
}
}
for id in module.free_items() {
if let ItemKind::Impl(i) = tcx.hir_item(id).kind {
if let Some(item) = i.of_trait {
let trait_ref = tcx.impl_trait_ref(id.owner_id.def_id).unwrap();
let trait_ref = trait_ref.instantiate_identity();
visitor.span = item.path.span;
let _ = visitor.visit_def_id(
trait_ref.def_id,
"trait",
&trait_ref.print_only_trait_path(),
);
}
if let DefKind::Impl { of_trait: true } = tcx.def_kind(def_id) {
let trait_ref = tcx.impl_trait_ref(def_id).unwrap();
let trait_ref = trait_ref.instantiate_identity();
visitor.span = tcx.hir_expect_item(def_id).expect_impl().of_trait.unwrap().path.span;
let _ =
visitor.visit_def_id(trait_ref.def_id, "trait", &trait_ref.print_only_trait_path());
}
}
}
@ -1895,7 +1859,11 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
// Check for private types in public interfaces.
let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities };
for id in tcx.hir_free_items() {
let crate_items = tcx.hir_crate_items(());
for id in crate_items.free_items() {
checker.check_item(id);
}
for id in crate_items.foreign_items() {
checker.check_foreign_item(id);
}
}

View file

@ -75,6 +75,17 @@ LL | priv_trait::mac!();
|
= note: this error originates in the macro `priv_trait::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
error: trait `PrivTr` is private
--> $DIR/associated-item-privacy-trait.rs:29:14
|
LL | impl PrivTr for u8 {}
| ^^^^^^ private trait
...
LL | priv_trait::mac!();
| ------------------ in this macro invocation
|
= note: this error originates in the macro `priv_trait::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
error: type `priv_signature::Priv` is private
--> $DIR/associated-item-privacy-trait.rs:46:21
|
@ -317,16 +328,5 @@ LL | priv_parent_substs::mac!();
|
= note: this error originates in the macro `priv_parent_substs::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
error: trait `PrivTr` is private
--> $DIR/associated-item-privacy-trait.rs:29:14
|
LL | impl PrivTr for u8 {}
| ^^^^^^ private trait
...
LL | priv_trait::mac!();
| ------------------ in this macro invocation
|
= note: this error originates in the macro `priv_trait::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 30 previous errors

View file

@ -84,42 +84,6 @@ note: but type `types::Priv` is only usable at visibility `pub(self)`
LL | struct Priv;
| ^^^^^^^^^^^
error: type `types::Priv` is more private than the item `types::ES`
--> $DIR/private-in-public-warn.rs:27:9
|
LL | pub static ES: Priv;
| ^^^^^^^^^^^^^^^^^^^ static `types::ES` is reachable at visibility `pub(crate)`
|
note: but type `types::Priv` is only usable at visibility `pub(self)`
--> $DIR/private-in-public-warn.rs:9:5
|
LL | struct Priv;
| ^^^^^^^^^^^
error: type `types::Priv` is more private than the item `types::ef1`
--> $DIR/private-in-public-warn.rs:28:9
|
LL | pub fn ef1(arg: Priv);
| ^^^^^^^^^^^^^^^^^^^^^^ function `types::ef1` is reachable at visibility `pub(crate)`
|
note: but type `types::Priv` is only usable at visibility `pub(self)`
--> $DIR/private-in-public-warn.rs:9:5
|
LL | struct Priv;
| ^^^^^^^^^^^
error: type `types::Priv` is more private than the item `types::ef2`
--> $DIR/private-in-public-warn.rs:29:9
|
LL | pub fn ef2() -> Priv;
| ^^^^^^^^^^^^^^^^^^^^^ function `types::ef2` is reachable at visibility `pub(crate)`
|
note: but type `types::Priv` is only usable at visibility `pub(self)`
--> $DIR/private-in-public-warn.rs:9:5
|
LL | struct Priv;
| ^^^^^^^^^^^
error[E0446]: private type `types::Priv` in public interface
--> $DIR/private-in-public-warn.rs:32:9
|
@ -395,6 +359,42 @@ note: but type `Priv2` is only usable at visibility `pub(self)`
LL | struct Priv2;
| ^^^^^^^^^^^^
error: type `types::Priv` is more private than the item `types::ES`
--> $DIR/private-in-public-warn.rs:27:9
|
LL | pub static ES: Priv;
| ^^^^^^^^^^^^^^^^^^^ static `types::ES` is reachable at visibility `pub(crate)`
|
note: but type `types::Priv` is only usable at visibility `pub(self)`
--> $DIR/private-in-public-warn.rs:9:5
|
LL | struct Priv;
| ^^^^^^^^^^^
error: type `types::Priv` is more private than the item `types::ef1`
--> $DIR/private-in-public-warn.rs:28:9
|
LL | pub fn ef1(arg: Priv);
| ^^^^^^^^^^^^^^^^^^^^^^ function `types::ef1` is reachable at visibility `pub(crate)`
|
note: but type `types::Priv` is only usable at visibility `pub(self)`
--> $DIR/private-in-public-warn.rs:9:5
|
LL | struct Priv;
| ^^^^^^^^^^^
error: type `types::Priv` is more private than the item `types::ef2`
--> $DIR/private-in-public-warn.rs:29:9
|
LL | pub fn ef2() -> Priv;
| ^^^^^^^^^^^^^^^^^^^^^ function `types::ef2` is reachable at visibility `pub(crate)`
|
note: but type `types::Priv` is only usable at visibility `pub(self)`
--> $DIR/private-in-public-warn.rs:9:5
|
LL | struct Priv;
| ^^^^^^^^^^^
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/private-in-public-warn.rs:42:23
|