add TestReachabilityVisitor
This commit is contained in:
parent
10804672c2
commit
0111fb00da
7 changed files with 246 additions and 2 deletions
|
@ -75,6 +75,14 @@ pub struct InPublicInterface<'a> {
|
|||
pub vis_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(privacy::report_access_level)]
|
||||
pub struct ReportAccessLevel {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub descr: String,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(privacy::from_private_dep_in_public_interface)]
|
||||
pub struct FromPrivateDependencyInPublicInterface<'a> {
|
||||
|
|
|
@ -30,7 +30,7 @@ use rustc_middle::ty::{self, Const, DefIdTree, GenericParamDefKind};
|
|||
use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::hygiene::Transparency;
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::Span;
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
@ -39,7 +39,8 @@ use std::{cmp, fmt, mem};
|
|||
|
||||
use errors::{
|
||||
FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface,
|
||||
InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, UnnamedItemIsPrivate,
|
||||
InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, ReportAccessLevel,
|
||||
UnnamedItemIsPrivate,
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -904,6 +905,60 @@ impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx>
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Visitor, used for AccessLevels table checking
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
pub struct TestReachabilityVisitor<'tcx, 'a> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
access_levels: &'a AccessLevels,
|
||||
}
|
||||
|
||||
impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
|
||||
fn access_level_diagnostic(&mut self, def_id: LocalDefId) {
|
||||
if self.tcx.has_attr(def_id.to_def_id(), sym::rustc_access_level) {
|
||||
let access_level = format!("{:?}", self.access_levels.map.get(&def_id));
|
||||
let span = self.tcx.def_span(def_id.to_def_id());
|
||||
self.tcx.sess.emit_err(ReportAccessLevel { span, descr: access_level });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
for field in variant.data.fields() {
|
||||
let def_id = self.tcx.hir().local_def_id(field.hir_id);
|
||||
self.access_level_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);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem<'tcx>) {
|
||||
self.access_level_diagnostic(item.def_id);
|
||||
}
|
||||
fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem<'tcx>) {
|
||||
self.access_level_diagnostic(item.def_id);
|
||||
}
|
||||
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) {
|
||||
self.access_level_diagnostic(item.def_id);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
/// Name privacy visitor, checks privacy and reports violations.
|
||||
/// Most of name privacy checks are performed during the main resolution phase,
|
||||
|
@ -2042,6 +2097,9 @@ fn privacy_access_levels(tcx: TyCtxt<'_>, (): ()) -> &AccessLevels {
|
|||
}
|
||||
}
|
||||
|
||||
let mut check_visitor = TestReachabilityVisitor { tcx, access_levels: &visitor.access_levels };
|
||||
tcx.hir().visit_all_item_likes_in_crate(&mut check_visitor);
|
||||
|
||||
tcx.arena.alloc(visitor.access_levels)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue