@@ -69,21 +69,7 @@ impl EffectiveVisibility {
6969 self . get ( tag) . is_public ( )
7070 }
7171
72- fn update ( & mut self , vis : Visibility , tag : AccessLevel , tree : impl DefIdTree ) -> bool {
73- let mut changed = false ;
74- for level in AccessLevel :: all_levels ( ) {
75- if level <= tag {
76- let current_effective_vis = self . get_mut ( level) ;
77- if * current_effective_vis != vis && vis. is_at_least ( * current_effective_vis, tree) {
78- changed = true ;
79- * current_effective_vis = vis;
80- }
81- }
82- }
83- changed
84- }
85-
86- fn from_vis ( vis : Visibility ) -> EffectiveVisibility {
72+ pub fn from_vis ( vis : Visibility ) -> EffectiveVisibility {
8773 EffectiveVisibility {
8874 public : vis,
8975 exported : vis,
@@ -173,33 +159,49 @@ impl<Id: Hash + Eq + Copy + Into<DefId>> AccessLevels<Id> {
173159 parent_id : Id ,
174160 tag : AccessLevel ,
175161 tree : impl DefIdTree ,
176- ) -> Result < bool , ( ) > {
162+ ) -> bool {
177163 let mut changed = false ;
178- let mut current_effective_vis = self
179- . get_effective_vis ( id)
180- . copied ( )
181- . unwrap_or_else ( || EffectiveVisibility :: from_vis ( default_vis ( ) ) ) ;
164+ let mut current_effective_vis = self . get_effective_vis ( id) . copied ( ) . unwrap_or_else ( || {
165+ if id. into ( ) . is_crate_root ( ) {
166+ EffectiveVisibility :: from_vis ( Visibility :: Public )
167+ } else {
168+ EffectiveVisibility :: from_vis ( default_vis ( ) )
169+ }
170+ } ) ;
182171 if let Some ( inherited_effective_vis) = self . get_effective_vis ( parent_id) {
172+ let mut inherited_effective_vis_at_prev_level = * inherited_effective_vis. get ( tag) ;
173+ let mut calculated_effective_vis = inherited_effective_vis_at_prev_level;
183174 for level in AccessLevel :: all_levels ( ) {
184175 if tag >= level {
185176 let inherited_effective_vis_at_level = * inherited_effective_vis. get ( level) ;
186- let calculated_effective_vis =
187- if nominal_vis. is_at_least ( inherited_effective_vis_at_level, tree) {
188- inherited_effective_vis_at_level
189- } else {
190- nominal_vis
191- } ;
192- changed |= current_effective_vis. update ( calculated_effective_vis, level, tree) ;
177+ let current_effective_vis_at_level = current_effective_vis. get_mut ( level) ;
178+ // effective visibility for id shouldn't be recalculated if
179+ // inherited from parent_id effective visibility isn't changed at next level
180+ if !( inherited_effective_vis_at_prev_level == inherited_effective_vis_at_level
181+ && tag != level)
182+ {
183+ calculated_effective_vis =
184+ if nominal_vis. is_at_least ( inherited_effective_vis_at_level, tree) {
185+ inherited_effective_vis_at_level
186+ } else {
187+ nominal_vis
188+ } ;
189+ }
190+ // effective visibility can't be decreased at next update call for the
191+ // same id
192+ if * current_effective_vis_at_level != calculated_effective_vis
193+ && calculated_effective_vis
194+ . is_at_least ( * current_effective_vis_at_level, tree)
195+ {
196+ changed = true ;
197+ * current_effective_vis_at_level = calculated_effective_vis;
198+ }
199+ inherited_effective_vis_at_prev_level = inherited_effective_vis_at_level;
193200 }
194201 }
195- } else {
196- if !id. into ( ) . is_crate_root ( ) {
197- return Err ( ( ) ) ;
198- }
199- changed |= current_effective_vis. update ( Visibility :: Public , AccessLevel :: Public , tree) ;
200202 }
201203 self . map . insert ( id, current_effective_vis) ;
202- Ok ( changed)
204+ changed
203205 }
204206}
205207
0 commit comments