@@ -24,13 +24,13 @@ use rustc_hir::def::{DefKind, Res};
24
24
use rustc_hir:: def_id:: { DefId , LocalDefId , LocalModDefId , CRATE_DEF_ID } ;
25
25
use rustc_hir:: intravisit:: { self , Visitor } ;
26
26
use rustc_hir:: { AssocItemKind , ForeignItemKind , ItemId , PatKind } ;
27
- use rustc_middle:: bug;
28
27
use rustc_middle:: hir:: nested_filter;
29
28
use rustc_middle:: middle:: privacy:: { EffectiveVisibilities , EffectiveVisibility , Level } ;
30
29
use rustc_middle:: query:: Providers ;
31
30
use rustc_middle:: ty:: GenericArgs ;
32
31
use rustc_middle:: ty:: { self , Const , GenericParamDefKind } ;
33
32
use rustc_middle:: ty:: { TraitRef , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable , TypeVisitor } ;
33
+ use rustc_middle:: { bug, span_bug} ;
34
34
use rustc_session:: lint;
35
35
use rustc_span:: hygiene:: Transparency ;
36
36
use rustc_span:: symbol:: { kw, sym, Ident } ;
@@ -1064,29 +1064,22 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
1064
1064
1065
1065
struct TypePrivacyVisitor < ' tcx > {
1066
1066
tcx : TyCtxt < ' tcx > ,
1067
+ module_def_id : LocalModDefId ,
1067
1068
maybe_typeck_results : Option < & ' tcx ty:: TypeckResults < ' tcx > > ,
1068
- current_item : LocalDefId ,
1069
1069
span : Span ,
1070
1070
}
1071
1071
1072
1072
impl < ' tcx > TypePrivacyVisitor < ' tcx > {
1073
- /// Gets the type-checking results for the current body.
1074
- /// As this will ICE if called outside bodies, only call when working with
1075
- /// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies).
1076
- #[ track_caller]
1077
- fn typeck_results ( & self ) -> & ' tcx ty:: TypeckResults < ' tcx > {
1078
- self . maybe_typeck_results
1079
- . expect ( "`TypePrivacyVisitor::typeck_results` called outside of body" )
1080
- }
1081
-
1082
1073
fn item_is_accessible ( & self , did : DefId ) -> bool {
1083
- self . tcx . visibility ( did) . is_accessible_from ( self . current_item , self . tcx )
1074
+ self . tcx . visibility ( did) . is_accessible_from ( self . module_def_id , self . tcx )
1084
1075
}
1085
1076
1086
1077
// Take node-id of an expression or pattern and check its type for privacy.
1087
1078
fn check_expr_pat_type ( & mut self , id : hir:: HirId , span : Span ) -> bool {
1088
1079
self . span = span;
1089
- let typeck_results = self . typeck_results ( ) ;
1080
+ let typeck_results = self
1081
+ . maybe_typeck_results
1082
+ . unwrap_or_else ( || span_bug ! ( span, "`hir::Expr` or `hir::Pat` outside of a body" ) ) ;
1090
1083
let result: ControlFlow < ( ) > = try {
1091
1084
self . visit ( typeck_results. node_type ( id) ) ?;
1092
1085
self . visit ( typeck_results. node_args ( id) ) ?;
@@ -1107,35 +1100,13 @@ impl<'tcx> TypePrivacyVisitor<'tcx> {
1107
1100
}
1108
1101
1109
1102
impl < ' tcx > Visitor < ' tcx > for TypePrivacyVisitor < ' tcx > {
1110
- type NestedFilter = nested_filter:: All ;
1111
-
1112
- /// We want to visit items in the context of their containing
1113
- /// module and so forth, so supply a crate for doing a deep walk.
1114
- fn nested_visit_map ( & mut self ) -> Self :: Map {
1115
- self . tcx . hir ( )
1116
- }
1117
-
1118
- fn visit_mod ( & mut self , _m : & ' tcx hir:: Mod < ' tcx > , _s : Span , _n : hir:: HirId ) {
1119
- // Don't visit nested modules, since we run a separate visitor walk
1120
- // for each module in `effective_visibilities`
1121
- }
1122
-
1123
- fn visit_nested_body ( & mut self , body : hir:: BodyId ) {
1103
+ fn visit_nested_body ( & mut self , body_id : hir:: BodyId ) {
1124
1104
let old_maybe_typeck_results =
1125
- self . maybe_typeck_results . replace ( self . tcx . typeck_body ( body) ) ;
1126
- let body = self . tcx . hir ( ) . body ( body) ;
1127
- self . visit_body ( body) ;
1105
+ self . maybe_typeck_results . replace ( self . tcx . typeck_body ( body_id) ) ;
1106
+ self . visit_body ( self . tcx . hir ( ) . body ( body_id) ) ;
1128
1107
self . maybe_typeck_results = old_maybe_typeck_results;
1129
1108
}
1130
1109
1131
- fn visit_generic_arg ( & mut self , generic_arg : & ' tcx hir:: GenericArg < ' tcx > ) {
1132
- match generic_arg {
1133
- hir:: GenericArg :: Type ( t) => self . visit_ty ( t) ,
1134
- hir:: GenericArg :: Infer ( inf) => self . visit_infer ( inf) ,
1135
- hir:: GenericArg :: Lifetime ( _) | hir:: GenericArg :: Const ( _) => { }
1136
- }
1137
- }
1138
-
1139
1110
fn visit_ty ( & mut self , hir_ty : & ' tcx hir:: Ty < ' tcx > ) {
1140
1111
self . span = hir_ty. span ;
1141
1112
if let Some ( typeck_results) = self . maybe_typeck_results {
@@ -1163,19 +1134,19 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
1163
1134
return ;
1164
1135
}
1165
1136
} else {
1166
- // We don't do anything for const infers here.
1137
+ // FIXME: check types of const infers here.
1167
1138
}
1168
1139
} else {
1169
- bug ! ( "visit_infer without typeck_results ") ;
1140
+ span_bug ! ( self . span , "`hir::InferArg` outside of a body ") ;
1170
1141
}
1171
1142
intravisit:: walk_inf ( self , inf) ;
1172
1143
}
1173
1144
1174
1145
fn visit_trait_ref ( & mut self , trait_ref : & ' tcx hir:: TraitRef < ' tcx > ) {
1175
1146
self . span = trait_ref. path . span ;
1176
- if self . maybe_typeck_results . is_none ( ) {
1177
- // Avoid calling `hir_trait_to_predicates` in bodies, it will ICE .
1178
- // The traits' privacy in bodies is already checked as a part of trait object types.
1147
+ if self . maybe_typeck_results . is_some ( ) {
1148
+ // Privacy of traits in bodies is checked as a part of trait object types .
1149
+ } else {
1179
1150
let bounds = rustc_hir_analysis:: hir_trait_to_predicates (
1180
1151
self . tcx ,
1181
1152
trait_ref,
@@ -1223,7 +1194,10 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
1223
1194
hir:: ExprKind :: MethodCall ( segment, ..) => {
1224
1195
// Method calls have to be checked specially.
1225
1196
self . span = segment. ident . span ;
1226
- if let Some ( def_id) = self . typeck_results ( ) . type_dependent_def_id ( expr. hir_id ) {
1197
+ let typeck_results = self
1198
+ . maybe_typeck_results
1199
+ . unwrap_or_else ( || span_bug ! ( self . span, "`hir::Expr` outside of a body" ) ) ;
1200
+ if let Some ( def_id) = typeck_results. type_dependent_def_id ( expr. hir_id ) {
1227
1201
if self . visit ( self . tcx . type_of ( def_id) . instantiate_identity ( ) ) . is_break ( ) {
1228
1202
return ;
1229
1203
}
@@ -1251,9 +1225,13 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
1251
1225
Res :: Def ( kind, def_id) => Some ( ( kind, def_id) ) ,
1252
1226
_ => None ,
1253
1227
} ,
1254
- hir:: QPath :: TypeRelative ( ..) | hir:: QPath :: LangItem ( ..) => self
1255
- . maybe_typeck_results
1256
- . and_then ( |typeck_results| typeck_results. type_dependent_def ( id) ) ,
1228
+ hir:: QPath :: TypeRelative ( ..) | hir:: QPath :: LangItem ( ..) => {
1229
+ match self . maybe_typeck_results {
1230
+ Some ( typeck_results) => typeck_results. type_dependent_def ( id) ,
1231
+ // FIXME: Check type-relative associated types in signatures.
1232
+ None => None ,
1233
+ }
1234
+ }
1257
1235
} ;
1258
1236
let def = def. filter ( |( kind, _) | {
1259
1237
matches ! (
@@ -1307,15 +1285,6 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
1307
1285
1308
1286
intravisit:: walk_local ( self , local) ;
1309
1287
}
1310
-
1311
- // Check types in item interfaces.
1312
- fn visit_item ( & mut self , item : & ' tcx hir:: Item < ' tcx > ) {
1313
- let orig_current_item = mem:: replace ( & mut self . current_item , item. owner_id . def_id ) ;
1314
- let old_maybe_typeck_results = self . maybe_typeck_results . take ( ) ;
1315
- intravisit:: walk_item ( self , item) ;
1316
- self . maybe_typeck_results = old_maybe_typeck_results;
1317
- self . current_item = orig_current_item;
1318
- }
1319
1288
}
1320
1289
1321
1290
impl < ' tcx > DefIdVisitor < ' tcx > for TypePrivacyVisitor < ' tcx > {
@@ -1785,13 +1754,8 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
1785
1754
1786
1755
// Check privacy of explicitly written types and traits as well as
1787
1756
// inferred types of expressions and patterns.
1788
- let mut visitor = TypePrivacyVisitor {
1789
- tcx,
1790
- maybe_typeck_results : None ,
1791
- current_item : module_def_id. to_local_def_id ( ) ,
1792
- span,
1793
- } ;
1794
- intravisit:: walk_mod ( & mut visitor, module, hir_id) ;
1757
+ let mut visitor = TypePrivacyVisitor { tcx, module_def_id, maybe_typeck_results : None , span } ;
1758
+ tcx. hir ( ) . visit_item_likes_in_module ( module_def_id, & mut visitor) ;
1795
1759
}
1796
1760
1797
1761
fn effective_visibilities ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) -> & EffectiveVisibilities {
0 commit comments