diff options
| author | Bryanskiy <ivakin.kir@gmail.com> | 2022-08-14 17:05:17 +0300 |
|---|---|---|
| committer | Bryanskiy <ivakin.kir@gmail.com> | 2022-08-31 14:23:07 +0300 |
| commit | 0111fb00dac90d67f8d770ca2a25923cfd24e25d (patch) | |
| tree | 1b3435bb88e8a50236e49ddfa1a349eaf8604494 /compiler/rustc_privacy/src | |
| parent | 10804672c221882cfd1c94809ad09846a35fe49d (diff) | |
| download | rust-0111fb00dac90d67f8d770ca2a25923cfd24e25d.tar.gz rust-0111fb00dac90d67f8d770ca2a25923cfd24e25d.zip | |
add TestReachabilityVisitor
Diffstat (limited to 'compiler/rustc_privacy/src')
| -rw-r--r-- | compiler/rustc_privacy/src/errors.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_privacy/src/lib.rs | 62 |
2 files changed, 68 insertions, 2 deletions
diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index 1e423ddb710..63f83f8965e 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -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> { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 5d562f18a81..075a1411f02 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -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) } |
