@@ -24,13 +24,13 @@ use rustc_hir::def::{DefKind, Res};
2424use rustc_hir:: def_id:: { DefId , LocalDefId , LocalModDefId , CRATE_DEF_ID } ;
2525use rustc_hir:: intravisit:: { self , Visitor } ;
2626use rustc_hir:: { AssocItemKind , ForeignItemKind , ItemId , PatKind } ;
27- use rustc_middle:: bug;
2827use rustc_middle:: hir:: nested_filter;
2928use rustc_middle:: middle:: privacy:: { EffectiveVisibilities , EffectiveVisibility , Level } ;
3029use rustc_middle:: query:: Providers ;
3130use rustc_middle:: ty:: GenericArgs ;
3231use rustc_middle:: ty:: { self , Const , GenericParamDefKind } ;
3332use rustc_middle:: ty:: { TraitRef , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable , TypeVisitor } ;
33+ use rustc_middle:: { bug, span_bug} ;
3434use rustc_session:: lint;
3535use rustc_span:: hygiene:: Transparency ;
3636use rustc_span:: symbol:: { kw, sym, Ident } ;
@@ -1064,29 +1064,22 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
10641064
10651065struct TypePrivacyVisitor < ' tcx > {
10661066 tcx : TyCtxt < ' tcx > ,
1067+ module_def_id : LocalModDefId ,
10671068 maybe_typeck_results : Option < & ' tcx ty:: TypeckResults < ' tcx > > ,
1068- current_item : LocalDefId ,
10691069 span : Span ,
10701070}
10711071
10721072impl < ' 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-
10821073 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 )
10841075 }
10851076
10861077 // Take node-id of an expression or pattern and check its type for privacy.
10871078 fn check_expr_pat_type ( & mut self , id : hir:: HirId , span : Span ) -> bool {
10881079 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" ) ) ;
10901083 let result: ControlFlow < ( ) > = try {
10911084 self . visit ( typeck_results. node_type ( id) ) ?;
10921085 self . visit ( typeck_results. node_args ( id) ) ?;
@@ -1107,35 +1100,13 @@ impl<'tcx> TypePrivacyVisitor<'tcx> {
11071100}
11081101
11091102impl < ' 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 ) {
11241104 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) ) ;
11281107 self . maybe_typeck_results = old_maybe_typeck_results;
11291108 }
11301109
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-
11391110 fn visit_ty ( & mut self , hir_ty : & ' tcx hir:: Ty < ' tcx > ) {
11401111 self . span = hir_ty. span ;
11411112 if let Some ( typeck_results) = self . maybe_typeck_results {
@@ -1163,19 +1134,19 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
11631134 return ;
11641135 }
11651136 } else {
1166- // We don't do anything for const infers here.
1137+ // FIXME: check types of const infers here.
11671138 }
11681139 } else {
1169- bug ! ( "visit_infer without typeck_results ") ;
1140+ span_bug ! ( self . span , "`hir::InferArg` outside of a body ") ;
11701141 }
11711142 intravisit:: walk_inf ( self , inf) ;
11721143 }
11731144
11741145 fn visit_trait_ref ( & mut self , trait_ref : & ' tcx hir:: TraitRef < ' tcx > ) {
11751146 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 {
11791150 let bounds = rustc_hir_analysis:: hir_trait_to_predicates (
11801151 self . tcx ,
11811152 trait_ref,
@@ -1223,7 +1194,10 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
12231194 hir:: ExprKind :: MethodCall ( segment, ..) => {
12241195 // Method calls have to be checked specially.
12251196 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 ) {
12271201 if self . visit ( self . tcx . type_of ( def_id) . instantiate_identity ( ) ) . is_break ( ) {
12281202 return ;
12291203 }
@@ -1251,9 +1225,13 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
12511225 Res :: Def ( kind, def_id) => Some ( ( kind, def_id) ) ,
12521226 _ => None ,
12531227 } ,
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+ }
12571235 } ;
12581236 let def = def. filter ( |( kind, _) | {
12591237 matches ! (
@@ -1307,15 +1285,6 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
13071285
13081286 intravisit:: walk_local ( self , local) ;
13091287 }
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- }
13191288}
13201289
13211290impl < ' tcx > DefIdVisitor < ' tcx > for TypePrivacyVisitor < ' tcx > {
@@ -1785,13 +1754,8 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
17851754
17861755 // Check privacy of explicitly written types and traits as well as
17871756 // 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) ;
17951759}
17961760
17971761fn effective_visibilities ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) -> & EffectiveVisibilities {
0 commit comments