Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Populate effective visibilities in 'rustc_resolve' #102026

Merged
merged 1 commit into from
Oct 16, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 104 additions & 32 deletions compiler/rustc_middle/src/middle/privacy.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//! 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
//! 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::stable_hasher::{HashStable, StableHasher};
use rustc_macros::HashStable;
use rustc_query_system::ich::StableHashingContext;
use rustc_span::def_id::LocalDefId;
use rustc_span::def_id::{DefId, LocalDefId};
use std::hash::Hash;

/// Represents the levels of accessibility an item can have.
@@ -27,26 +27,36 @@ pub enum AccessLevel {
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 {
public: Option<Visibility>,
exported: Option<Visibility>,
reachable: Option<Visibility>,
reachable_from_impl_trait: Option<Visibility>,
public: Visibility,
exported: Visibility,
reachable: Visibility,
reachable_from_impl_trait: Visibility,
}

impl EffectiveVisibility {
pub fn get(&self, tag: AccessLevel) -> Option<&Visibility> {
pub fn get(&self, tag: AccessLevel) -> &Visibility {
match tag {
AccessLevel::Public => &self.public,
AccessLevel::Exported => &self.exported,
AccessLevel::Reachable => &self.reachable,
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 {
AccessLevel::Public => &mut self.public,
AccessLevel::Exported => &mut self.exported,
@@ -56,7 +66,30 @@ impl EffectiveVisibility {
}

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> {
self.get_effective_vis(id).and_then(|effective_vis| {
for level in [
AccessLevel::Public,
AccessLevel::Exported,
AccessLevel::Reachable,
AccessLevel::ReachableFromImplTrait,
] {
for level in AccessLevel::all_levels() {
if effective_vis.is_public_at_level(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> {
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> {
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> {
47 changes: 25 additions & 22 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
@@ -433,7 +433,11 @@ impl<'tcx> EmbargoVisitor<'tcx> {
let old_level = self.get(def_id);
// Accessibility levels can only grow.
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;
level
} else {
@@ -921,31 +925,30 @@ pub struct TestReachabilityVisitor<'tcx, 'a> {

impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
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) {
let mut error_msg = String::new();

let effective_vis =
self.access_levels.get_effective_vis(def_id).copied().unwrap_or_default();
for level in [
AccessLevel::Public,
AccessLevel::Exported,
AccessLevel::Reachable,
AccessLevel::ReachableFromImplTrait,
] {
let vis_str = match effective_vis.get(level) {
Some(ty::Visibility::Restricted(restricted_id)) => {
format!("pub({})", self.tcx.item_name(restricted_id.to_def_id()))
if let Some(effective_vis) = self.access_levels.get_effective_vis(def_id) {
let mut error_msg = String::new();
let span = self.tcx.def_span(def_id.to_def_id());
for level in AccessLevel::all_levels() {
let vis_str = match effective_vis.get(level) {
ty::Visibility::Restricted(restricted_id) => {
if restricted_id.is_top_level_module() {
"pub(crate)".to_string()
} else if *restricted_id == self.tcx.parent_module_from_def_id(def_id) {
"pub(self)".to_string()
} else {
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(),
None => "pub(self)".to_string(),
};
if level != AccessLevel::Public {
error_msg.push_str(", ");
error_msg.push_str(&format!("{:?}: {}", level, vis_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 });
}
}
}
129 changes: 65 additions & 64 deletions compiler/rustc_resolve/src/access_levels.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
use crate::NameBinding;
use crate::NameBindingKind;
use crate::Resolver;
use rustc_ast::ast;
use rustc_ast::visit;
use rustc_ast::visit::Visitor;
use rustc_ast::Crate;
use rustc_ast::EnumDef;
use rustc_ast::NodeId;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_middle::middle::privacy::AccessLevel;
use rustc_middle::ty::DefIdTree;
use rustc_span::sym;
use rustc_middle::ty::{DefIdTree, Visibility};

pub struct AccessLevelsVisitor<'r, '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) {
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);

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).
fn set_bindings_access_level(&mut self, module_id: LocalDefId) {
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 resolutions = self.r.resolutions(module);

for (key, name_resolution) in resolutions.borrow().iter() {
if let Some(binding) = name_resolution.borrow().binding() && binding.vis.is_public() && !binding.is_ambiguity() {
let access_level = match binding.is_import() {
true => {
set_import_binding_access_level(self, binding, module_level, key.ns);
Some(AccessLevel::Exported)
},
false => module_level,
};
if let Some(mut binding) = name_resolution.borrow().binding() && !binding.is_ambiguity() {
// 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.

// FIXME: tag and is_public() condition must be deleted,
// 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()) {
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`.
/// 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(
fn update(
&mut self,
def_id: LocalDefId,
access_level: Option<AccessLevel>,
) -> Option<AccessLevel> {
let old_level = self.r.access_levels.get_access_level(def_id);
if old_level < access_level {
self.r.access_levels.set_access_level(def_id, access_level.unwrap());
self.changed = true;
access_level
nominal_vis: Visibility,
parent_id: LocalDefId,
tag: AccessLevel,
) {
let mut access_levels = std::mem::take(&mut self.r.access_levels);
let module_id =
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 {
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.
ast::ItemKind::ForeignMod(..) => {
let parent_level =
self.r.access_levels.get_access_level(self.r.local_parent(def_id));
self.set_access_level(item.id, parent_level);
let parent_id = self.r.local_parent(def_id);
self.update(def_id, Visibility::Public, parent_id, AccessLevel::Public);
}

// Only exported `macro_rules!` items are public, but they always are
ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => {
if item.attrs.iter().any(|attr| attr.has_name(sym::macro_export)) {
self.set_access_level(item.id, Some(AccessLevel::Public));
}
let parent_id = self.r.local_parent(def_id);
let vis = self.r.visibilities[&def_id];
self.update(def_id, vis, parent_id, AccessLevel::Public);
}

ast::ItemKind::Mod(..) => {
@@ -146,19 +147,19 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
self.set_bindings_access_level(def_id);
for variant in variants {
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() {
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, _) => {
let inherited_level = self.r.access_levels.get_access_level(def_id);
for field in def.fields() {
if field.vis.kind.is_pub() {
self.set_access_level(field.id, inherited_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, def_id, AccessLevel::Public);
}
}

8 changes: 6 additions & 2 deletions src/librustdoc/visit_ast.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::Node;
use rustc_hir::CRATE_HIR_ID;
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::symbol::{kw, sym, Symbol};
use rustc_span::Span;
@@ -230,7 +230,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
} else {
// All items need to be handled here in case someone wishes to link
// 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,
);
}
}
}
10 changes: 7 additions & 3 deletions src/librustdoc/visit_lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use rustc_data_structures::fx::FxHashSet;
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::ty::TyCtxt;
use rustc_middle::ty::{TyCtxt, Visibility};

// 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);
// Accessibility levels can only grow
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
} else {
old_level
33 changes: 16 additions & 17 deletions src/test/ui/privacy/access_levels.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
#![feature(rustc_attrs)]

#[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]
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]
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]
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]
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]
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]
struct PrivStruct; //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self)

#[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]
a: u8, //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self)
#[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]
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]
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]
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]
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]
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]
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 {
#[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]
#[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]
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() {}
40 changes: 17 additions & 23 deletions src/test/ui/privacy/access_levels.stderr
Original file line number Diff line number Diff line change
@@ -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
|
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
|
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
|
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
|
LL | pub trait PubTrait {
@@ -28,7 +28,7 @@ error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFr
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
|
LL | pub union PubUnion {
@@ -40,31 +40,31 @@ error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFr
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
|
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
|
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
|
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
|
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
|
LL | macro_rules! none_macro {
@@ -76,13 +76,13 @@ error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
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
|
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
|
LL | pub a: u8,
@@ -94,13 +94,13 @@ error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
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
|
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
|
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;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self)
--> $DIR/access_levels.rs:72:9
|
LL | pub use half_public_import::HalfPublicImport;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:14:13
|
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
|
LL | type B;
| ^^^^^^

error: aborting due to 22 previous errors
error: aborting due to 21 previous errors