Populate effective visibilities in 'rustc_resolve'

This commit is contained in:
Bryanskiy 2022-09-25 14:25:02 +03:00
parent e20fabb0d0
commit 496ccd982c
7 changed files with 240 additions and 163 deletions

View File

@ -1,12 +1,12 @@
//! A pass that checks to make sure private fields and methods aren't used //! A pass that checks to make sure private fields and methods aren't used
//! outside their scopes. This pass will also generate a set of exported items //! outside their scopes. This pass will also generate a set of exported items
//! which are available for use externally when compiled as a library. //! which are available for use externally when compiled as a library.
use crate::ty::Visibility; use crate::ty::{DefIdTree, Visibility};
use rustc_data_structures::fx::FxHashMap; 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::{DefId, LocalDefId};
use std::hash::Hash; use std::hash::Hash;
/// Represents the levels of accessibility an item can have. /// Represents the levels of accessibility an item can have.
@ -27,26 +27,36 @@ pub enum AccessLevel {
Public, Public,
} }
#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable, Default)] impl AccessLevel {
pub fn all_levels() -> [AccessLevel; 4] {
[
AccessLevel::Public,
AccessLevel::Exported,
AccessLevel::Reachable,
AccessLevel::ReachableFromImplTrait,
]
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]
pub struct EffectiveVisibility { pub struct EffectiveVisibility {
public: Option<Visibility>, public: Visibility,
exported: Option<Visibility>, exported: Visibility,
reachable: Option<Visibility>, reachable: Visibility,
reachable_from_impl_trait: Option<Visibility>, reachable_from_impl_trait: Visibility,
} }
impl EffectiveVisibility { impl EffectiveVisibility {
pub fn get(&self, tag: AccessLevel) -> Option<&Visibility> { pub fn get(&self, tag: AccessLevel) -> &Visibility {
match tag { match tag {
AccessLevel::Public => &self.public, AccessLevel::Public => &self.public,
AccessLevel::Exported => &self.exported, AccessLevel::Exported => &self.exported,
AccessLevel::Reachable => &self.reachable, AccessLevel::Reachable => &self.reachable,
AccessLevel::ReachableFromImplTrait => &self.reachable_from_impl_trait, AccessLevel::ReachableFromImplTrait => &self.reachable_from_impl_trait,
} }
.as_ref()
} }
fn get_mut(&mut self, tag: AccessLevel) -> &mut Option<Visibility> { fn get_mut(&mut self, tag: AccessLevel) -> &mut Visibility {
match tag { match tag {
AccessLevel::Public => &mut self.public, AccessLevel::Public => &mut self.public,
AccessLevel::Exported => &mut self.exported, AccessLevel::Exported => &mut self.exported,
@ -56,7 +66,30 @@ impl EffectiveVisibility {
} }
pub fn is_public_at_level(&self, tag: AccessLevel) -> bool { pub fn is_public_at_level(&self, tag: AccessLevel) -> bool {
self.get(tag).map_or(false, |vis| vis.is_public()) self.get(tag).is_public()
}
fn update(&mut self, vis: Visibility, tag: AccessLevel, tree: impl DefIdTree) -> bool {
let mut changed = false;
for level in AccessLevel::all_levels() {
if level <= tag {
let current_effective_vis = self.get_mut(level);
if *current_effective_vis != vis && vis.is_at_least(*current_effective_vis, tree) {
changed = true;
*current_effective_vis = vis;
}
}
}
changed
}
fn from_vis(vis: Visibility) -> EffectiveVisibility {
EffectiveVisibility {
public: vis,
exported: vis,
reachable: vis,
reachable_from_impl_trait: vis,
}
} }
} }
@ -89,12 +122,7 @@ impl<Id: Hash + Eq + Copy> AccessLevels<Id> {
pub fn get_access_level(&self, id: Id) -> Option<AccessLevel> { pub fn get_access_level(&self, id: Id) -> Option<AccessLevel> {
self.get_effective_vis(id).and_then(|effective_vis| { self.get_effective_vis(id).and_then(|effective_vis| {
for level in [ for level in AccessLevel::all_levels() {
AccessLevel::Public,
AccessLevel::Exported,
AccessLevel::Reachable,
AccessLevel::ReachableFromImplTrait,
] {
if effective_vis.is_public_at_level(level) { if effective_vis.is_public_at_level(level) {
return Some(level); return Some(level);
} }
@ -103,21 +131,6 @@ impl<Id: Hash + Eq + Copy> AccessLevels<Id> {
}) })
} }
pub fn set_access_level(&mut self, id: Id, tag: AccessLevel) {
let mut effective_vis = self.get_effective_vis(id).copied().unwrap_or_default();
for level in [
AccessLevel::Public,
AccessLevel::Exported,
AccessLevel::Reachable,
AccessLevel::ReachableFromImplTrait,
] {
if level <= tag {
*effective_vis.get_mut(level) = Some(Visibility::Public);
}
}
self.map.insert(id, effective_vis);
}
pub fn get_effective_vis(&self, id: Id) -> Option<&EffectiveVisibility> { pub fn get_effective_vis(&self, id: Id) -> Option<&EffectiveVisibility> {
self.map.get(&id) self.map.get(&id)
} }
@ -129,6 +142,65 @@ impl<Id: Hash + Eq + Copy> AccessLevels<Id> {
pub fn map_id<OutId: Hash + Eq + Copy>(&self, f: impl Fn(Id) -> OutId) -> AccessLevels<OutId> { pub fn map_id<OutId: Hash + Eq + Copy>(&self, f: impl Fn(Id) -> OutId) -> AccessLevels<OutId> {
AccessLevels { map: self.map.iter().map(|(k, v)| (f(*k), *v)).collect() } AccessLevels { map: self.map.iter().map(|(k, v)| (f(*k), *v)).collect() }
} }
pub fn set_access_level(
&mut self,
id: Id,
default_vis: impl FnOnce() -> Visibility,
tag: AccessLevel,
) {
let mut effective_vis = self
.get_effective_vis(id)
.copied()
.unwrap_or_else(|| EffectiveVisibility::from_vis(default_vis()));
for level in AccessLevel::all_levels() {
if level <= tag {
*effective_vis.get_mut(level) = Visibility::Public;
}
}
self.map.insert(id, effective_vis);
}
}
impl<Id: Hash + Eq + Copy + Into<DefId>> AccessLevels<Id> {
// `parent_id` is not necessarily a parent in source code tree,
// it is the node from which the maximum effective visibility is inherited.
pub fn update(
&mut self,
id: Id,
nominal_vis: Visibility,
default_vis: impl FnOnce() -> Visibility,
parent_id: Id,
tag: AccessLevel,
tree: impl DefIdTree,
) -> Result<bool, ()> {
let mut changed = false;
let mut current_effective_vis = self
.get_effective_vis(id)
.copied()
.unwrap_or_else(|| EffectiveVisibility::from_vis(default_vis()));
if let Some(inherited_effective_vis) = self.get_effective_vis(parent_id) {
for level in AccessLevel::all_levels() {
if tag >= level {
let inherited_effective_vis_at_level = *inherited_effective_vis.get(level);
let calculated_effective_vis =
if nominal_vis.is_at_least(inherited_effective_vis_at_level, tree) {
inherited_effective_vis_at_level
} else {
nominal_vis
};
changed |= current_effective_vis.update(calculated_effective_vis, level, tree);
}
}
} else {
if !id.into().is_crate_root() {
return Err(());
}
changed |= current_effective_vis.update(Visibility::Public, AccessLevel::Public, tree);
}
self.map.insert(id, current_effective_vis);
Ok(changed)
}
} }
impl<Id> Default for AccessLevels<Id> { impl<Id> Default for AccessLevels<Id> {

View File

@ -433,7 +433,11 @@ impl<'tcx> EmbargoVisitor<'tcx> {
let old_level = self.get(def_id); let old_level = self.get(def_id);
// Accessibility levels can only grow. // Accessibility levels can only grow.
if level > old_level { if level > old_level {
self.access_levels.set_access_level(def_id, level.unwrap()); self.access_levels.set_access_level(
def_id,
|| ty::Visibility::Restricted(self.tcx.parent_module_from_def_id(def_id)),
level.unwrap(),
);
self.changed = true; self.changed = true;
level level
} else { } else {
@ -921,31 +925,30 @@ pub struct TestReachabilityVisitor<'tcx, 'a> {
impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> { impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
fn access_level_diagnostic(&mut self, def_id: LocalDefId) { fn access_level_diagnostic(&mut self, def_id: LocalDefId) {
let span = self.tcx.def_span(def_id.to_def_id());
if self.tcx.has_attr(def_id.to_def_id(), sym::rustc_effective_visibility) { if self.tcx.has_attr(def_id.to_def_id(), sym::rustc_effective_visibility) {
let mut error_msg = String::new(); if let Some(effective_vis) = self.access_levels.get_effective_vis(def_id) {
let mut error_msg = String::new();
let effective_vis = let span = self.tcx.def_span(def_id.to_def_id());
self.access_levels.get_effective_vis(def_id).copied().unwrap_or_default(); for level in AccessLevel::all_levels() {
for level in [ let vis_str = match effective_vis.get(level) {
AccessLevel::Public, ty::Visibility::Restricted(restricted_id) => {
AccessLevel::Exported, if restricted_id.is_top_level_module() {
AccessLevel::Reachable, "pub(crate)".to_string()
AccessLevel::ReachableFromImplTrait, } else if *restricted_id == self.tcx.parent_module_from_def_id(def_id) {
] { "pub(self)".to_string()
let vis_str = match effective_vis.get(level) { } else {
Some(ty::Visibility::Restricted(restricted_id)) => { format!("pub({})", self.tcx.item_name(restricted_id.to_def_id()))
format!("pub({})", self.tcx.item_name(restricted_id.to_def_id())) }
}
ty::Visibility::Public => "pub".to_string(),
};
if level != AccessLevel::Public {
error_msg.push_str(", ");
} }
Some(ty::Visibility::Public) => "pub".to_string(), error_msg.push_str(&format!("{:?}: {}", level, vis_str));
None => "pub(self)".to_string(),
};
if level != AccessLevel::Public {
error_msg.push_str(", ");
} }
error_msg.push_str(&format!("{:?}: {}", level, vis_str)); self.tcx.sess.emit_err(ReportEffectiveVisibility { span, descr: error_msg });
} }
self.tcx.sess.emit_err(ReportEffectiveVisibility { span, descr: error_msg });
} }
} }
} }

View File

@ -1,4 +1,3 @@
use crate::NameBinding;
use crate::NameBindingKind; use crate::NameBindingKind;
use crate::Resolver; use crate::Resolver;
use rustc_ast::ast; use rustc_ast::ast;
@ -6,12 +5,10 @@ use rustc_ast::visit;
use rustc_ast::visit::Visitor; use rustc_ast::visit::Visitor;
use rustc_ast::Crate; use rustc_ast::Crate;
use rustc_ast::EnumDef; use rustc_ast::EnumDef;
use rustc_ast::NodeId;
use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LocalDefId;
use rustc_hir::def_id::CRATE_DEF_ID; use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_middle::middle::privacy::AccessLevel; use rustc_middle::middle::privacy::AccessLevel;
use rustc_middle::ty::DefIdTree; use rustc_middle::ty::{DefIdTree, Visibility};
use rustc_span::sym;
pub struct AccessLevelsVisitor<'r, 'a> { pub struct AccessLevelsVisitor<'r, 'a> {
r: &'r mut Resolver<'a>, r: &'r mut Resolver<'a>,
@ -25,7 +22,7 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
pub fn compute_access_levels<'c>(r: &'r mut Resolver<'a>, krate: &'c Crate) { pub fn compute_access_levels<'c>(r: &'r mut Resolver<'a>, krate: &'c Crate) {
let mut visitor = AccessLevelsVisitor { r, changed: false }; let mut visitor = AccessLevelsVisitor { r, changed: false };
visitor.set_access_level_def_id(CRATE_DEF_ID, Some(AccessLevel::Public)); visitor.update(CRATE_DEF_ID, Visibility::Public, CRATE_DEF_ID, AccessLevel::Public);
visitor.set_bindings_access_level(CRATE_DEF_ID); visitor.set_bindings_access_level(CRATE_DEF_ID);
while visitor.changed { while visitor.changed {
@ -45,67 +42,72 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
/// This will also follow `use` chains (see PrivacyVisitor::set_import_binding_access_level). /// This will also follow `use` chains (see PrivacyVisitor::set_import_binding_access_level).
fn set_bindings_access_level(&mut self, module_id: LocalDefId) { fn set_bindings_access_level(&mut self, module_id: LocalDefId) {
assert!(self.r.module_map.contains_key(&&module_id.to_def_id())); assert!(self.r.module_map.contains_key(&&module_id.to_def_id()));
let module_level = self.r.access_levels.get_access_level(module_id);
if !module_level.is_some() {
return;
}
// Set the given binding access level to `AccessLevel::Public` and
// sets the rest of the `use` chain to `AccessLevel::Exported` until
// we hit the actual exported item.
let set_import_binding_access_level =
|this: &mut Self, mut binding: &NameBinding<'a>, mut access_level, ns| {
while let NameBindingKind::Import { binding: nested_binding, import, .. } =
binding.kind
{
this.set_access_level(this.r.import_id_for_ns(import, ns), access_level);
access_level = Some(AccessLevel::Exported);
binding = nested_binding;
}
};
let module = self.r.get_module(module_id.to_def_id()).unwrap(); let module = self.r.get_module(module_id.to_def_id()).unwrap();
let resolutions = self.r.resolutions(module); let resolutions = self.r.resolutions(module);
for (key, name_resolution) in resolutions.borrow().iter() { for (key, name_resolution) in resolutions.borrow().iter() {
if let Some(binding) = name_resolution.borrow().binding() && binding.vis.is_public() && !binding.is_ambiguity() { if let Some(mut binding) = name_resolution.borrow().binding() && !binding.is_ambiguity() {
let access_level = match binding.is_import() { // Set the given binding access level to `AccessLevel::Public` and
true => { // sets the rest of the `use` chain to `AccessLevel::Exported` until
set_import_binding_access_level(self, binding, module_level, key.ns); // we hit the actual exported item.
Some(AccessLevel::Exported)
}, // FIXME: tag and is_public() condition must be deleted,
false => module_level, // but assertion fail occurs in import_id_for_ns
}; let tag = if binding.is_import() { AccessLevel::Exported } else { AccessLevel::Public };
if binding.vis.is_public() {
let mut prev_parent_id = module_id;
let mut level = AccessLevel::Public;
while let NameBindingKind::Import { binding: nested_binding, import, .. } =
binding.kind
{
let id = self.r.local_def_id(self.r.import_id_for_ns(import, key.ns));
self.update(
id,
binding.vis.expect_local(),
prev_parent_id,
level,
);
level = AccessLevel::Exported;
prev_parent_id = id;
binding = nested_binding;
}
}
if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) { if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) {
self.set_access_level_def_id(def_id, access_level); self.update(def_id, binding.vis.expect_local(), module_id, tag);
} }
} }
} }
} }
/// Sets the access level of the `LocalDefId` corresponding to the given `NodeId`. fn update(
/// This function will panic if the `NodeId` does not have a `LocalDefId`
fn set_access_level(
&mut self,
node_id: NodeId,
access_level: Option<AccessLevel>,
) -> Option<AccessLevel> {
self.set_access_level_def_id(self.r.local_def_id(node_id), access_level)
}
fn set_access_level_def_id(
&mut self, &mut self,
def_id: LocalDefId, def_id: LocalDefId,
access_level: Option<AccessLevel>, nominal_vis: Visibility,
) -> Option<AccessLevel> { parent_id: LocalDefId,
let old_level = self.r.access_levels.get_access_level(def_id); tag: AccessLevel,
if old_level < access_level { ) {
self.r.access_levels.set_access_level(def_id, access_level.unwrap()); let mut access_levels = std::mem::take(&mut self.r.access_levels);
self.changed = true; let module_id =
access_level self.r.get_nearest_non_block_module(def_id.to_def_id()).def_id().expect_local();
let res = access_levels.update(
def_id,
nominal_vis,
|| Visibility::Restricted(module_id),
parent_id,
tag,
&*self.r,
);
if let Ok(changed) = res {
self.changed |= changed;
} else { } else {
old_level self.r.session.delay_span_bug(
self.r.opt_span(def_id.to_def_id()).unwrap(),
"Can't update effective visibility",
);
} }
self.r.access_levels = access_levels;
} }
} }
@ -125,16 +127,15 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
// Foreign modules inherit level from parents. // Foreign modules inherit level from parents.
ast::ItemKind::ForeignMod(..) => { ast::ItemKind::ForeignMod(..) => {
let parent_level = let parent_id = self.r.local_parent(def_id);
self.r.access_levels.get_access_level(self.r.local_parent(def_id)); self.update(def_id, Visibility::Public, parent_id, AccessLevel::Public);
self.set_access_level(item.id, parent_level);
} }
// Only exported `macro_rules!` items are public, but they always are // Only exported `macro_rules!` items are public, but they always are
ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => { ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => {
if item.attrs.iter().any(|attr| attr.has_name(sym::macro_export)) { let parent_id = self.r.local_parent(def_id);
self.set_access_level(item.id, Some(AccessLevel::Public)); let vis = self.r.visibilities[&def_id];
} self.update(def_id, vis, parent_id, AccessLevel::Public);
} }
ast::ItemKind::Mod(..) => { ast::ItemKind::Mod(..) => {
@ -146,19 +147,19 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
self.set_bindings_access_level(def_id); self.set_bindings_access_level(def_id);
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);
let variant_level = self.r.access_levels.get_access_level(variant_def_id);
for field in variant.data.fields() { for field in variant.data.fields() {
self.set_access_level(field.id, variant_level); let field_def_id = self.r.local_def_id(field.id);
let vis = self.r.visibilities[&field_def_id];
self.update(field_def_id, vis, variant_def_id, AccessLevel::Public);
} }
} }
} }
ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => { ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => {
let inherited_level = self.r.access_levels.get_access_level(def_id);
for field in def.fields() { for field in def.fields() {
if field.vis.kind.is_pub() { let field_def_id = self.r.local_def_id(field.id);
self.set_access_level(field.id, inherited_level); let vis = self.r.visibilities[&field_def_id];
} self.update(field_def_id, vis, def_id, AccessLevel::Public);
} }
} }

View File

@ -8,7 +8,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::Node; use rustc_hir::Node;
use rustc_hir::CRATE_HIR_ID; use rustc_hir::CRATE_HIR_ID;
use rustc_middle::middle::privacy::AccessLevel; use rustc_middle::middle::privacy::AccessLevel;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::{TyCtxt, Visibility};
use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::Span; use rustc_span::Span;
@ -230,7 +230,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
} else { } else {
// All items need to be handled here in case someone wishes to link // All items need to be handled here in case someone wishes to link
// to them with intra-doc links // to them with intra-doc links
self.cx.cache.access_levels.set_access_level(did, AccessLevel::Public); self.cx.cache.access_levels.set_access_level(
did,
|| Visibility::Restricted(CRATE_DEF_ID),
AccessLevel::Public,
);
} }
} }
} }

View File

@ -1,8 +1,8 @@
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_ID};
use rustc_middle::middle::privacy::{AccessLevel, AccessLevels}; use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::{TyCtxt, Visibility};
// FIXME: this may not be exhaustive, but is sufficient for rustdocs current uses // FIXME: this may not be exhaustive, but is sufficient for rustdocs current uses
@ -41,7 +41,11 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
let old_level = self.access_levels.get_access_level(did); let old_level = self.access_levels.get_access_level(did);
// Accessibility levels can only grow // Accessibility levels can only grow
if level > old_level && !is_hidden { if level > old_level && !is_hidden {
self.access_levels.set_access_level(did, level.unwrap()); self.access_levels.set_access_level(
did,
|| Visibility::Restricted(CRATE_DEF_ID),
level.unwrap(),
);
level level
} else { } else {
old_level old_level

View File

@ -1,44 +1,44 @@
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
#[rustc_effective_visibility] #[rustc_effective_visibility]
mod outer { //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) mod outer { //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
#[rustc_effective_visibility] #[rustc_effective_visibility]
pub mod inner1 { //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub pub mod inner1 { //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility] #[rustc_effective_visibility]
extern "C" {} //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub extern "C" {} //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility] #[rustc_effective_visibility]
pub trait PubTrait { //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub pub trait PubTrait { //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility] #[rustc_effective_visibility]
const A: i32; //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub const A: i32; //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility] #[rustc_effective_visibility]
type B; //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub type B; //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
} }
#[rustc_effective_visibility] #[rustc_effective_visibility]
struct PrivStruct; //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) struct PrivStruct; //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self)
#[rustc_effective_visibility] #[rustc_effective_visibility]
pub union PubUnion { //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub pub union PubUnion { //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility] #[rustc_effective_visibility]
a: u8, //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) a: u8, //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self)
#[rustc_effective_visibility] #[rustc_effective_visibility]
pub b: u8, //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub pub b: u8, //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
} }
#[rustc_effective_visibility] #[rustc_effective_visibility]
pub enum Enum { //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub pub enum Enum { //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility] #[rustc_effective_visibility]
A( //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub A( //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility] #[rustc_effective_visibility]
PubUnion, //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub PubUnion, //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
), ),
} }
} }
#[rustc_effective_visibility] #[rustc_effective_visibility]
macro_rules! none_macro { //~ Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) macro_rules! none_macro { //~ Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
() => {}; () => {};
} }
@ -49,9 +49,9 @@ mod outer { //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(sel
} }
#[rustc_effective_visibility] #[rustc_effective_visibility]
pub struct ReachableStruct { //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub, ReachableFromImplTrait: pub pub struct ReachableStruct { //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility] #[rustc_effective_visibility]
pub a: u8, //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub, ReachableFromImplTrait: pub pub a: u8, //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub, ReachableFromImplTrait: pub
} }
} }
@ -62,14 +62,13 @@ pub fn foo() -> outer::ReachableStruct { outer::ReachableStruct {a: 0} }
mod half_public_import { mod half_public_import {
#[rustc_effective_visibility] #[rustc_effective_visibility]
pub type HalfPublicImport = u8; //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub pub type HalfPublicImport = u8; //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility] #[rustc_effective_visibility]
#[allow(non_upper_case_globals)] #[allow(non_upper_case_globals)]
pub(crate) const HalfPublicImport: u8 = 0; //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) pub(crate) const HalfPublicImport: u8 = 0; //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
} }
#[rustc_effective_visibility] #[rustc_effective_visibility]
pub use half_public_import::HalfPublicImport; //~ ERROR Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub pub use half_public_import::HalfPublicImport; //~ ERROR Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
//~^ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self)
fn main() {} fn main() {}

View File

@ -1,22 +1,22 @@
error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) error: Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
--> $DIR/access_levels.rs:4:1 --> $DIR/access_levels.rs:4:1
| |
LL | mod outer { LL | mod outer {
| ^^^^^^^^^ | ^^^^^^^^^
error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:6:5 --> $DIR/access_levels.rs:6:5
| |
LL | pub mod inner1 { LL | pub mod inner1 {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:9:9 --> $DIR/access_levels.rs:9:9
| |
LL | extern "C" {} LL | extern "C" {}
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:12:9 --> $DIR/access_levels.rs:12:9
| |
LL | pub trait PubTrait { LL | pub trait PubTrait {
@ -28,7 +28,7 @@ error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFr
LL | struct PrivStruct; LL | struct PrivStruct;
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:23:9 --> $DIR/access_levels.rs:23:9
| |
LL | pub union PubUnion { LL | pub union PubUnion {
@ -40,31 +40,31 @@ error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFr
LL | a: u8, LL | a: u8,
| ^^^^^ | ^^^^^
error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:27:13 --> $DIR/access_levels.rs:27:13
| |
LL | pub b: u8, LL | pub b: u8,
| ^^^^^^^^^ | ^^^^^^^^^
error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:31:9 --> $DIR/access_levels.rs:31:9
| |
LL | pub enum Enum { LL | pub enum Enum {
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:33:13 --> $DIR/access_levels.rs:33:13
| |
LL | A( LL | A(
| ^ | ^
error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:35:17 --> $DIR/access_levels.rs:35:17
| |
LL | PubUnion, LL | PubUnion,
| ^^^^^^^^ | ^^^^^^^^
error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) error: Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
--> $DIR/access_levels.rs:41:5 --> $DIR/access_levels.rs:41:5
| |
LL | macro_rules! none_macro { LL | macro_rules! none_macro {
@ -76,13 +76,13 @@ error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
LL | macro_rules! public_macro { LL | macro_rules! public_macro {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: Public: pub(self), Exported: pub(self), Reachable: pub, ReachableFromImplTrait: pub error: Public: pub(crate), Exported: pub(crate), Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:52:5 --> $DIR/access_levels.rs:52:5
| |
LL | pub struct ReachableStruct { LL | pub struct ReachableStruct {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Public: pub(self), Exported: pub(self), Reachable: pub, ReachableFromImplTrait: pub error: Public: pub(crate), Exported: pub(crate), Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:54:9 --> $DIR/access_levels.rs:54:9
| |
LL | pub a: u8, LL | pub a: u8,
@ -94,13 +94,13 @@ error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
LL | pub use outer::inner1; LL | pub use outer::inner1;
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:65:5 --> $DIR/access_levels.rs:65:5
| |
LL | pub type HalfPublicImport = u8; LL | pub type HalfPublicImport = u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) error: Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
--> $DIR/access_levels.rs:68:5 --> $DIR/access_levels.rs:68:5
| |
LL | pub(crate) const HalfPublicImport: u8 = 0; LL | pub(crate) const HalfPublicImport: u8 = 0;
@ -112,23 +112,17 @@ error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
LL | pub use half_public_import::HalfPublicImport; LL | pub use half_public_import::HalfPublicImport;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self) error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:72:9
|
LL | pub use half_public_import::HalfPublicImport;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:14:13 --> $DIR/access_levels.rs:14:13
| |
LL | const A: i32; LL | const A: i32;
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:16:13 --> $DIR/access_levels.rs:16:13
| |
LL | type B; LL | type B;
| ^^^^^^ | ^^^^^^
error: aborting due to 22 previous errors error: aborting due to 21 previous errors