@@ -10,6 +10,7 @@ use rustc_hir::def_id::CRATE_DEF_ID;
1010use rustc_middle:: middle:: privacy:: { EffectiveVisibilities , EffectiveVisibility } ;
1111use rustc_middle:: middle:: privacy:: { IntoDefIdTree , Level } ;
1212use rustc_middle:: ty:: { DefIdTree , Visibility } ;
13+ use std:: mem;
1314
1415type ImportId < ' a > = Interned < ' a , NameBinding < ' a > > ;
1516
@@ -35,6 +36,8 @@ pub struct EffectiveVisibilitiesVisitor<'r, 'a> {
3536 /// keys in `Resolver::effective_visibilities` are not enough for that, because multiple
3637 /// bindings can correspond to a single def id in imports. So we keep a separate table.
3738 import_effective_visibilities : EffectiveVisibilities < ImportId < ' a > > ,
39+ // It's possible to recalculate this at any point, but it's relatively expensive.
40+ current_private_vis : Visibility ,
3841 changed : bool ,
3942}
4043
@@ -80,10 +83,12 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
8083 r,
8184 def_effective_visibilities : Default :: default ( ) ,
8285 import_effective_visibilities : Default :: default ( ) ,
86+ current_private_vis : Visibility :: Public ,
8387 changed : false ,
8488 } ;
8589
8690 visitor. update ( CRATE_DEF_ID , CRATE_DEF_ID ) ;
91+ visitor. current_private_vis = Visibility :: Restricted ( CRATE_DEF_ID ) ;
8792 visitor. set_bindings_effective_visibilities ( CRATE_DEF_ID ) ;
8893
8994 while visitor. changed {
@@ -155,6 +160,10 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
155160 }
156161 }
157162
163+ fn cheap_private_vis ( & self , parent_id : ParentId < ' _ > ) -> Option < Visibility > {
164+ matches ! ( parent_id, ParentId :: Def ( _) ) . then_some ( self . current_private_vis )
165+ }
166+
158167 fn effective_vis_or_private ( & mut self , parent_id : ParentId < ' a > ) -> EffectiveVisibility {
159168 // Private nodes are only added to the table for caching, they could be added or removed at
160169 // any moment without consequences, so we don't set `changed` to true when adding them.
@@ -170,23 +179,25 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
170179
171180 fn update_import ( & mut self , binding : ImportId < ' a > , parent_id : ParentId < ' a > ) {
172181 let nominal_vis = binding. vis . expect_local ( ) ;
182+ let private_vis = self . cheap_private_vis ( parent_id) ;
173183 let inherited_eff_vis = self . effective_vis_or_private ( parent_id) ;
174184 self . changed |= self . import_effective_visibilities . update (
175185 binding,
176186 nominal_vis,
177- |r| ( r. private_vis_import ( binding) , r) ,
187+ |r| ( private_vis . unwrap_or_else ( || r. private_vis_import ( binding) ) , r) ,
178188 inherited_eff_vis,
179189 parent_id. level ( ) ,
180190 & mut * self . r ,
181191 ) ;
182192 }
183193
184194 fn update_def ( & mut self , def_id : LocalDefId , nominal_vis : Visibility , parent_id : ParentId < ' a > ) {
195+ let private_vis = self . cheap_private_vis ( parent_id) ;
185196 let inherited_eff_vis = self . effective_vis_or_private ( parent_id) ;
186197 self . changed |= self . def_effective_visibilities . update (
187198 def_id,
188199 nominal_vis,
189- |r| ( r. private_vis_def ( def_id) , r) ,
200+ |r| ( private_vis . unwrap_or_else ( || r. private_vis_def ( def_id) ) , r) ,
190201 inherited_eff_vis,
191202 parent_id. level ( ) ,
192203 & mut * self . r ,
@@ -213,8 +224,11 @@ impl<'r, 'ast> Visitor<'ast> for EffectiveVisibilitiesVisitor<'ast, 'r> {
213224 ) ,
214225
215226 ast:: ItemKind :: Mod ( ..) => {
227+ let prev_private_vis =
228+ mem:: replace ( & mut self . current_private_vis , Visibility :: Restricted ( def_id) ) ;
216229 self . set_bindings_effective_visibilities ( def_id) ;
217230 visit:: walk_item ( self , item) ;
231+ self . current_private_vis = prev_private_vis;
218232 }
219233
220234 ast:: ItemKind :: Enum ( EnumDef { ref variants } , _) => {
0 commit comments