@@ -10,6 +10,7 @@ use rustc_hir::def_id::CRATE_DEF_ID;
10
10
use rustc_middle:: middle:: privacy:: { EffectiveVisibilities , EffectiveVisibility } ;
11
11
use rustc_middle:: middle:: privacy:: { IntoDefIdTree , Level } ;
12
12
use rustc_middle:: ty:: { DefIdTree , Visibility } ;
13
+ use std:: mem;
13
14
14
15
type ImportId < ' a > = Interned < ' a , NameBinding < ' a > > ;
15
16
@@ -35,6 +36,8 @@ pub struct EffectiveVisibilitiesVisitor<'r, 'a> {
35
36
/// keys in `Resolver::effective_visibilities` are not enough for that, because multiple
36
37
/// bindings can correspond to a single def id in imports. So we keep a separate table.
37
38
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 ,
38
41
changed : bool ,
39
42
}
40
43
@@ -80,10 +83,12 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
80
83
r,
81
84
def_effective_visibilities : Default :: default ( ) ,
82
85
import_effective_visibilities : Default :: default ( ) ,
86
+ current_private_vis : Visibility :: Public ,
83
87
changed : false ,
84
88
} ;
85
89
86
90
visitor. update ( CRATE_DEF_ID , CRATE_DEF_ID ) ;
91
+ visitor. current_private_vis = Visibility :: Restricted ( CRATE_DEF_ID ) ;
87
92
visitor. set_bindings_effective_visibilities ( CRATE_DEF_ID ) ;
88
93
89
94
while visitor. changed {
@@ -155,6 +160,10 @@ impl<'r, 'a> EffectiveVisibilitiesVisitor<'r, 'a> {
155
160
}
156
161
}
157
162
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
+
158
167
fn effective_vis_or_private ( & mut self , parent_id : ParentId < ' a > ) -> EffectiveVisibility {
159
168
// Private nodes are only added to the table for caching, they could be added or removed at
160
169
// 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> {
170
179
171
180
fn update_import ( & mut self , binding : ImportId < ' a > , parent_id : ParentId < ' a > ) {
172
181
let nominal_vis = binding. vis . expect_local ( ) ;
182
+ let private_vis = self . cheap_private_vis ( parent_id) ;
173
183
let inherited_eff_vis = self . effective_vis_or_private ( parent_id) ;
174
184
self . changed |= self . import_effective_visibilities . update (
175
185
binding,
176
186
nominal_vis,
177
- |r| ( r. private_vis_import ( binding) , r) ,
187
+ |r| ( private_vis . unwrap_or_else ( || r. private_vis_import ( binding) ) , r) ,
178
188
inherited_eff_vis,
179
189
parent_id. level ( ) ,
180
190
& mut * self . r ,
181
191
) ;
182
192
}
183
193
184
194
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) ;
185
196
let inherited_eff_vis = self . effective_vis_or_private ( parent_id) ;
186
197
self . changed |= self . def_effective_visibilities . update (
187
198
def_id,
188
199
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) ,
190
201
inherited_eff_vis,
191
202
parent_id. level ( ) ,
192
203
& mut * self . r ,
@@ -213,8 +224,11 @@ impl<'r, 'ast> Visitor<'ast> for EffectiveVisibilitiesVisitor<'ast, 'r> {
213
224
) ,
214
225
215
226
ast:: ItemKind :: Mod ( ..) => {
227
+ let prev_private_vis =
228
+ mem:: replace ( & mut self . current_private_vis , Visibility :: Restricted ( def_id) ) ;
216
229
self . set_bindings_effective_visibilities ( def_id) ;
217
230
visit:: walk_item ( self , item) ;
231
+ self . current_private_vis = prev_private_vis;
218
232
}
219
233
220
234
ast:: ItemKind :: Enum ( EnumDef { ref variants } , _) => {
0 commit comments