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:
commit
ac4ffdce9a
3 changed files with 92 additions and 124 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue