privacy: Rename "accessibility levels" to "effective visibilities"

And a couple of other naming tweaks

Related to https://github.com/rust-lang/rust/issues/48054
This commit is contained in:
Vadim Petrochenkov 2022-09-22 16:19:53 +03:00
parent 629a414d7b
commit 34eb73c72d
53 changed files with 524 additions and 516 deletions

View File

@ -927,7 +927,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
sess.time("misc_checking_3", || {
parallel!(
{
tcx.ensure().privacy_access_levels(());
tcx.ensure().effective_visibilities(());
parallel!(
{

View File

@ -563,7 +563,7 @@ impl MissingDoc {
// It's an option so the crate root can also use this function (it doesn't
// have a `NodeId`).
if def_id != CRATE_DEF_ID {
if !cx.access_levels.is_exported(def_id) {
if !cx.effective_visibilities.is_exported(def_id) {
return;
}
}
@ -721,7 +721,7 @@ declare_lint_pass!(MissingCopyImplementations => [MISSING_COPY_IMPLEMENTATIONS])
impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
if !cx.access_levels.is_reachable(item.def_id.def_id) {
if !cx.effective_visibilities.is_reachable(item.def_id.def_id) {
return;
}
let (def, ty) = match item.kind {
@ -814,7 +814,7 @@ impl_lint_pass!(MissingDebugImplementations => [MISSING_DEBUG_IMPLEMENTATIONS]);
impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
if !cx.access_levels.is_reachable(item.def_id.def_id) {
if !cx.effective_visibilities.is_reachable(item.def_id.def_id) {
return;
}
@ -1385,7 +1385,8 @@ impl UnreachablePub {
exportable: bool,
) {
let mut applicability = Applicability::MachineApplicable;
if cx.tcx.visibility(def_id).is_public() && !cx.access_levels.is_reachable(def_id) {
if cx.tcx.visibility(def_id).is_public() && !cx.effective_visibilities.is_reachable(def_id)
{
if vis_span.from_expansion() {
applicability = Applicability::MaybeIncorrect;
}

View File

@ -31,7 +31,7 @@ use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::def_id::{CrateNum, DefId};
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_middle::middle::privacy::AccessLevels;
use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::middle::stability;
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::print::with_no_trimmed_paths;
@ -542,7 +542,7 @@ pub struct LateContext<'tcx> {
pub param_env: ty::ParamEnv<'tcx>,
/// Items accessible from the crate being checked.
pub access_levels: &'tcx AccessLevels,
pub effective_visibilities: &'tcx EffectiveVisibilities,
/// The store of registered lints and the lint levels.
pub lint_store: &'tcx LintStore,

View File

@ -338,14 +338,14 @@ fn late_lint_mod_pass<'tcx, T: LateLintPass<'tcx>>(
module_def_id: LocalDefId,
pass: T,
) {
let access_levels = &tcx.privacy_access_levels(());
let effective_visibilities = &tcx.effective_visibilities(());
let context = LateContext {
tcx,
enclosing_body: None,
cached_typeck_results: Cell::new(None),
param_env: ty::ParamEnv::empty(),
access_levels,
effective_visibilities,
lint_store: unerased_lint_store(tcx),
last_node_with_lint_attrs: tcx.hir().local_def_id_to_hir_id(module_def_id),
generics: None,
@ -386,14 +386,14 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx>>(
}
fn late_lint_pass_crate<'tcx, T: LateLintPass<'tcx>>(tcx: TyCtxt<'tcx>, pass: T) {
let access_levels = &tcx.privacy_access_levels(());
let effective_visibilities = &tcx.effective_visibilities(());
let context = LateContext {
tcx,
enclosing_body: None,
cached_typeck_results: Cell::new(None),
param_env: ty::ParamEnv::empty(),
access_levels,
effective_visibilities,
lint_store: unerased_lint_store(tcx),
last_node_with_lint_attrs: hir::CRATE_HIR_ID,
generics: None,

View File

@ -212,7 +212,7 @@ macro_rules! late_lint_mod_passes {
TypeLimits: TypeLimits::new(),
NonSnakeCase: NonSnakeCase,
InvalidNoMangleItems: InvalidNoMangleItems,
// Depends on access levels
// Depends on effective visibilities
UnreachablePub: UnreachablePub,
ExplicitOutlivesRequirements: ExplicitOutlivesRequirements,
InvalidValue: InvalidValue,

View File

@ -787,9 +787,8 @@ fn should_encode_attr(
} else if attr.doc_str().is_some() {
// We keep all public doc comments because they might be "imported" into downstream crates
// if they use `#[doc(inline)]` to copy an item's documentation into their own.
*is_def_id_public.get_or_insert_with(|| {
tcx.privacy_access_levels(()).get_effective_vis(def_id).is_some()
})
*is_def_id_public
.get_or_insert_with(|| tcx.effective_visibilities(()).effective_vis(def_id).is_some())
} else if attr.has_name(sym::doc) {
// If this is a `doc` attribute, and it's marked `inline` (as in `#[doc(inline)]`), we can
// remove it. It won't be inlinable in downstream crates.

View File

@ -77,7 +77,7 @@ macro_rules! arena_types {
rustc_middle::infer::canonical::QueryResponse<'tcx, rustc_middle::ty::Ty<'tcx>>
>,
[] all_traits: Vec<rustc_hir::def_id::DefId>,
[] privacy_access_levels: rustc_middle::middle::privacy::AccessLevels,
[] effective_visibilities: rustc_middle::middle::privacy::EffectiveVisibilities,
[] foreign_module: rustc_session::cstore::ForeignModule,
[] foreign_modules: Vec<rustc_session::cstore::ForeignModule>,
[] upvars_mentioned: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,

View File

@ -9,106 +9,101 @@ use rustc_query_system::ich::StableHashingContext;
use rustc_span::def_id::{DefId, LocalDefId};
use std::hash::Hash;
/// Represents the levels of accessibility an item can have.
/// Represents the levels of effective visibility an item can have.
///
/// The variants are sorted in ascending order of accessibility.
/// The variants are sorted in ascending order of directness.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, HashStable)]
pub enum AccessLevel {
/// Superset of `AccessLevel::Reachable` used to mark impl Trait items.
ReachableFromImplTrait,
/// Exported items + items participating in various kinds of public interfaces,
/// but not directly nameable. For example, if function `fn f() -> T {...}` is
/// public, then type `T` is reachable. Its values can be obtained by other crates
/// even if the type itself is not nameable.
pub enum Level {
/// Superset of `Reachable` including items leaked through return position `impl Trait`.
ReachableThroughImplTrait,
/// Item is either reexported, or leaked through any kind of interface.
/// For example, if function `fn f() -> T {...}` is directly public, then type `T` is publicly
/// reachable and its values can be obtained by other crates even if the type itself is not
/// nameable.
Reachable,
/// Public items + items accessible to other crates with the help of `pub use` re-exports.
Exported,
/// Items accessible to other crates directly, without the help of re-exports.
Public,
/// Item is accessible either directly, or with help of `use` reexports.
Reexported,
/// Item is directly accessible, without help of reexports.
Direct,
}
impl AccessLevel {
pub fn all_levels() -> [AccessLevel; 4] {
[
AccessLevel::Public,
AccessLevel::Exported,
AccessLevel::Reachable,
AccessLevel::ReachableFromImplTrait,
]
impl Level {
pub fn all_levels() -> [Level; 4] {
[Level::Direct, Level::Reexported, Level::Reachable, Level::ReachableThroughImplTrait]
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable)]
pub struct EffectiveVisibility {
public: Visibility,
exported: Visibility,
direct: Visibility,
reexported: Visibility,
reachable: Visibility,
reachable_from_impl_trait: Visibility,
reachable_through_impl_trait: Visibility,
}
impl EffectiveVisibility {
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,
pub fn at_level(&self, level: Level) -> &Visibility {
match level {
Level::Direct => &self.direct,
Level::Reexported => &self.reexported,
Level::Reachable => &self.reachable,
Level::ReachableThroughImplTrait => &self.reachable_through_impl_trait,
}
}
fn get_mut(&mut self, tag: AccessLevel) -> &mut Visibility {
match tag {
AccessLevel::Public => &mut self.public,
AccessLevel::Exported => &mut self.exported,
AccessLevel::Reachable => &mut self.reachable,
AccessLevel::ReachableFromImplTrait => &mut self.reachable_from_impl_trait,
fn at_level_mut(&mut self, level: Level) -> &mut Visibility {
match level {
Level::Direct => &mut self.direct,
Level::Reexported => &mut self.reexported,
Level::Reachable => &mut self.reachable,
Level::ReachableThroughImplTrait => &mut self.reachable_through_impl_trait,
}
}
pub fn is_public_at_level(&self, tag: AccessLevel) -> bool {
self.get(tag).is_public()
pub fn is_public_at_level(&self, level: Level) -> bool {
self.at_level(level).is_public()
}
pub fn from_vis(vis: Visibility) -> EffectiveVisibility {
EffectiveVisibility {
public: vis,
exported: vis,
direct: vis,
reexported: vis,
reachable: vis,
reachable_from_impl_trait: vis,
reachable_through_impl_trait: vis,
}
}
}
/// Holds a map of accessibility levels for reachable HIR nodes.
/// Holds a map of effective visibilities for reachable HIR nodes.
#[derive(Debug, Clone)]
pub struct AccessLevels<Id = LocalDefId> {
pub struct EffectiveVisibilities<Id = LocalDefId> {
map: FxHashMap<Id, EffectiveVisibility>,
}
impl<Id: Hash + Eq + Copy> AccessLevels<Id> {
pub fn is_public_at_level(&self, id: Id, tag: AccessLevel) -> bool {
self.get_effective_vis(id)
.map_or(false, |effective_vis| effective_vis.is_public_at_level(tag))
impl<Id: Hash + Eq + Copy> EffectiveVisibilities<Id> {
pub fn is_public_at_level(&self, id: Id, level: Level) -> bool {
self.effective_vis(id)
.map_or(false, |effective_vis| effective_vis.is_public_at_level(level))
}
/// See `AccessLevel::Reachable`.
/// See `Level::Reachable`.
pub fn is_reachable(&self, id: Id) -> bool {
self.is_public_at_level(id, AccessLevel::Reachable)
self.is_public_at_level(id, Level::Reachable)
}
/// See `AccessLevel::Exported`.
/// See `Level::Reexported`.
pub fn is_exported(&self, id: Id) -> bool {
self.is_public_at_level(id, AccessLevel::Exported)
self.is_public_at_level(id, Level::Reexported)
}
/// See `AccessLevel::Public`.
pub fn is_public(&self, id: Id) -> bool {
self.is_public_at_level(id, AccessLevel::Public)
/// See `Level::Direct`.
pub fn is_directly_public(&self, id: Id) -> bool {
self.is_public_at_level(id, Level::Direct)
}
pub fn get_access_level(&self, id: Id) -> Option<AccessLevel> {
self.get_effective_vis(id).and_then(|effective_vis| {
for level in AccessLevel::all_levels() {
pub fn public_at_level(&self, id: Id) -> Option<Level> {
self.effective_vis(id).and_then(|effective_vis| {
for level in Level::all_levels() {
if effective_vis.is_public_at_level(level) {
return Some(level);
}
@ -117,7 +112,7 @@ impl<Id: Hash + Eq + Copy> AccessLevels<Id> {
})
}
pub fn get_effective_vis(&self, id: Id) -> Option<&EffectiveVisibility> {
pub fn effective_vis(&self, id: Id) -> Option<&EffectiveVisibility> {
self.map.get(&id)
}
@ -125,30 +120,33 @@ impl<Id: Hash + Eq + Copy> AccessLevels<Id> {
self.map.iter()
}
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 map_id<OutId: Hash + Eq + Copy>(
&self,
f: impl Fn(Id) -> OutId,
) -> EffectiveVisibilities<OutId> {
EffectiveVisibilities { map: self.map.iter().map(|(k, v)| (f(*k), *v)).collect() }
}
pub fn set_access_level(
pub fn set_public_at_level(
&mut self,
id: Id,
default_vis: impl FnOnce() -> Visibility,
tag: AccessLevel,
level: Level,
) {
let mut effective_vis = self
.get_effective_vis(id)
.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;
for l in Level::all_levels() {
if l <= level {
*effective_vis.at_level_mut(l) = Visibility::Public;
}
}
self.map.insert(id, effective_vis);
}
}
impl<Id: Hash + Eq + Copy + Into<DefId>> AccessLevels<Id> {
impl<Id: Hash + Eq + Copy + Into<DefId>> EffectiveVisibilities<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(
@ -157,28 +155,29 @@ impl<Id: Hash + Eq + Copy + Into<DefId>> AccessLevels<Id> {
nominal_vis: Visibility,
default_vis: impl FnOnce() -> Visibility,
parent_id: Id,
tag: AccessLevel,
level: Level,
tree: impl DefIdTree,
) -> bool {
let mut changed = false;
let mut current_effective_vis = self.get_effective_vis(id).copied().unwrap_or_else(|| {
let mut current_effective_vis = self.effective_vis(id).copied().unwrap_or_else(|| {
if id.into().is_crate_root() {
EffectiveVisibility::from_vis(Visibility::Public)
} else {
EffectiveVisibility::from_vis(default_vis())
}
});
if let Some(inherited_effective_vis) = self.get_effective_vis(parent_id) {
let mut inherited_effective_vis_at_prev_level = *inherited_effective_vis.get(tag);
if let Some(inherited_effective_vis) = self.effective_vis(parent_id) {
let mut inherited_effective_vis_at_prev_level =
*inherited_effective_vis.at_level(level);
let mut calculated_effective_vis = inherited_effective_vis_at_prev_level;
for level in AccessLevel::all_levels() {
if tag >= level {
let inherited_effective_vis_at_level = *inherited_effective_vis.get(level);
let current_effective_vis_at_level = current_effective_vis.get_mut(level);
for l in Level::all_levels() {
if level >= l {
let inherited_effective_vis_at_level = *inherited_effective_vis.at_level(l);
let current_effective_vis_at_level = current_effective_vis.at_level_mut(l);
// effective visibility for id shouldn't be recalculated if
// inherited from parent_id effective visibility isn't changed at next level
if !(inherited_effective_vis_at_prev_level == inherited_effective_vis_at_level
&& tag != level)
&& level != l)
{
calculated_effective_vis =
if nominal_vis.is_at_least(inherited_effective_vis_at_level, tree) {
@ -205,15 +204,15 @@ impl<Id: Hash + Eq + Copy + Into<DefId>> AccessLevels<Id> {
}
}
impl<Id> Default for AccessLevels<Id> {
impl<Id> Default for EffectiveVisibilities<Id> {
fn default() -> Self {
AccessLevels { map: Default::default() }
EffectiveVisibilities { map: Default::default() }
}
}
impl<'a> HashStable<StableHashingContext<'a>> for AccessLevels {
impl<'a> HashStable<StableHashingContext<'a>> for EffectiveVisibilities {
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
let AccessLevels { ref map } = *self;
let EffectiveVisibilities { ref map } = *self;
map.hash_stable(hcx, hasher);
}
}

View File

@ -1065,10 +1065,10 @@ rustc_queries! {
cache_on_disk_if { key.is_local() }
}
/// Performs part of the privacy check and computes "access levels".
query privacy_access_levels(_: ()) -> &'tcx AccessLevels {
/// Performs part of the privacy check and computes effective visibilities.
query effective_visibilities(_: ()) -> &'tcx EffectiveVisibilities {
eval_always
desc { "checking privacy access levels" }
desc { "checking effective visibilities" }
}
query check_private_in_public(_: ()) -> () {
eval_always

View File

@ -17,7 +17,7 @@ pub use self::IntVarValue::*;
pub use self::Variance::*;
use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
use crate::metadata::ModChild;
use crate::middle::privacy::AccessLevels;
use crate::middle::privacy::EffectiveVisibilities;
use crate::mir::{Body, GeneratorLayout};
use crate::traits::{self, Reveal};
use crate::ty;
@ -160,7 +160,7 @@ pub struct ResolverGlobalCtxt {
pub expn_that_defined: FxHashMap<LocalDefId, ExpnId>,
/// Reference span for definitions.
pub source_span: IndexVec<LocalDefId, Span>,
pub access_levels: AccessLevels,
pub effective_visibilities: EffectiveVisibilities,
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,

View File

@ -5,7 +5,7 @@ use crate::metadata::ModChild;
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
use crate::middle::lib_features::LibFeatures;
use crate::middle::privacy::AccessLevels;
use crate::middle::privacy::EffectiveVisibilities;
use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes};
use crate::middle::stability::{self, DeprecationEntry};
use crate::mir;

View File

@ -11,7 +11,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Node, PatKind, TyKind};
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::privacy::AccessLevel;
use rustc_middle::middle::privacy::Level;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
use rustc_session::lint;
@ -604,13 +604,13 @@ fn check_foreign_item<'tcx>(
fn create_and_seed_worklist<'tcx>(
tcx: TyCtxt<'tcx>,
) -> (Vec<LocalDefId>, FxHashMap<LocalDefId, LocalDefId>) {
let access_levels = &tcx.privacy_access_levels(());
let effective_visibilities = &tcx.effective_visibilities(());
// see `MarkSymbolVisitor::struct_constructors`
let mut struct_constructors = Default::default();
let mut worklist = access_levels
let mut worklist = effective_visibilities
.iter()
.filter_map(|(&id, effective_vis)| {
effective_vis.is_public_at_level(AccessLevel::Reachable).then_some(id)
effective_vis.is_public_at_level(Level::Reachable).then_some(id)
})
// Seed entry point
.chain(tcx.entry_fn(()).and_then(|(def_id, _)| def_id.as_local()))

View File

@ -12,7 +12,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::Node;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::middle::privacy::{self, AccessLevel};
use rustc_middle::middle::privacy::{self, Level};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, DefIdTree, TyCtxt};
use rustc_session::config::CrateType;
@ -303,7 +303,7 @@ fn check_item<'tcx>(
tcx: TyCtxt<'tcx>,
id: hir::ItemId,
worklist: &mut Vec<LocalDefId>,
access_levels: &privacy::AccessLevels,
effective_visibilities: &privacy::EffectiveVisibilities,
) {
if has_custom_linkage(tcx, id.def_id.def_id) {
worklist.push(id.def_id.def_id);
@ -318,7 +318,7 @@ fn check_item<'tcx>(
if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) =
item.kind
{
if !access_levels.is_reachable(item.def_id.def_id) {
if !effective_visibilities.is_reachable(item.def_id.def_id) {
worklist.extend(items.iter().map(|ii_ref| ii_ref.id.def_id.def_id));
let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res else {
@ -354,7 +354,7 @@ fn has_custom_linkage<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
}
fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet<LocalDefId> {
let access_levels = &tcx.privacy_access_levels(());
let effective_visibilities = &tcx.effective_visibilities(());
let any_library =
tcx.sess.crate_types().iter().any(|ty| {
@ -373,10 +373,10 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet<LocalDefId> {
// If other crates link to us, they're going to expect to be able to
// use the lang items, so we need to be sure to mark them as
// exported.
reachable_context.worklist = access_levels
reachable_context.worklist = effective_visibilities
.iter()
.filter_map(|(&id, effective_vis)| {
effective_vis.is_public_at_level(AccessLevel::ReachableFromImplTrait).then_some(id)
effective_vis.is_public_at_level(Level::ReachableThroughImplTrait).then_some(id)
})
.collect::<Vec<_>>();
@ -399,7 +399,7 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet<LocalDefId> {
let crate_items = tcx.hir_crate_items(());
for id in crate_items.items() {
check_item(tcx, id, &mut reachable_context.worklist, access_levels);
check_item(tcx, id, &mut reachable_context.worklist, effective_visibilities);
}
for id in crate_items.impl_items() {

View File

@ -20,7 +20,7 @@ use rustc_hir::hir_id::CRATE_HIR_ID;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{FieldDef, Item, ItemKind, TraitRef, Ty, TyKind, Variant};
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::privacy::AccessLevels;
use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::middle::stability::{AllowUnstable, DeprecationEntry, Index};
use rustc_middle::ty::{query::Providers, TyCtxt};
use rustc_session::lint;
@ -516,13 +516,16 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
struct MissingStabilityAnnotations<'tcx> {
tcx: TyCtxt<'tcx>,
access_levels: &'tcx AccessLevels,
effective_visibilities: &'tcx EffectiveVisibilities,
}
impl<'tcx> MissingStabilityAnnotations<'tcx> {
fn check_missing_stability(&self, def_id: LocalDefId, span: Span) {
let stab = self.tcx.stability().local_stability(def_id);
if !self.tcx.sess.opts.test && stab.is_none() && self.access_levels.is_reachable(def_id) {
if !self.tcx.sess.opts.test
&& stab.is_none()
&& self.effective_visibilities.is_reachable(def_id)
{
let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id());
self.tcx.sess.emit_err(MissingStabilityAttr { span, descr });
}
@ -540,7 +543,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
.lookup_stability(def_id)
.map_or(false, |stability| stability.level.is_stable());
let missing_const_stability_attribute = self.tcx.lookup_const_stability(def_id).is_none();
let is_reachable = self.access_levels.is_reachable(def_id);
let is_reachable = self.effective_visibilities.is_reachable(def_id);
if is_const && is_stable && missing_const_stability_attribute && is_reachable {
let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id());
@ -919,8 +922,8 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
let is_staged_api =
tcx.sess.opts.unstable_opts.force_unstable_if_unmarked || tcx.features().staged_api;
if is_staged_api {
let access_levels = &tcx.privacy_access_levels(());
let mut missing = MissingStabilityAnnotations { tcx, access_levels };
let effective_visibilities = &tcx.effective_visibilities(());
let mut missing = MissingStabilityAnnotations { tcx, effective_visibilities };
missing.check_missing_stability(CRATE_DEF_ID, tcx.hir().span(CRATE_HIR_ID));
tcx.hir().walk_toplevel_module(&mut missing);
tcx.hir().visit_all_item_likes_in_crate(&mut missing);

View File

@ -23,7 +23,7 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind};
use rustc_middle::bug;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
use rustc_middle::middle::privacy::{EffectiveVisibilities, Level};
use rustc_middle::span_bug;
use rustc_middle::ty::abstract_const::{walk_abstract_const, AbstractConst, Node as ACNode};
use rustc_middle::ty::query::Providers;
@ -310,7 +310,7 @@ fn min(vis1: ty::Visibility, vis2: ty::Visibility, tcx: TyCtxt<'_>) -> ty::Visib
struct FindMin<'a, 'tcx, VL: VisibilityLike> {
tcx: TyCtxt<'tcx>,
access_levels: &'a AccessLevels,
effective_visibilities: &'a EffectiveVisibilities,
min: VL,
}
@ -344,8 +344,12 @@ trait VisibilityLike: Sized {
// Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to
// associated types for which we can't determine visibility precisely.
fn of_impl(def_id: LocalDefId, tcx: TyCtxt<'_>, access_levels: &AccessLevels) -> Self {
let mut find = FindMin { tcx, access_levels, min: Self::MAX };
fn of_impl(
def_id: LocalDefId,
tcx: TyCtxt<'_>,
effective_visibilities: &EffectiveVisibilities,
) -> Self {
let mut find = FindMin { tcx, effective_visibilities, min: Self::MAX };
find.visit(tcx.type_of(def_id));
if let Some(trait_ref) = tcx.impl_trait_ref(def_id) {
find.visit_trait(trait_ref);
@ -359,8 +363,8 @@ impl VisibilityLike for ty::Visibility {
min(find.tcx.local_visibility(def_id), find.min, find.tcx)
}
}
impl VisibilityLike for Option<AccessLevel> {
const MAX: Self = Some(AccessLevel::Public);
impl VisibilityLike for Option<Level> {
const MAX: Self = Some(Level::Direct);
// Type inference is very smart sometimes.
// It can make an impl reachable even some components of its type or trait are unreachable.
// E.g. methods of `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
@ -372,7 +376,7 @@ impl VisibilityLike for Option<AccessLevel> {
// (which require reaching the `DefId`s in them).
const SHALLOW: bool = true;
fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self {
cmp::min(find.access_levels.get_access_level(def_id), find.min)
cmp::min(find.effective_visibilities.public_at_level(def_id), find.min)
}
}
@ -383,8 +387,8 @@ impl VisibilityLike for Option<AccessLevel> {
struct EmbargoVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
/// Accessibility levels for reachable nodes.
access_levels: AccessLevels,
/// Effective visibilities for reachable nodes.
effective_visibilities: EffectiveVisibilities,
/// A set of pairs corresponding to modules, where the first module is
/// reachable via a macro that's defined in the second module. This cannot
/// be represented as reachable because it can't handle the following case:
@ -398,38 +402,34 @@ struct EmbargoVisitor<'tcx> {
/// n::p::f()
/// }
macro_reachable: FxHashSet<(LocalDefId, LocalDefId)>,
/// Previous accessibility level; `None` means unreachable.
prev_level: Option<AccessLevel>,
/// Previous visibility level; `None` means unreachable.
prev_level: Option<Level>,
/// Has something changed in the level map?
changed: bool,
}
struct ReachEverythingInTheInterfaceVisitor<'a, 'tcx> {
access_level: Option<AccessLevel>,
level: Option<Level>,
item_def_id: LocalDefId,
ev: &'a mut EmbargoVisitor<'tcx>,
}
impl<'tcx> EmbargoVisitor<'tcx> {
fn get(&self, def_id: LocalDefId) -> Option<AccessLevel> {
self.access_levels.get_access_level(def_id)
fn get(&self, def_id: LocalDefId) -> Option<Level> {
self.effective_visibilities.public_at_level(def_id)
}
fn update_with_hir_id(
&mut self,
hir_id: hir::HirId,
level: Option<AccessLevel>,
) -> Option<AccessLevel> {
fn update_with_hir_id(&mut self, hir_id: hir::HirId, level: Option<Level>) -> Option<Level> {
let def_id = self.tcx.hir().local_def_id(hir_id);
self.update(def_id, level)
}
/// Updates node level and returns the updated level.
fn update(&mut self, def_id: LocalDefId, level: Option<AccessLevel>) -> Option<AccessLevel> {
fn update(&mut self, def_id: LocalDefId, level: Option<Level>) -> Option<Level> {
let old_level = self.get(def_id);
// Accessibility levels can only grow.
// Visibility levels can only grow.
if level > old_level {
self.access_levels.set_access_level(
self.effective_visibilities.set_public_at_level(
def_id,
|| ty::Visibility::Restricted(self.tcx.parent_module_from_def_id(def_id)),
level.unwrap(),
@ -444,10 +444,10 @@ impl<'tcx> EmbargoVisitor<'tcx> {
fn reach(
&mut self,
def_id: LocalDefId,
access_level: Option<AccessLevel>,
level: Option<Level>,
) -> ReachEverythingInTheInterfaceVisitor<'_, 'tcx> {
ReachEverythingInTheInterfaceVisitor {
access_level: cmp::min(access_level, Some(AccessLevel::Reachable)),
level: cmp::min(level, Some(Level::Reachable)),
item_def_id: def_id,
ev: self,
}
@ -530,7 +530,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
vis: ty::Visibility,
module: LocalDefId,
) {
let level = Some(AccessLevel::Reachable);
let level = Some(Level::Reachable);
if vis.is_public() {
self.update(def_id, level);
}
@ -627,10 +627,10 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
let item_level = match item.kind {
hir::ItemKind::Impl { .. } => {
let impl_level = Option::<AccessLevel>::of_impl(
let impl_level = Option::<Level>::of_impl(
item.def_id.def_id,
self.tcx,
&self.access_levels,
&self.effective_visibilities,
);
self.update(item.def_id.def_id, impl_level)
}
@ -705,7 +705,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
hir::ItemKind::Macro(..) | hir::ItemKind::ExternCrate(..) => {}
// All nested items are checked by `visit_item`.
hir::ItemKind::Mod(..) => {}
// Handled in the access level of in rustc_resolve
// Handled in `rustc_resolve`.
hir::ItemKind::Use(..) => {}
// The interface is empty.
hir::ItemKind::GlobalAsm(..) => {}
@ -718,8 +718,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
// FIXME: This is some serious pessimization intended to workaround deficiencies
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
// reachable if they are returned via `impl Trait`, even from private functions.
let exist_level =
cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait));
let exist_level = cmp::max(item_level, Some(Level::ReachableThroughImplTrait));
self.reach(item.def_id.def_id, exist_level).generics().predicates().ty();
}
}
@ -901,10 +900,10 @@ impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx>
_descr: &dyn fmt::Display,
) -> ControlFlow<Self::BreakTy> {
if let Some(def_id) = def_id.as_local() {
if let (ty::Visibility::Public, _) | (_, Some(AccessLevel::ReachableFromImplTrait)) =
(self.tcx().visibility(def_id.to_def_id()), self.access_level)
if let (ty::Visibility::Public, _) | (_, Some(Level::ReachableThroughImplTrait)) =
(self.tcx().visibility(def_id.to_def_id()), self.level)
{
self.ev.update(def_id, self.access_level);
self.ev.update(def_id, self.level);
}
}
ControlFlow::CONTINUE
@ -912,21 +911,21 @@ impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx>
}
////////////////////////////////////////////////////////////////////////////////
/// Visitor, used for AccessLevels table checking
/// Visitor, used for EffectiveVisibilities table checking
////////////////////////////////////////////////////////////////////////////////
pub struct TestReachabilityVisitor<'tcx, 'a> {
tcx: TyCtxt<'tcx>,
access_levels: &'a AccessLevels,
effective_visibilities: &'a EffectiveVisibilities,
}
impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
fn access_level_diagnostic(&mut self, def_id: LocalDefId) {
fn effective_visibility_diagnostic(&mut self, def_id: LocalDefId) {
if self.tcx.has_attr(def_id.to_def_id(), sym::rustc_effective_visibility) {
let mut error_msg = String::new();
let span = self.tcx.def_span(def_id.to_def_id());
if let Some(effective_vis) = self.access_levels.get_effective_vis(def_id) {
for level in AccessLevel::all_levels() {
let vis_str = match effective_vis.get(level) {
if let Some(effective_vis) = self.effective_visibilities.effective_vis(def_id) {
for level in Level::all_levels() {
let vis_str = match effective_vis.at_level(level) {
ty::Visibility::Restricted(restricted_id) => {
if restricted_id.is_top_level_module() {
"pub(crate)".to_string()
@ -938,7 +937,7 @@ impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
}
ty::Visibility::Public => "pub".to_string(),
};
if level != AccessLevel::Public {
if level != Level::Direct {
error_msg.push_str(", ");
}
error_msg.push_str(&format!("{:?}: {}", level, vis_str));
@ -953,23 +952,23 @@ impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
impl<'tcx, 'a> Visitor<'tcx> for TestReachabilityVisitor<'tcx, 'a> {
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
self.access_level_diagnostic(item.def_id.def_id);
self.effective_visibility_diagnostic(item.def_id.def_id);
match item.kind {
hir::ItemKind::Enum(ref def, _) => {
for variant in def.variants.iter() {
let variant_id = self.tcx.hir().local_def_id(variant.id);
self.access_level_diagnostic(variant_id);
self.effective_visibility_diagnostic(variant_id);
for field in variant.data.fields() {
let def_id = self.tcx.hir().local_def_id(field.hir_id);
self.access_level_diagnostic(def_id);
self.effective_visibility_diagnostic(def_id);
}
}
}
hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => {
for field in def.fields() {
let def_id = self.tcx.hir().local_def_id(field.hir_id);
self.access_level_diagnostic(def_id);
self.effective_visibility_diagnostic(def_id);
}
}
_ => {}
@ -977,13 +976,13 @@ impl<'tcx, 'a> Visitor<'tcx> for TestReachabilityVisitor<'tcx, 'a> {
}
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem<'tcx>) {
self.access_level_diagnostic(item.def_id.def_id);
self.effective_visibility_diagnostic(item.def_id.def_id);
}
fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem<'tcx>) {
self.access_level_diagnostic(item.def_id.def_id);
self.effective_visibility_diagnostic(item.def_id.def_id);
}
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
self.access_level_diagnostic(item.def_id.def_id);
self.effective_visibility_diagnostic(item.def_id.def_id);
}
}
@ -1054,7 +1053,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
fn visit_mod(&mut self, _m: &'tcx hir::Mod<'tcx>, _s: Span, _n: hir::HirId) {
// Don't visit nested modules, since we run a separate visitor walk
// for each module in `privacy_access_levels`
// for each module in `effective_visibilities`
}
fn visit_nested_body(&mut self, body: hir::BodyId) {
@ -1179,7 +1178,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
fn visit_mod(&mut self, _m: &'tcx hir::Mod<'tcx>, _s: Span, _n: hir::HirId) {
// Don't visit nested modules, since we run a separate visitor walk
// for each module in `privacy_access_levels`
// for each module in `effective_visibilities`
}
fn visit_nested_body(&mut self, body: hir::BodyId) {
@ -1404,7 +1403,7 @@ impl<'tcx> DefIdVisitor<'tcx> for TypePrivacyVisitor<'tcx> {
struct ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
access_levels: &'a AccessLevels,
effective_visibilities: &'a EffectiveVisibilities,
in_variant: bool,
// Set of errors produced by this obsolete visitor.
old_error_set: HirIdSet,
@ -1447,7 +1446,7 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
fn trait_is_public(&self, trait_id: LocalDefId) -> bool {
// FIXME: this would preferably be using `exported_items`, but all
// traits are exported currently (see `EmbargoVisitor.exported_trait`).
self.access_levels.is_public(trait_id)
self.effective_visibilities.is_directly_public(trait_id)
}
fn check_generic_bound(&mut self, bound: &hir::GenericBound<'_>) {
@ -1459,7 +1458,7 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
}
fn item_is_public(&self, def_id: LocalDefId) -> bool {
self.access_levels.is_reachable(def_id) || self.tcx.visibility(def_id).is_public()
self.effective_visibilities.is_reachable(def_id) || self.tcx.visibility(def_id).is_public()
}
}
@ -1573,9 +1572,9 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|| impl_.items.iter().any(|impl_item_ref| {
let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
match impl_item.kind {
hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) => {
self.access_levels.is_reachable(impl_item_ref.id.def_id.def_id)
}
hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) => self
.effective_visibilities
.is_reachable(impl_item_ref.id.def_id.def_id),
hir::ImplItemKind::Type(_) => false,
}
});
@ -1635,7 +1634,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
// methods will be visible as `Public::foo`.
let mut found_pub_static = false;
for impl_item_ref in impl_.items {
if self.access_levels.is_reachable(impl_item_ref.id.def_id.def_id)
if self.effective_visibilities.is_reachable(impl_item_ref.id.def_id.def_id)
|| self.tcx.visibility(impl_item_ref.id.def_id).is_public()
{
let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
@ -1695,7 +1694,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
}
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
if self.access_levels.is_reachable(item.def_id.def_id) {
if self.effective_visibilities.is_reachable(item.def_id.def_id) {
intravisit::walk_foreign_item(self, item)
}
}
@ -1710,7 +1709,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
}
fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) {
if self.access_levels.is_reachable(self.tcx.hir().local_def_id(v.id)) {
if self.effective_visibilities.is_reachable(self.tcx.hir().local_def_id(v.id)) {
self.in_variant = true;
intravisit::walk_variant(self, v);
self.in_variant = false;
@ -2040,7 +2039,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
pub fn provide(providers: &mut Providers) {
*providers = Providers {
visibility,
privacy_access_levels,
effective_visibilities,
check_private_in_public,
check_mod_privacy,
..*providers
@ -2112,14 +2111,14 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
intravisit::walk_mod(&mut visitor, module, hir_id);
}
fn privacy_access_levels(tcx: TyCtxt<'_>, (): ()) -> &AccessLevels {
fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
// Build up a set of all exported items in the AST. This is a set of all
// items which are reachable from external crates based on visibility.
let mut visitor = EmbargoVisitor {
tcx,
access_levels: tcx.resolutions(()).access_levels.clone(),
effective_visibilities: tcx.resolutions(()).effective_visibilities.clone(),
macro_reachable: Default::default(),
prev_level: Some(AccessLevel::Public),
prev_level: Some(Level::Direct),
changed: false,
};
@ -2132,18 +2131,19 @@ fn privacy_access_levels(tcx: TyCtxt<'_>, (): ()) -> &AccessLevels {
}
}
let mut check_visitor = TestReachabilityVisitor { tcx, access_levels: &visitor.access_levels };
let mut check_visitor =
TestReachabilityVisitor { tcx, effective_visibilities: &visitor.effective_visibilities };
tcx.hir().visit_all_item_likes_in_crate(&mut check_visitor);
tcx.arena.alloc(visitor.access_levels)
tcx.arena.alloc(visitor.effective_visibilities)
}
fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
let access_levels = tcx.privacy_access_levels(());
let effective_visibilities = tcx.effective_visibilities(());
let mut visitor = ObsoleteVisiblePrivateTypesVisitor {
tcx,
access_levels,
effective_visibilities,
in_variant: false,
old_error_set: Default::default(),
};

View File

@ -6,55 +6,54 @@ use rustc_ast::Crate;
use rustc_ast::EnumDef;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_middle::middle::privacy::AccessLevel;
use rustc_middle::middle::privacy::Level;
use rustc_middle::ty::{DefIdTree, Visibility};
pub struct AccessLevelsVisitor<'r, 'a> {
pub struct EffectiveVisibilitiesVisitor<'r, 'a> {
r: &'r mut Resolver<'a>,
changed: bool,
}
impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
/// Fills the `Resolver::access_levels` table with public & exported items
impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
/// Fills the `Resolver::effective_visibilities` table with public & exported items
/// For now, this doesn't resolve macros (FIXME) and cannot resolve Impl, as we
/// need access to a TyCtxt for that.
pub fn compute_access_levels<'c>(r: &'r mut Resolver<'a>, krate: &'c Crate) {
let mut visitor = AccessLevelsVisitor { r, changed: false };
pub fn compute_effective_visibilities<'c>(r: &'r mut Resolver<'a>, krate: &'c Crate) {
let mut visitor = EffectiveVisibilitiesVisitor { r, changed: false };
visitor.update(CRATE_DEF_ID, Visibility::Public, CRATE_DEF_ID, AccessLevel::Public);
visitor.set_bindings_access_level(CRATE_DEF_ID);
visitor.update(CRATE_DEF_ID, Visibility::Public, CRATE_DEF_ID, Level::Direct);
visitor.set_bindings_effective_visibilities(CRATE_DEF_ID);
while visitor.changed {
visitor.reset();
visit::walk_crate(&mut visitor, krate);
}
info!("resolve::access_levels: {:#?}", r.access_levels);
info!("resolve::effective_visibilities: {:#?}", r.effective_visibilities);
}
fn reset(&mut self) {
self.changed = false;
}
/// Update the access level of the bindings in the given module accordingly. The module access
/// level has to be Exported or Public.
/// This will also follow `use` chains (see PrivacyVisitor::set_import_binding_access_level).
fn set_bindings_access_level(&mut self, module_id: LocalDefId) {
/// Update effective visibilities of bindings in the given module,
/// including their whole reexport chains.
fn set_bindings_effective_visibilities(&mut self, module_id: LocalDefId) {
assert!(self.r.module_map.contains_key(&&module_id.to_def_id()));
let module = self.r.get_module(module_id.to_def_id()).unwrap();
let resolutions = self.r.resolutions(module);
for (_, name_resolution) in resolutions.borrow().iter() {
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
// Set the given effective visibility level to `Level::Direct` and
// sets the rest of the `use` chain to `Level::Reexported` until
// we hit the actual exported item.
// FIXME: tag and is_public() condition should be removed, but assertions occur.
let tag = if binding.is_import() { AccessLevel::Exported } else { AccessLevel::Public };
let tag = if binding.is_import() { Level::Reexported } else { Level::Direct };
if binding.vis.is_public() {
let mut prev_parent_id = module_id;
let mut level = AccessLevel::Public;
let mut level = Level::Direct;
while let NameBindingKind::Import { binding: nested_binding, import, .. } =
binding.kind
{
@ -76,7 +75,7 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
update(additional_ids.1);
}
level = AccessLevel::Exported;
level = Level::Reexported;
prev_parent_id = self.r.local_def_id(import.id);
binding = nested_binding;
}
@ -94,7 +93,7 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
def_id: LocalDefId,
nominal_vis: Visibility,
parent_id: LocalDefId,
tag: AccessLevel,
tag: Level,
) {
let module_id = self
.r
@ -106,8 +105,8 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
{
return;
}
let mut access_levels = std::mem::take(&mut self.r.access_levels);
self.changed |= access_levels.update(
let mut effective_visibilities = std::mem::take(&mut self.r.effective_visibilities);
self.changed |= effective_visibilities.update(
def_id,
nominal_vis,
|| Visibility::Restricted(module_id),
@ -115,14 +114,14 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
tag,
&*self.r,
);
self.r.access_levels = access_levels;
self.r.effective_visibilities = effective_visibilities;
}
}
impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
impl<'r, 'ast> Visitor<'ast> for EffectiveVisibilitiesVisitor<'ast, 'r> {
fn visit_item(&mut self, item: &'ast ast::Item) {
let def_id = self.r.local_def_id(item.id);
// Set access level of nested items.
// Update effective visibilities of nested items.
// If it's a mod, also make the visitor walk all of its items
match item.kind {
// Resolved in rustc_privacy when types are available
@ -136,29 +135,29 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
// Foreign modules inherit level from parents.
ast::ItemKind::ForeignMod(..) => {
let parent_id = self.r.local_parent(def_id);
self.update(def_id, Visibility::Public, parent_id, AccessLevel::Public);
self.update(def_id, Visibility::Public, parent_id, Level::Direct);
}
// Only exported `macro_rules!` items are public, but they always are
ast::ItemKind::MacroDef(ref macro_def) if macro_def.macro_rules => {
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);
self.update(def_id, vis, parent_id, Level::Direct);
}
ast::ItemKind::Mod(..) => {
self.set_bindings_access_level(def_id);
self.set_bindings_effective_visibilities(def_id);
visit::walk_item(self, item);
}
ast::ItemKind::Enum(EnumDef { ref variants }, _) => {
self.set_bindings_access_level(def_id);
self.set_bindings_effective_visibilities(def_id);
for variant in variants {
let variant_def_id = self.r.local_def_id(variant.id);
for field in variant.data.fields() {
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);
self.update(field_def_id, vis, variant_def_id, Level::Direct);
}
}
}
@ -167,12 +166,12 @@ impl<'r, 'ast> Visitor<'ast> for AccessLevelsVisitor<'ast, 'r> {
for field in def.fields() {
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);
self.update(field_def_id, vis, def_id, Level::Direct);
}
}
ast::ItemKind::Trait(..) => {
self.set_bindings_access_level(def_id);
self.set_bindings_effective_visibilities(def_id);
}
ast::ItemKind::ExternCrate(..)

View File

@ -7,6 +7,7 @@
//! Type-relative name resolution (methods, fields, associated items) happens in `rustc_hir_analysis`.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(drain_filter)]
#![feature(if_let_guard)]
@ -40,7 +41,7 @@ use rustc_hir::TraitCandidate;
use rustc_index::vec::IndexVec;
use rustc_metadata::creader::{CStore, CrateLoader};
use rustc_middle::metadata::ModChild;
use rustc_middle::middle::privacy::AccessLevels;
use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::span_bug;
use rustc_middle::ty::{self, DefIdTree, MainDefinition, RegisteredTools};
use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs};
@ -63,15 +64,15 @@ use imports::{Import, ImportKind, ImportResolver, NameResolution};
use late::{HasGenericParams, PathSource, PatternSource};
use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
use crate::access_levels::AccessLevelsVisitor;
use crate::effective_visibilities::EffectiveVisibilitiesVisitor;
type Res = def::Res<NodeId>;
mod access_levels;
mod build_reduced_graph;
mod check_unused;
mod def_collector;
mod diagnostics;
mod effective_visibilities;
mod ident;
mod imports;
mod late;
@ -1030,7 +1031,7 @@ pub struct Resolver<'a> {
proc_macros: Vec<NodeId>,
confused_type_with_std_module: FxHashMap<Span, Span>,
access_levels: AccessLevels,
effective_visibilities: EffectiveVisibilities,
}
/// Nothing really interesting here; it just provides memory for the rest of the crate.
@ -1334,7 +1335,7 @@ impl<'a> Resolver<'a> {
trait_impls: Default::default(),
proc_macros: Default::default(),
confused_type_with_std_module: Default::default(),
access_levels: Default::default(),
effective_visibilities: Default::default(),
};
let root_parent_scope = ParentScope::module(graph_root, &resolver);
@ -1392,14 +1393,14 @@ impl<'a> Resolver<'a> {
let glob_map = self.glob_map;
let main_def = self.main_def;
let confused_type_with_std_module = self.confused_type_with_std_module;
let access_levels = self.access_levels;
let effective_visibilities = self.effective_visibilities;
let global_ctxt = ResolverGlobalCtxt {
cstore,
source_span,
expn_that_defined,
visibilities,
has_pub_restricted,
access_levels,
effective_visibilities,
extern_crate_map,
reexport_map,
glob_map,
@ -1457,7 +1458,7 @@ impl<'a> Resolver<'a> {
proc_macros,
confused_type_with_std_module: self.confused_type_with_std_module.clone(),
registered_tools: self.registered_tools.clone(),
access_levels: self.access_levels.clone(),
effective_visibilities: self.effective_visibilities.clone(),
};
let ast_lowering = ty::ResolverAstLowering {
legacy_const_generic_args: self.legacy_const_generic_args.clone(),
@ -1520,8 +1521,8 @@ impl<'a> Resolver<'a> {
pub fn resolve_crate(&mut self, krate: &Crate) {
self.session.time("resolve_crate", || {
self.session.time("finalize_imports", || ImportResolver { r: self }.finalize_imports());
self.session.time("resolve_access_levels", || {
AccessLevelsVisitor::compute_access_levels(self, krate)
self.session.time("compute_effective_visibilities", || {
EffectiveVisibilitiesVisitor::compute_effective_visibilities(self, krate)
});
self.session.time("finalize_macro_resolutions", || self.finalize_macro_resolutions());
self.session.time("late_resolve_crate", || self.late_resolve_crate(krate));

View File

@ -57,7 +57,7 @@ macro_rules! access_from {
($save_ctxt:expr, $id:expr) => {
Access {
public: $save_ctxt.tcx.visibility($id).is_public(),
reachable: $save_ctxt.access_levels.is_reachable($id),
reachable: $save_ctxt.effective_visibilities.is_reachable($id),
}
};
}

View File

@ -26,7 +26,7 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::Node;
use rustc_hir_pretty::{enum_def_to_string, fn_to_string, ty_to_string};
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::privacy::AccessLevels;
use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::ty::{self, print::with_no_trimmed_paths, DefIdTree, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_session::config::{CrateType, Input, OutputType};
@ -54,7 +54,7 @@ use rls_data::{
pub struct SaveContext<'tcx> {
tcx: TyCtxt<'tcx>,
maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
access_levels: &'tcx AccessLevels,
effective_visibilities: &'tcx EffectiveVisibilities,
span_utils: SpanUtils<'tcx>,
config: Config,
impl_counter: Cell<u32>,
@ -968,16 +968,16 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>(
info!("Dumping crate {}", cratename);
// Privacy checking must be done outside of type inference; use a
// fallback in case the access levels couldn't have been correctly computed.
let access_levels = match tcx.sess.compile_status() {
Ok(..) => tcx.privacy_access_levels(()),
Err(..) => tcx.arena.alloc(AccessLevels::default()),
// fallback in case effective visibilities couldn't have been correctly computed.
let effective_visibilities = match tcx.sess.compile_status() {
Ok(..) => tcx.effective_visibilities(()),
Err(..) => tcx.arena.alloc(EffectiveVisibilities::default()),
};
let save_ctxt = SaveContext {
tcx,
maybe_typeck_results: None,
access_levels: &access_levels,
effective_visibilities: &effective_visibilities,
span_utils: SpanUtils::new(&tcx.sess),
config: find_config(config),
impl_counter: Cell::new(0),

View File

@ -20,7 +20,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
trace!("get_blanket_impls({:?})", ty);
let mut impls = Vec::new();
for trait_def_id in cx.tcx.all_traits() {
if !cx.cache.access_levels.is_public(trait_def_id)
if !cx.cache.effective_visibilities.is_directly_public(trait_def_id)
|| cx.generated_synthetics.get(&(ty.0, trait_def_id)).is_some()
{
continue;

View File

@ -347,7 +347,7 @@ pub(crate) fn build_impl(
if !did.is_local() {
if let Some(traitref) = associated_trait {
let did = traitref.def_id;
if !cx.cache.access_levels.is_public(did) {
if !cx.cache.effective_visibilities.is_directly_public(did) {
return;
}
@ -376,7 +376,7 @@ pub(crate) fn build_impl(
// reachable in rustdoc generated documentation
if !did.is_local() {
if let Some(did) = for_.def_id(&cx.cache) {
if !cx.cache.access_levels.is_public(did) {
if !cx.cache.effective_visibilities.is_directly_public(did) {
return;
}

View File

@ -1421,7 +1421,7 @@ fn maybe_expand_private_type_alias<'tcx>(
let Res::Def(DefKind::TyAlias, def_id) = path.res else { return None };
// Substitute private type aliases
let def_id = def_id.as_local()?;
let alias = if !cx.cache.access_levels.is_exported(def_id.to_def_id()) {
let alias = if !cx.cache.effective_visibilities.is_exported(def_id.to_def_id()) {
&cx.tcx.hir().expect_item(def_id).kind
} else {
return None;

View File

@ -348,7 +348,7 @@ pub(crate) fn run_global_ctxt(
let auto_traits =
tcx.all_traits().filter(|&trait_def_id| tcx.trait_is_auto(trait_def_id)).collect();
let access_levels = tcx.privacy_access_levels(()).map_id(Into::into);
let effective_visibilities = tcx.effective_visibilities(()).map_id(Into::into);
let mut ctxt = DocContext {
tcx,
@ -361,7 +361,7 @@ pub(crate) fn run_global_ctxt(
impl_trait_bounds: Default::default(),
generated_synthetics: Default::default(),
auto_traits,
cache: Cache::new(access_levels, render_options.document_private),
cache: Cache::new(effective_visibilities, render_options.document_private),
inlined: FxHashSet::default(),
output_format,
render_options,

View File

@ -2,7 +2,7 @@ use std::mem;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::def_id::{CrateNum, DefId};
use rustc_middle::middle::privacy::AccessLevels;
use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::Symbol;
@ -77,8 +77,8 @@ pub(crate) struct Cache {
// Note that external items for which `doc(hidden)` applies to are shown as
// non-reachable while local items aren't. This is because we're reusing
// the access levels from the privacy check pass.
pub(crate) access_levels: AccessLevels<DefId>,
// the effective visibilities from the privacy check pass.
pub(crate) effective_visibilities: EffectiveVisibilities<DefId>,
/// The version of the crate being documented, if given from the `--crate-version` flag.
pub(crate) crate_version: Option<String>,
@ -132,8 +132,11 @@ struct CacheBuilder<'a, 'tcx> {
}
impl Cache {
pub(crate) fn new(access_levels: AccessLevels<DefId>, document_private: bool) -> Self {
Cache { access_levels, document_private, ..Cache::default() }
pub(crate) fn new(
effective_visibilities: EffectiveVisibilities<DefId>,
document_private: bool,
) -> Self {
Cache { effective_visibilities, document_private, ..Cache::default() }
}
/// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was
@ -381,7 +384,10 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
// paths map if there was already an entry present and we're
// not a public item.
if !self.cache.paths.contains_key(&item.item_id.expect_def_id())
|| self.cache.access_levels.is_public(item.item_id.expect_def_id())
|| self
.cache
.effective_visibilities
.is_directly_public(item.item_id.expect_def_id())
{
self.cache.paths.insert(
item.item_id.expect_def_id(),

View File

@ -659,7 +659,7 @@ pub(crate) fn href_with_root_path(
}
if !did.is_local()
&& !cache.access_levels.is_public(did)
&& !cache.effective_visibilities.is_directly_public(did)
&& !cache.document_private
&& !cache.primitive_locations.values().any(|&id| id == did)
{

View File

@ -56,7 +56,7 @@ impl crate::doctest::Tester for Tests {
}
pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool {
if !cx.cache.access_levels.is_public(item.item_id.expect_def_id())
if !cx.cache.effective_visibilities.is_directly_public(item.item_id.expect_def_id())
|| matches!(
*item.kind,
clean::StructFieldItem(_)
@ -130,7 +130,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
);
}
} else if tests.found_tests > 0
&& !cx.cache.access_levels.is_exported(item.item_id.expect_def_id())
&& !cx.cache.effective_visibilities.is_exported(item.item_id.expect_def_id())
{
cx.tcx.struct_span_lint_hir(
crate::lint::PRIVATE_DOC_TESTS,

View File

@ -1202,8 +1202,8 @@ impl LinkCollector<'_, '_> {
item.item_id.expect_def_id().as_local().map(|src_id| (src_id, dst_id))
})
{
if self.cx.tcx.privacy_access_levels(()).is_exported(src_id)
&& !self.cx.tcx.privacy_access_levels(()).is_exported(dst_id)
if self.cx.tcx.effective_visibilities(()).is_exported(src_id)
&& !self.cx.tcx.effective_visibilities(()).is_exported(dst_id)
{
privacy_error(self.cx, diag_info, path_str);
}

View File

@ -23,7 +23,7 @@ pub(crate) fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) ->
{
let mut stripper = Stripper {
retained: &mut retained,
access_levels: &cx.cache.access_levels,
effective_visibilities: &cx.cache.effective_visibilities,
update_retained: true,
is_json_output,
};

View File

@ -1,6 +1,6 @@
//! A collection of utility functions for the `strip_*` passes.
use rustc_hir::def_id::DefId;
use rustc_middle::middle::privacy::AccessLevels;
use rustc_middle::middle::privacy::EffectiveVisibilities;
use std::mem;
use crate::clean::{self, Item, ItemId, ItemIdSet};
@ -9,7 +9,7 @@ use crate::formats::cache::Cache;
pub(crate) struct Stripper<'a> {
pub(crate) retained: &'a mut ItemIdSet,
pub(crate) access_levels: &'a AccessLevels<DefId>,
pub(crate) effective_visibilities: &'a EffectiveVisibilities<DefId>,
pub(crate) update_retained: bool,
pub(crate) is_json_output: bool,
}
@ -20,13 +20,13 @@ pub(crate) struct Stripper<'a> {
#[inline]
fn is_item_reachable(
is_json_output: bool,
access_levels: &AccessLevels<DefId>,
effective_visibilities: &EffectiveVisibilities<DefId>,
item_id: ItemId,
) -> bool {
if is_json_output {
access_levels.is_reachable(item_id.expect_def_id())
effective_visibilities.is_reachable(item_id.expect_def_id())
} else {
access_levels.is_exported(item_id.expect_def_id())
effective_visibilities.is_exported(item_id.expect_def_id())
}
}
@ -64,7 +64,7 @@ impl<'a> DocFolder for Stripper<'a> {
| clean::ForeignTypeItem => {
let item_id = i.item_id;
if item_id.is_local()
&& !is_item_reachable(self.is_json_output, self.access_levels, item_id)
&& !is_item_reachable(self.is_json_output, self.effective_visibilities, item_id)
{
debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
return None;
@ -168,7 +168,7 @@ impl<'a> DocFolder for ImplStripper<'a> {
item_id.is_local()
&& !is_item_reachable(
self.is_json_output,
&self.cache.access_levels,
&self.cache.effective_visibilities,
item_id,
)
})

View File

@ -7,7 +7,7 @@ use rustc_hir::def::{DefKind, Res};
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::middle::privacy::Level;
use rustc_middle::ty::{TyCtxt, Visibility};
use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
use rustc_span::symbol::{kw, sym, Symbol};
@ -230,10 +230,10 @@ 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(
self.cx.cache.effective_visibilities.set_public_at_level(
did,
|| Visibility::Restricted(CRATE_DEF_ID),
AccessLevel::Public,
Level::Direct,
);
}
}
@ -246,7 +246,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
None => return false,
};
let is_private = !self.cx.cache.access_levels.is_public(res_did);
let is_private = !self.cx.cache.effective_visibilities.is_directly_public(res_did);
let is_hidden = inherits_doc_hidden(self.cx.tcx, res_hir_id);
// Only inline if requested or if the item would otherwise be stripped.

View File

@ -1,7 +1,7 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_ID};
use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
use rustc_middle::middle::privacy::{EffectiveVisibilities, Level};
use rustc_middle::ty::{TyCtxt, Visibility};
// FIXME: this may not be exhaustive, but is sufficient for rustdocs current uses
@ -10,10 +10,10 @@ use rustc_middle::ty::{TyCtxt, Visibility};
/// specific rustdoc annotations into account (i.e., `doc(hidden)`)
pub(crate) struct LibEmbargoVisitor<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
// Accessibility levels for reachable nodes
access_levels: &'a mut AccessLevels<DefId>,
// Previous accessibility level, None means unreachable
prev_level: Option<AccessLevel>,
// Effective visibilities for reachable nodes
effective_visibilities: &'a mut EffectiveVisibilities<DefId>,
// Previous level, None means unreachable
prev_level: Option<Level>,
// Keeps track of already visited modules, in case a module re-exports its parent
visited_mods: FxHashSet<DefId>,
}
@ -22,26 +22,26 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
pub(crate) fn new(cx: &'a mut crate::core::DocContext<'tcx>) -> LibEmbargoVisitor<'a, 'tcx> {
LibEmbargoVisitor {
tcx: cx.tcx,
access_levels: &mut cx.cache.access_levels,
prev_level: Some(AccessLevel::Public),
effective_visibilities: &mut cx.cache.effective_visibilities,
prev_level: Some(Level::Direct),
visited_mods: FxHashSet::default(),
}
}
pub(crate) fn visit_lib(&mut self, cnum: CrateNum) {
let did = cnum.as_def_id();
self.update(did, Some(AccessLevel::Public));
self.update(did, Some(Level::Direct));
self.visit_mod(did);
}
// Updates node level and returns the updated level
fn update(&mut self, did: DefId, level: Option<AccessLevel>) -> Option<AccessLevel> {
fn update(&mut self, did: DefId, level: Option<Level>) -> Option<Level> {
let is_hidden = self.tcx.is_doc_hidden(did);
let old_level = self.access_levels.get_access_level(did);
// Accessibility levels can only grow
let old_level = self.effective_visibilities.public_at_level(did);
// Visibility levels can only grow
if level > old_level && !is_hidden {
self.access_levels.set_access_level(
self.effective_visibilities.set_public_at_level(
did,
|| Visibility::Restricted(CRATE_DEF_ID),
level.unwrap(),

View File

@ -1,75 +0,0 @@
#![feature(rustc_attrs)]
#[rustc_effective_visibility]
mod outer { //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
#[rustc_effective_visibility]
pub mod inner1 { //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility]
extern "C" {} //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility]
pub trait PubTrait { //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility]
const A: i32; //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility]
type B; //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
}
#[rustc_effective_visibility]
struct PrivStruct; //~ ERROR not in the table
#[rustc_effective_visibility]
pub union PubUnion { //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility]
a: u8, //~ ERROR not in the table
#[rustc_effective_visibility]
pub b: u8, //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
}
#[rustc_effective_visibility]
pub enum Enum { //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility]
A( //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility]
PubUnion, //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
),
}
}
#[rustc_effective_visibility]
macro_rules! none_macro { //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
() => {};
}
#[macro_export]
#[rustc_effective_visibility]
macro_rules! public_macro { //~ ERROR Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
() => {};
}
#[rustc_effective_visibility]
pub struct ReachableStruct { //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub, ReachableFromImplTrait: pub
#[rustc_effective_visibility]
pub a: u8, //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub, ReachableFromImplTrait: pub
}
}
#[rustc_effective_visibility]
pub use outer::inner1; //~ ERROR Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
pub fn foo() -> outer::ReachableStruct { outer::ReachableStruct {a: 0} }
mod half_public_import {
#[rustc_effective_visibility]
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(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, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
fn main() {}

View File

@ -1,134 +0,0 @@
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(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:6:5
|
LL | pub mod inner1 {
| ^^^^^^^^^^^^^^
error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:9:9
|
LL | extern "C" {}
| ^^^^^^^^^^^^^
error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:12:9
|
LL | pub trait PubTrait {
| ^^^^^^^^^^^^^^^^^^
error: not in the table
--> $DIR/access_levels.rs:20:9
|
LL | struct PrivStruct;
| ^^^^^^^^^^^^^^^^^
error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:23:9
|
LL | pub union PubUnion {
| ^^^^^^^^^^^^^^^^^^
error: not in the table
--> $DIR/access_levels.rs:25:13
|
LL | a: u8,
| ^^^^^
error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:27:13
|
LL | pub b: u8,
| ^^^^^^^^^
error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:31:9
|
LL | pub enum Enum {
| ^^^^^^^^^^^^^
error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:33:13
|
LL | A(
| ^
error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:35:17
|
LL | PubUnion,
| ^^^^^^^^
error: Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
--> $DIR/access_levels.rs:41:5
|
LL | macro_rules! none_macro {
| ^^^^^^^^^^^^^^^^^^^^^^^
error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:47:5
|
LL | macro_rules! public_macro {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: Public: pub(crate), Exported: pub(crate), Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:52:5
|
LL | pub struct ReachableStruct {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Public: pub(crate), Exported: pub(crate), Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:54:9
|
LL | pub a: u8,
| ^^^^^^^^^
error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:59:9
|
LL | pub use outer::inner1;
| ^^^^^^^^^^^^^
error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:65:5
|
LL | pub type HalfPublicImport = u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
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;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:72:9
|
LL | pub use half_public_import::HalfPublicImport;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:72:9
|
LL | pub use half_public_import::HalfPublicImport;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
--> $DIR/access_levels.rs:14:13
|
LL | const A: i32;
| ^^^^^^^^^^^^
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

View File

@ -0,0 +1,75 @@
#![feature(rustc_attrs)]
#[rustc_effective_visibility]
mod outer { //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
#[rustc_effective_visibility]
pub mod inner1 { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
#[rustc_effective_visibility]
extern "C" {} //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
#[rustc_effective_visibility]
pub trait PubTrait { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
#[rustc_effective_visibility]
const A: i32; //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
#[rustc_effective_visibility]
type B; //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
}
#[rustc_effective_visibility]
struct PrivStruct; //~ ERROR not in the table
#[rustc_effective_visibility]
pub union PubUnion { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
#[rustc_effective_visibility]
a: u8, //~ ERROR not in the table
#[rustc_effective_visibility]
pub b: u8, //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
}
#[rustc_effective_visibility]
pub enum Enum { //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
#[rustc_effective_visibility]
A( //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
#[rustc_effective_visibility]
PubUnion, //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
),
}
}
#[rustc_effective_visibility]
macro_rules! none_macro { //~ Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
() => {};
}
#[macro_export]
#[rustc_effective_visibility]
macro_rules! public_macro { //~ Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
() => {};
}
#[rustc_effective_visibility]
pub struct ReachableStruct { //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub
#[rustc_effective_visibility]
pub a: u8, //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub
}
}
#[rustc_effective_visibility]
pub use outer::inner1; //~ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
pub fn foo() -> outer::ReachableStruct { outer::ReachableStruct {a: 0} }
mod half_public_import {
#[rustc_effective_visibility]
pub type HalfPublicImport = u8; //~ ERROR Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
#[rustc_effective_visibility]
#[allow(non_upper_case_globals)]
pub(crate) const HalfPublicImport: u8 = 0; //~ ERROR Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
}
#[rustc_effective_visibility]
pub use half_public_import::HalfPublicImport; //~ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
//~^ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
fn main() {}

View File

@ -0,0 +1,134 @@
error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
--> $DIR/effective_visibilities.rs:4:1
|
LL | mod outer {
| ^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:6:5
|
LL | pub mod inner1 {
| ^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:9:9
|
LL | extern "C" {}
| ^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:12:9
|
LL | pub trait PubTrait {
| ^^^^^^^^^^^^^^^^^^
error: not in the table
--> $DIR/effective_visibilities.rs:20:9
|
LL | struct PrivStruct;
| ^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:23:9
|
LL | pub union PubUnion {
| ^^^^^^^^^^^^^^^^^^
error: not in the table
--> $DIR/effective_visibilities.rs:25:13
|
LL | a: u8,
| ^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:27:13
|
LL | pub b: u8,
| ^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:31:9
|
LL | pub enum Enum {
| ^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:33:13
|
LL | A(
| ^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:35:17
|
LL | PubUnion,
| ^^^^^^^^
error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
--> $DIR/effective_visibilities.rs:41:5
|
LL | macro_rules! none_macro {
| ^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:47:5
|
LL | macro_rules! public_macro {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:52:5
|
LL | pub struct ReachableStruct {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:54:9
|
LL | pub a: u8,
| ^^^^^^^^^
error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:59:9
|
LL | pub use outer::inner1;
| ^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:65:5
|
LL | pub type HalfPublicImport = u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
--> $DIR/effective_visibilities.rs:68:5
|
LL | pub(crate) const HalfPublicImport: u8 = 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:72:9
|
LL | pub use half_public_import::HalfPublicImport;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:72:9
|
LL | pub use half_public_import::HalfPublicImport;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:14:13
|
LL | const A: i32;
| ^^^^^^^^^^^^
error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
--> $DIR/effective_visibilities.rs:16:13
|
LL | type B;
| ^^^^^^
error: aborting due to 22 previous errors

View File

@ -345,7 +345,7 @@ fn lint_for_missing_headers<'tcx>(
body_id: Option<hir::BodyId>,
panic_span: Option<Span>,
) {
if !cx.access_levels.is_exported(def_id) {
if !cx.effective_visibilities.is_exported(def_id) {
return; // Private functions do not require doc comments
}

View File

@ -296,7 +296,7 @@ impl LateLintPass<'_> for EnumVariantNames {
}
}
if let ItemKind::Enum(ref def, _) = item.kind {
if !(self.avoid_breaking_exported_api && cx.access_levels.is_exported(item.def_id.def_id)) {
if !(self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(item.def_id.def_id)) {
check_variant(cx, self.threshold, def, item_name, item.span);
}
}

View File

@ -73,7 +73,7 @@ impl LateLintPass<'_> for ExhaustiveItems {
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
if_chain! {
if let ItemKind::Enum(..) | ItemKind::Struct(..) = item.kind;
if cx.access_levels.is_exported(item.def_id.def_id);
if cx.effective_visibilities.is_exported(item.def_id.def_id);
let attrs = cx.tcx.hir().attrs(item.hir_id());
if !attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
then {

View File

@ -24,7 +24,7 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
let attrs = cx.tcx.hir().attrs(item.hir_id());
let attr = cx.tcx.get_attr(item.def_id.to_def_id(), sym::must_use);
if let hir::ItemKind::Fn(ref sig, _generics, ref body_id) = item.kind {
let is_public = cx.access_levels.is_exported(item.def_id.def_id);
let is_public = cx.effective_visibilities.is_exported(item.def_id.def_id);
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
if let Some(attr) = attr {
check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr);
@ -44,7 +44,7 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
if let hir::ImplItemKind::Fn(ref sig, ref body_id) = item.kind {
let is_public = cx.access_levels.is_exported(item.def_id.def_id);
let is_public = cx.effective_visibilities.is_exported(item.def_id.def_id);
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
let attrs = cx.tcx.hir().attrs(item.hir_id());
let attr = cx.tcx.get_attr(item.def_id.to_def_id(), sym::must_use);
@ -67,7 +67,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
if let hir::TraitItemKind::Fn(ref sig, ref eid) = item.kind {
let is_public = cx.access_levels.is_exported(item.def_id.def_id);
let is_public = cx.effective_visibilities.is_exported(item.def_id.def_id);
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
let attrs = cx.tcx.hir().attrs(item.hir_id());
@ -137,7 +137,7 @@ fn check_must_use_candidate<'tcx>(
|| mutates_static(cx, body)
|| in_external_macro(cx.sess(), item_span)
|| returns_unit(decl)
|| !cx.access_levels.is_exported(item_id)
|| !cx.effective_visibilities.is_exported(item_id)
|| is_must_use_ty(cx, return_ty(cx, cx.tcx.hir().local_def_id_to_hir_id(item_id)))
{
return;

View File

@ -42,7 +42,7 @@ fn check_raw_ptr<'tcx>(
body: &'tcx hir::Body<'tcx>,
def_id: LocalDefId,
) {
if unsafety == hir::Unsafety::Normal && cx.access_levels.is_exported(def_id) {
if unsafety == hir::Unsafety::Normal && cx.effective_visibilities.is_exported(def_id) {
let raw_ptrs = iter_input_pats(decl, body)
.filter_map(|arg| raw_ptr_arg(cx, arg))
.collect::<HirIdSet>();

View File

@ -36,7 +36,7 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, l
if let hir::ItemKind::Fn(ref sig, _generics, _) = item.kind
&& let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.def_id.def_id, item.span)
{
if cx.access_levels.is_exported(item.def_id.def_id) {
if cx.effective_visibilities.is_exported(item.def_id.def_id) {
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
check_result_unit_err(cx, err_ty, fn_header_span);
}
@ -50,7 +50,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::ImplItem
&& let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.def_id.def_id, item.span)
&& trait_ref_of_method(cx, item.def_id.def_id).is_none()
{
if cx.access_levels.is_exported(item.def_id.def_id) {
if cx.effective_visibilities.is_exported(item.def_id.def_id) {
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
check_result_unit_err(cx, err_ty, fn_header_span);
}
@ -62,7 +62,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::TraitIt
if let hir::TraitItemKind::Fn(ref sig, _) = item.kind {
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
if let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.def_id.def_id, item.span) {
if cx.access_levels.is_exported(item.def_id.def_id) {
if cx.effective_visibilities.is_exported(item.def_id.def_id) {
check_result_unit_err(cx, err_ty, fn_header_span);
}
check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold);

View File

@ -111,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
}
}
if !cx.access_levels.is_exported(item.def_id.def_id) {
if !cx.effective_visibilities.is_exported(item.def_id.def_id) {
return;
}

View File

@ -134,7 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
if item.ident.name == sym::len;
if let ImplItemKind::Fn(sig, _) = &item.kind;
if sig.decl.implicit_self.has_implicit_self();
if cx.access_levels.is_exported(item.def_id.def_id);
if cx.effective_visibilities.is_exported(item.def_id.def_id);
if matches!(sig.decl.output, FnRetTy::Return(_));
if let Some(imp) = get_parent_as_impl(cx.tcx, item.hir_id());
if imp.of_trait.is_none();
@ -210,7 +210,7 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items
}
}
if cx.access_levels.is_exported(visited_trait.def_id.def_id)
if cx.effective_visibilities.is_exported(visited_trait.def_id.def_id)
&& trait_items.iter().any(|i| is_named_self(cx, i, sym::len))
{
let mut current_and_super_traits = DefIdSet::default();
@ -331,7 +331,7 @@ fn check_for_is_empty<'tcx>(
None,
None,
),
Some(is_empty) if !cx.access_levels.is_exported(is_empty.def_id.expect_local()) => (
Some(is_empty) if !cx.effective_visibilities.is_exported(is_empty.def_id.expect_local()) => (
format!(
"{item_kind} `{}` has a public `len` method, but a private `is_empty` method",
item_name.as_str(),

View File

@ -3258,7 +3258,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
let method_sig = cx.tcx.erase_late_bound_regions(method_sig);
let first_arg_ty_opt = method_sig.inputs().iter().next().copied();
// if this impl block implements a trait, lint in trait definition instead
if !implements_trait && cx.access_levels.is_exported(impl_item.def_id.def_id) {
if !implements_trait && cx.effective_visibilities.is_exported(impl_item.def_id.def_id) {
// check missing trait implementations
for method_config in &TRAIT_METHODS {
if name == method_config.method_name
@ -3292,7 +3292,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
if sig.decl.implicit_self.has_implicit_self()
&& !(self.avoid_breaking_exported_api
&& cx.access_levels.is_exported(impl_item.def_id.def_id))
&& cx.effective_visibilities.is_exported(impl_item.def_id.def_id))
&& let Some(first_arg) = iter_input_pats(sig.decl, cx.tcx.hir().body(id)).next()
&& let Some(first_arg_ty) = first_arg_ty_opt
{

View File

@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
return;
}
if !cx.access_levels.is_exported(it.def_id.def_id) {
if !cx.effective_visibilities.is_exported(it.def_id.def_id) {
return;
}
match it.kind {
@ -142,7 +142,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
}
// If the item being implemented is not exported, then we don't need #[inline]
if !cx.access_levels.is_exported(impl_item.def_id.def_id) {
if !cx.effective_visibilities.is_exported(impl_item.def_id.def_id) {
return;
}
@ -159,7 +159,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
};
if let Some(trait_def_id) = trait_def_id {
if trait_def_id.is_local() && !cx.access_levels.is_exported(impl_item.def_id.def_id) {
if trait_def_id.is_local() && !cx.effective_visibilities.is_exported(impl_item.def_id.def_id) {
// If a trait is being implemented for an item, and the
// trait is not exported, we don't need #[inline]
return;

View File

@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
if_chain! {
if sig.decl.inputs.is_empty();
if name == sym::new;
if cx.access_levels.is_reachable(impl_item.def_id.def_id);
if cx.effective_visibilities.is_reachable(impl_item.def_id.def_id);
let self_def_id = cx.tcx.hir().get_parent_item(id);
let self_ty = cx.tcx.type_of(self_def_id);
if self_ty == return_ty(cx, id);

View File

@ -139,7 +139,7 @@ impl<'tcx> PassByRefOrValue {
}
fn check_poly_fn(&mut self, cx: &LateContext<'tcx>, def_id: LocalDefId, decl: &FnDecl<'_>, span: Option<Span>) {
if self.avoid_breaking_exported_api && cx.access_levels.is_exported(def_id) {
if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {
return;
}

View File

@ -47,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
if_chain! {
if cx.tcx.visibility(item.def_id.def_id) == ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id());
if !cx.access_levels.is_exported(item.def_id.def_id) && self.is_exported.last() == Some(&false);
if !cx.effective_visibilities.is_exported(item.def_id.def_id) && self.is_exported.last() == Some(&false);
if is_not_macro_export(item);
then {
let span = item.span.with_hi(item.ident.span.hi());
@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
}
if let ItemKind::Mod { .. } = item.kind {
self.is_exported.push(cx.access_levels.is_exported(item.def_id.def_id));
self.is_exported.push(cx.effective_visibilities.is_exported(item.def_id.def_id));
}
}

View File

@ -74,7 +74,7 @@ fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, spa
if !in_external_macro(cx.sess(), span);
if decl.implicit_self.has_implicit_self();
// We only show this warning for public exported methods.
if cx.access_levels.is_exported(fn_def);
if cx.effective_visibilities.is_exported(fn_def);
// We don't want to emit this lint if the `#[must_use]` attribute is already there.
if !cx.tcx.hir().attrs(hir_id).iter().any(|attr| attr.has_name(sym::must_use));
if cx.tcx.visibility(fn_def.to_def_id()).is_public();

View File

@ -319,7 +319,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
false
};
let is_exported = cx.access_levels.is_exported(cx.tcx.hir().local_def_id(id));
let is_exported = cx.effective_visibilities.is_exported(cx.tcx.hir().local_def_id(id));
self.check_fn_decl(
cx,
@ -333,7 +333,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
}
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
let is_exported = cx.access_levels.is_exported(item.def_id.def_id);
let is_exported = cx.effective_visibilities.is_exported(item.def_id.def_id);
match item.kind {
ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _) => self.check_ty(
@ -379,7 +379,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
}
fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) {
let is_exported = cx.access_levels.is_exported(cx.tcx.hir().local_def_id(field.hir_id));
let is_exported = cx.effective_visibilities.is_exported(cx.tcx.hir().local_def_id(field.hir_id));
self.check_ty(
cx,
@ -392,7 +392,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
}
fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &TraitItem<'_>) {
let is_exported = cx.access_levels.is_exported(item.def_id.def_id);
let is_exported = cx.effective_visibilities.is_exported(item.def_id.def_id);
let context = CheckTyContext {
is_exported,

View File

@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
match fn_kind {
FnKind::ItemFn(..) | FnKind::Method(..) => {
let def_id = cx.tcx.hir().local_def_id(hir_id);
if self.avoid_breaking_exported_api && cx.access_levels.is_exported(def_id) {
if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {
return;
}
},

View File

@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedSelf {
if let ItemKind::Impl(Impl { of_trait: None, .. }) = parent_item.kind;
if assoc_item.fn_has_self_parameter;
if let ImplItemKind::Fn(.., body_id) = &impl_item.kind;
if !cx.access_levels.is_exported(impl_item.def_id.def_id) || !self.avoid_breaking_exported_api;
if !cx.effective_visibilities.is_exported(impl_item.def_id.def_id) || !self.avoid_breaking_exported_api;
let body = cx.tcx.hir().body(*body_id);
if let [self_param, ..] = body.params;
if !is_local_used(cx, body, self_param.pat.hir_id);

View File

@ -105,7 +105,7 @@ impl LateLintPass<'_> for UpperCaseAcronyms {
fn check_item(&mut self, cx: &LateContext<'_>, it: &Item<'_>) {
// do not lint public items or in macros
if in_external_macro(cx.sess(), it.span)
|| (self.avoid_breaking_exported_api && cx.access_levels.is_exported(it.def_id.def_id))
|| (self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(it.def_id.def_id))
{
return;
}