@@ -155,10 +155,6 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
155
155
}
156
156
}
157
157
158
- fn cheap_private_vis ( & self , parent_id : ParentId < ' _ > ) -> Option < Visibility > {
159
- matches ! ( parent_id, ParentId :: Def ( _) ) . then_some ( self . current_private_vis )
160
- }
161
-
162
158
fn effective_vis_or_private ( & mut self , parent_id : ParentId < ' a > ) -> EffectiveVisibility {
163
159
// Private nodes are only added to the table for caching, they could be added or removed at
164
160
// any moment without consequences, so we don't set `changed` to true when adding them.
@@ -172,29 +168,53 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
172
168
}
173
169
}
174
170
171
+ /// All effective visibilities for a node are larger or equal than private visibility
172
+ /// for that node (see `check_invariants` in middle/privacy.rs).
173
+ /// So if either parent or nominal visibility is the same as private visibility, then
174
+ /// `min(parent_vis, nominal_vis) <= private_vis`, and the update logic is guaranteed
175
+ /// to not update anything and we can skip it.
176
+ ///
177
+ /// We are checking this condition only if the correct value of private visibility is
178
+ /// cheaply available, otherwise it does't make sense performance-wise.
179
+ ///
180
+ /// `None` is returned if the update can be skipped,
181
+ /// and cheap private visibility is returned otherwise.
182
+ fn may_update (
183
+ & self ,
184
+ nominal_vis : Visibility ,
185
+ parent_id : ParentId < ' _ > ,
186
+ ) -> Option < Option < Visibility > > {
187
+ match parent_id {
188
+ ParentId :: Def ( def_id) => ( nominal_vis != self . current_private_vis
189
+ && self . r . visibilities [ & def_id] != self . current_private_vis )
190
+ . then_some ( Some ( self . current_private_vis ) ) ,
191
+ ParentId :: Import ( _) => Some ( None ) ,
192
+ }
193
+ }
194
+
175
195
fn update_import ( & mut self , binding : ImportId < ' a > , parent_id : ParentId < ' a > ) {
176
196
let nominal_vis = binding. vis . expect_local ( ) ;
177
- let private_vis = self . cheap_private_vis ( parent_id) ;
197
+ let Some ( cheap_private_vis ) = self . may_update ( nominal_vis , parent_id) else { return } ;
178
198
let inherited_eff_vis = self . effective_vis_or_private ( parent_id) ;
179
199
let tcx = self . r . tcx ;
180
200
self . changed |= self . import_effective_visibilities . update (
181
201
binding,
182
202
nominal_vis,
183
- || private_vis . unwrap_or_else ( || self . r . private_vis_import ( binding) ) ,
203
+ || cheap_private_vis . unwrap_or_else ( || self . r . private_vis_import ( binding) ) ,
184
204
inherited_eff_vis,
185
205
parent_id. level ( ) ,
186
206
tcx,
187
207
) ;
188
208
}
189
209
190
210
fn update_def ( & mut self , def_id : LocalDefId , nominal_vis : Visibility , parent_id : ParentId < ' a > ) {
191
- let private_vis = self . cheap_private_vis ( parent_id) ;
211
+ let Some ( cheap_private_vis ) = self . may_update ( nominal_vis , parent_id) else { return } ;
192
212
let inherited_eff_vis = self . effective_vis_or_private ( parent_id) ;
193
213
let tcx = self . r . tcx ;
194
214
self . changed |= self . def_effective_visibilities . update (
195
215
def_id,
196
216
nominal_vis,
197
- || private_vis . unwrap_or_else ( || self . r . private_vis_def ( def_id) ) ,
217
+ || cheap_private_vis . unwrap_or_else ( || self . r . private_vis_def ( def_id) ) ,
198
218
inherited_eff_vis,
199
219
parent_id. level ( ) ,
200
220
tcx,
0 commit comments