Rollup merge of #109704 - petrochenkov:effvisclean, r=jackh726

resolve: Minor improvements to effective visibilities

See individual commits.
This commit is contained in:
Michael Goulet 2023-03-30 12:42:19 -07:00 committed by GitHub
commit fbe738345c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 71 additions and 65 deletions

View file

@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_macros::HashStable; use rustc_macros::HashStable;
use rustc_query_system::ich::StableHashingContext; use rustc_query_system::ich::StableHashingContext;
use rustc_span::def_id::LocalDefId; use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID};
use std::hash::Hash; use std::hash::Hash;
/// Represents the levels of effective visibility an item can have. /// Represents the levels of effective visibility an item can have.
@ -107,6 +107,10 @@ impl EffectiveVisibilities {
}) })
} }
pub fn update_root(&mut self) {
self.map.insert(CRATE_DEF_ID, EffectiveVisibility::from_vis(Visibility::Public));
}
// FIXME: Share code with `fn update`. // FIXME: Share code with `fn update`.
pub fn update_eff_vis( pub fn update_eff_vis(
&mut self, &mut self,

View file

@ -2149,6 +2149,7 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
let mut check_visitor = let mut check_visitor =
TestReachabilityVisitor { tcx, effective_visibilities: &visitor.effective_visibilities }; TestReachabilityVisitor { tcx, effective_visibilities: &visitor.effective_visibilities };
check_visitor.effective_visibility_diagnostic(CRATE_DEF_ID);
tcx.hir().visit_all_item_likes_in_crate(&mut check_visitor); tcx.hir().visit_all_item_likes_in_crate(&mut check_visitor);
tcx.arena.alloc(visitor.effective_visibilities) tcx.arena.alloc(visitor.effective_visibilities)

View file

@ -61,7 +61,7 @@ impl Resolver<'_, '_> {
// For mod items `nearest_normal_mod` returns its argument, but we actually need its parent. // For mod items `nearest_normal_mod` returns its argument, but we actually need its parent.
let normal_mod_id = self.nearest_normal_mod(def_id); let normal_mod_id = self.nearest_normal_mod(def_id);
if normal_mod_id == def_id { if normal_mod_id == def_id {
self.tcx.opt_local_parent(def_id).map_or(Visibility::Public, Visibility::Restricted) Visibility::Restricted(self.tcx.local_parent(def_id))
} else { } else {
Visibility::Restricted(normal_mod_id) Visibility::Restricted(normal_mod_id)
} }
@ -80,12 +80,11 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
r, r,
def_effective_visibilities: Default::default(), def_effective_visibilities: Default::default(),
import_effective_visibilities: Default::default(), import_effective_visibilities: Default::default(),
current_private_vis: Visibility::Public, current_private_vis: Visibility::Restricted(CRATE_DEF_ID),
changed: false, changed: false,
}; };
visitor.update(CRATE_DEF_ID, CRATE_DEF_ID); visitor.def_effective_visibilities.update_root();
visitor.current_private_vis = Visibility::Restricted(CRATE_DEF_ID);
visitor.set_bindings_effective_visibilities(CRATE_DEF_ID); visitor.set_bindings_effective_visibilities(CRATE_DEF_ID);
while visitor.changed { while visitor.changed {
@ -125,43 +124,32 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
for (_, name_resolution) in resolutions.borrow().iter() { for (_, name_resolution) in resolutions.borrow().iter() {
if let Some(mut binding) = name_resolution.borrow().binding() { if let Some(mut binding) = name_resolution.borrow().binding() {
if !binding.is_ambiguity() { // Set the given effective visibility level to `Level::Direct` and
// Set the given effective visibility level to `Level::Direct` and // sets the rest of the `use` chain to `Level::Reexported` until
// sets the rest of the `use` chain to `Level::Reexported` until // we hit the actual exported item.
// we hit the actual exported item. //
let mut parent_id = ParentId::Def(module_id); // If the binding is ambiguous, put the root ambiguity binding and all reexports
while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind // leading to it into the table. They are used by the `ambiguous_glob_reexports`
{ // lint. For all bindings added to the table this way `is_ambiguity` returns true.
let binding_id = ImportId::new_unchecked(binding); let mut parent_id = ParentId::Def(module_id);
self.update_import(binding_id, parent_id); while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind {
let binding_id = ImportId::new_unchecked(binding);
self.update_import(binding_id, parent_id);
parent_id = ParentId::Import(binding_id); if binding.ambiguity.is_some() {
binding = nested_binding; // Stop at the root ambiguity, further bindings in the chain should not
// be reexported because the root ambiguity blocks any access to them.
// (Those further bindings are most likely not ambiguities themselves.)
break;
} }
if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) { parent_id = ParentId::Import(binding_id);
self.update_def(def_id, binding.vis.expect_local(), parent_id); binding = nested_binding;
} }
} else {
// Put the root ambiguity binding and all reexports leading to it into the
// table. They are used by the `ambiguous_glob_reexports` lint. For all
// bindings added to the table here `is_ambiguity` returns true.
let mut parent_id = ParentId::Def(module_id);
while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind
{
let binding_id = ImportId::new_unchecked(binding);
self.update_import(binding_id, parent_id);
if binding.ambiguity.is_some() { if binding.ambiguity.is_none()
// Stop at the root ambiguity, further bindings in the chain should not && let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) {
// be reexported because the root ambiguity blocks any access to them. self.update_def(def_id, binding.vis.expect_local(), parent_id);
// (Those further bindings are most likely not ambiguities themselves.)
break;
}
parent_id = ParentId::Import(binding_id);
binding = nested_binding;
}
} }
} }
} }
@ -213,7 +201,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
); );
} }
fn update(&mut self, def_id: LocalDefId, parent_id: LocalDefId) { fn update_field(&mut self, def_id: LocalDefId, parent_id: LocalDefId) {
self.update_def(def_id, self.r.visibilities[&def_id], ParentId::Def(parent_id)); self.update_def(def_id, self.r.visibilities[&def_id], ParentId::Def(parent_id));
} }
} }
@ -245,14 +233,14 @@ impl<'r, 'ast, 'tcx> Visitor<'ast> for EffectiveVisibilitiesVisitor<'ast, 'r, 't
for variant in variants { for variant in variants {
let variant_def_id = self.r.local_def_id(variant.id); let variant_def_id = self.r.local_def_id(variant.id);
for field in variant.data.fields() { for field in variant.data.fields() {
self.update(self.r.local_def_id(field.id), variant_def_id); self.update_field(self.r.local_def_id(field.id), variant_def_id);
} }
} }
} }
ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => { ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => {
for field in def.fields() { for field in def.fields() {
self.update(self.r.local_def_id(field.id), def_id); self.update_field(self.r.local_def_id(field.id), def_id);
} }
} }

View file

@ -1,3 +1,4 @@
#![rustc_effective_visibility] //~ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
#[rustc_effective_visibility] #[rustc_effective_visibility]

View file

@ -1,140 +1,152 @@
error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:1:1
|
LL | / #![rustc_effective_visibility]
LL | | #![feature(rustc_attrs)]
LL | |
LL | | #[rustc_effective_visibility]
... |
LL | |
LL | | fn main() {}
| |____________^
error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate) error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
--> $DIR/effective_visibilities.rs:4:1 --> $DIR/effective_visibilities.rs:5:1
| |
LL | mod outer { LL | mod outer {
| ^^^^^^^^^ | ^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:6:5 --> $DIR/effective_visibilities.rs:7:5
| |
LL | pub mod inner1 { LL | pub mod inner1 {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error: not in the table error: not in the table
--> $DIR/effective_visibilities.rs:9:9 --> $DIR/effective_visibilities.rs:10:9
| |
LL | extern "C" {} LL | extern "C" {}
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:12:9 --> $DIR/effective_visibilities.rs:13:9
| |
LL | pub trait PubTrait { LL | pub trait PubTrait {
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self) error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
--> $DIR/effective_visibilities.rs:20:9 --> $DIR/effective_visibilities.rs:21:9
| |
LL | struct PrivStruct; LL | struct PrivStruct;
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self) error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
--> $DIR/effective_visibilities.rs:20:9 --> $DIR/effective_visibilities.rs:21:9
| |
LL | struct PrivStruct; LL | struct PrivStruct;
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:24:9 --> $DIR/effective_visibilities.rs:25:9
| |
LL | pub union PubUnion { LL | pub union PubUnion {
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self) error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
--> $DIR/effective_visibilities.rs:26:13 --> $DIR/effective_visibilities.rs:27:13
| |
LL | a: u8, LL | a: u8,
| ^^^^^ | ^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:28:13 --> $DIR/effective_visibilities.rs:29:13
| |
LL | pub b: u8, LL | pub b: u8,
| ^^^^^^^^^ | ^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:32:9 --> $DIR/effective_visibilities.rs:33:9
| |
LL | pub enum Enum { LL | pub enum Enum {
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:34:13 --> $DIR/effective_visibilities.rs:35:13
| |
LL | A( LL | A(
| ^ | ^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:34:13 --> $DIR/effective_visibilities.rs:35:13
| |
LL | A( LL | A(
| ^ | ^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:37:17 --> $DIR/effective_visibilities.rs:38:17
| |
LL | PubUnion, LL | PubUnion,
| ^^^^^^^^ | ^^^^^^^^
error: not in the table error: not in the table
--> $DIR/effective_visibilities.rs:43:5 --> $DIR/effective_visibilities.rs:44:5
| |
LL | macro_rules! none_macro { LL | macro_rules! none_macro {
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub(self), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub(self), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:49:5 --> $DIR/effective_visibilities.rs:50:5
| |
LL | macro_rules! public_macro { LL | macro_rules! public_macro {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:54:5 --> $DIR/effective_visibilities.rs:55:5
| |
LL | pub struct ReachableStruct { LL | pub struct ReachableStruct {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:56:9 --> $DIR/effective_visibilities.rs:57:9
| |
LL | pub a: u8, LL | pub a: u8,
| ^^^^^^^^^ | ^^^^^^^^^
error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:61:9 --> $DIR/effective_visibilities.rs:62:9
| |
LL | pub use outer::inner1; LL | pub use outer::inner1;
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:67:5 --> $DIR/effective_visibilities.rs:68:5
| |
LL | pub type HalfPublicImport = u8; LL | pub type HalfPublicImport = u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate) error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
--> $DIR/effective_visibilities.rs:70:5 --> $DIR/effective_visibilities.rs:71:5
| |
LL | pub(crate) const HalfPublicImport: u8 = 0; LL | pub(crate) const HalfPublicImport: u8 = 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:74:9 --> $DIR/effective_visibilities.rs:75:9
| |
LL | pub use half_public_import::HalfPublicImport; LL | pub use half_public_import::HalfPublicImport;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:14:13 --> $DIR/effective_visibilities.rs:15:13
| |
LL | const A: i32; LL | const A: i32;
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:16:13 --> $DIR/effective_visibilities.rs:17:13
| |
LL | type B; LL | type B;
| ^^^^^^ | ^^^^^^
error: aborting due to 23 previous errors error: aborting due to 24 previous errors