@@ -30,7 +30,7 @@ use rustc_middle::ty::{self, Const, DefIdTree, GenericParamDefKind};
30
30
use rustc_middle:: ty:: { TraitRef , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable , TypeVisitor } ;
31
31
use rustc_session:: lint;
32
32
use rustc_span:: hygiene:: Transparency ;
33
- use rustc_span:: symbol:: { kw, Ident } ;
33
+ use rustc_span:: symbol:: { kw, sym , Ident } ;
34
34
use rustc_span:: Span ;
35
35
36
36
use std:: marker:: PhantomData ;
@@ -39,7 +39,8 @@ use std::{cmp, fmt, mem};
39
39
40
40
use errors:: {
41
41
FieldIsPrivate , FieldIsPrivateLabel , FromPrivateDependencyInPublicInterface , InPublicInterface ,
42
- InPublicInterfaceTraits , ItemIsPrivate , PrivateInPublicLint , UnnamedItemIsPrivate ,
42
+ InPublicInterfaceTraits , ItemIsPrivate , PrivateInPublicLint , ReportAccessLevel ,
43
+ UnnamedItemIsPrivate ,
43
44
} ;
44
45
45
46
////////////////////////////////////////////////////////////////////////////////
@@ -904,6 +905,60 @@ impl<'tcx> DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx>
904
905
}
905
906
}
906
907
908
+ ////////////////////////////////////////////////////////////////////////////////
909
+ /// Visitor, used for AccessLevels table checking
910
+ ////////////////////////////////////////////////////////////////////////////////
911
+ pub struct TestReachabilityVisitor < ' tcx > {
912
+ tcx : TyCtxt < ' tcx > ,
913
+ access_levels : & ' tcx AccessLevels ,
914
+ }
915
+
916
+ impl < ' tcx > TestReachabilityVisitor < ' tcx > {
917
+ fn access_level_diagnostic ( & mut self , def_id : LocalDefId ) {
918
+ if self . tcx . has_attr ( def_id. to_def_id ( ) , sym:: rustc_access_level) {
919
+ let access_level = format ! ( "{:?}" , self . access_levels. map. get( & def_id) ) ;
920
+ let span = self . tcx . def_span ( def_id. to_def_id ( ) ) ;
921
+ self . tcx . sess . emit_err ( ReportAccessLevel { span, descr : access_level } ) ;
922
+ }
923
+ }
924
+ }
925
+
926
+ impl < ' tcx > Visitor < ' tcx > for TestReachabilityVisitor < ' tcx > {
927
+ fn visit_item ( & mut self , item : & ' tcx hir:: Item < ' tcx > ) {
928
+ self . access_level_diagnostic ( item. def_id ) ;
929
+
930
+ match item. kind {
931
+ hir:: ItemKind :: Enum ( ref def, _) => {
932
+ for variant in def. variants . iter ( ) {
933
+ let variant_id = self . tcx . hir ( ) . local_def_id ( variant. id ) ;
934
+ self . access_level_diagnostic ( variant_id) ;
935
+ for field in variant. data . fields ( ) {
936
+ let def_id = self . tcx . hir ( ) . local_def_id ( field. hir_id ) ;
937
+ self . access_level_diagnostic ( def_id) ;
938
+ }
939
+ }
940
+ }
941
+ hir:: ItemKind :: Struct ( ref def, _) | hir:: ItemKind :: Union ( ref def, _) => {
942
+ for field in def. fields ( ) {
943
+ let def_id = self . tcx . hir ( ) . local_def_id ( field. hir_id ) ;
944
+ self . access_level_diagnostic ( def_id) ;
945
+ }
946
+ }
947
+ _ => { }
948
+ }
949
+ }
950
+
951
+ fn visit_trait_item ( & mut self , item : & ' tcx hir:: TraitItem < ' tcx > ) {
952
+ self . access_level_diagnostic ( item. def_id ) ;
953
+ }
954
+ fn visit_impl_item ( & mut self , item : & ' tcx hir:: ImplItem < ' tcx > ) {
955
+ self . access_level_diagnostic ( item. def_id ) ;
956
+ }
957
+ fn visit_foreign_item ( & mut self , item : & ' tcx hir:: ForeignItem < ' tcx > ) {
958
+ self . access_level_diagnostic ( item. def_id ) ;
959
+ }
960
+ }
961
+
907
962
//////////////////////////////////////////////////////////////////////////////////////
908
963
/// Name privacy visitor, checks privacy and reports violations.
909
964
/// Most of name privacy checks are performed during the main resolution phase,
@@ -2043,6 +2098,10 @@ fn privacy_access_levels(tcx: TyCtxt<'_>, (): ()) -> &AccessLevels {
2043
2098
}
2044
2099
}
2045
2100
2101
+ let mut check_visitor =
2102
+ TestReachabilityVisitor { tcx, access_levels : & tcx. resolutions ( ( ) ) . access_levels } ;
2103
+ tcx. hir ( ) . visit_all_item_likes_in_crate ( & mut check_visitor) ;
2104
+
2046
2105
tcx. arena . alloc ( visitor. access_levels )
2047
2106
}
2048
2107
0 commit comments