mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
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:
parent
629a414d7b
commit
34eb73c72d
@ -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!(
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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>,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)>,
|
||||
|
@ -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;
|
||||
|
@ -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()))
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
@ -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(),
|
||||
};
|
||||
|
@ -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(..)
|
@ -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));
|
||||
|
@ -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),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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(),
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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,
|
||||
)
|
||||
})
|
||||
|
@ -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.
|
||||
|
@ -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(),
|
||||
|
@ -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() {}
|
@ -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
|
||||
|
75
src/test/ui/privacy/effective_visibilities.rs
Normal file
75
src/test/ui/privacy/effective_visibilities.rs
Normal 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() {}
|
134
src/test/ui/privacy/effective_visibilities.stderr
Normal file
134
src/test/ui/privacy/effective_visibilities.stderr
Normal 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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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>();
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
},
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user