@@ -38,20 +38,18 @@ pub(crate) struct EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
3838}
3939
4040impl Resolver < ' _ , ' _ > {
41- fn nearest_normal_mod ( & self , def_id : LocalDefId ) -> LocalDefId {
42- self . get_nearest_non_block_module ( def_id. to_def_id ( ) ) . nearest_parent_mod ( ) . expect_local ( )
43- }
44-
45- fn private_vis_import ( & self , decl : Decl < ' _ > ) -> Visibility {
46- let DeclKind :: Import { import, .. } = decl. kind else { unreachable ! ( ) } ;
41+ fn private_vis_decl ( & self , decl : Decl < ' _ > ) -> Visibility {
4742 Visibility :: Restricted (
48- import . def_id ( ) . map ( |id| self . nearest_normal_mod ( id ) ) . unwrap_or ( CRATE_DEF_ID ) ,
43+ decl . parent_module . map_or ( CRATE_DEF_ID , |m| m . nearest_parent_mod ( ) . expect_local ( ) ) ,
4944 )
5045 }
5146
5247 fn private_vis_def ( & self , def_id : LocalDefId ) -> Visibility {
53- // For mod items `nearest_normal_mod` returns its argument, but we actually need its parent.
54- let normal_mod_id = self . nearest_normal_mod ( def_id) ;
48+ // For mod items `normal_mod_id` will be equal to `def_id`, but we actually need its parent.
49+ let normal_mod_id = self
50+ . get_nearest_non_block_module ( def_id. to_def_id ( ) )
51+ . nearest_parent_mod ( )
52+ . expect_local ( ) ;
5553 if normal_mod_id == def_id {
5654 Visibility :: Restricted ( self . tcx . local_parent ( def_id) )
5755 } else {
@@ -117,15 +115,23 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
117115 // Set the given effective visibility level to `Level::Direct` and
118116 // sets the rest of the `use` chain to `Level::Reexported` until
119117 // we hit the actual exported item.
118+ let orig_private_vis = self . current_private_vis ;
120119 let mut parent_id = ParentId :: Def ( module_id) ;
121120 while let DeclKind :: Import { source_decl, .. } = decl. kind {
121+ if matches ! ( parent_id, ParentId :: Import ( _) ) {
122+ self . current_private_vis = self . r . private_vis_decl ( decl) ;
123+ }
122124 self . update_import ( decl, parent_id) ;
123125 parent_id = ParentId :: Import ( decl) ;
124126 decl = source_decl;
125127 }
126128 if let Some ( def_id) = decl. res ( ) . opt_def_id ( ) . and_then ( |id| id. as_local ( ) ) {
129+ if matches ! ( parent_id, ParentId :: Import ( _) ) {
130+ self . current_private_vis = self . r . private_vis_decl ( decl) ;
131+ }
127132 self . update_def ( def_id, decl. vis ( ) . expect_local ( ) , parent_id) ;
128133 }
134+ self . current_private_vis = orig_private_vis;
129135 }
130136 }
131137
@@ -138,7 +144,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
138144 . effective_vis_or_private ( def_id, || self . r . private_vis_def ( def_id) ) ,
139145 ParentId :: Import ( binding) => self
140146 . import_effective_visibilities
141- . effective_vis_or_private ( binding, || self . r . private_vis_import ( binding) ) ,
147+ . effective_vis_or_private ( binding, || self . r . private_vis_decl ( binding) ) ,
142148 }
143149 }
144150
@@ -147,34 +153,25 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
147153 /// So if either parent or nominal visibility is the same as private visibility, then
148154 /// `min(parent_vis, nominal_vis) <= private_vis`, and the update logic is guaranteed
149155 /// to not update anything and we can skip it.
150- ///
151- /// We are checking this condition only if the correct value of private visibility is
152- /// cheaply available, otherwise it doesn't make sense performance-wise.
153- ///
154- /// `None` is returned if the update can be skipped,
155- /// and cheap private visibility is returned otherwise.
156- fn may_update (
157- & self ,
158- nominal_vis : Visibility ,
159- parent_id : ParentId < ' _ > ,
160- ) -> Option < Option < Visibility > > {
161- match parent_id {
162- ParentId :: Def ( def_id) => ( nominal_vis != self . current_private_vis
163- && self . r . tcx . local_visibility ( def_id) != self . current_private_vis )
164- . then_some ( Some ( self . current_private_vis ) ) ,
165- ParentId :: Import ( _) => Some ( None ) ,
166- }
156+ fn may_update ( & self , nominal_vis : Visibility , parent_id : ParentId < ' _ > ) -> bool {
157+ nominal_vis != self . current_private_vis
158+ && match parent_id {
159+ ParentId :: Def ( def_id) => self . r . tcx . local_visibility ( def_id) ,
160+ ParentId :: Import ( decl) => decl. vis ( ) . expect_local ( ) ,
161+ } != self . current_private_vis
167162 }
168163
169164 fn update_import ( & mut self , decl : Decl < ' ra > , parent_id : ParentId < ' ra > ) {
170165 let nominal_vis = decl. vis ( ) . expect_local ( ) ;
171- let Some ( cheap_private_vis) = self . may_update ( nominal_vis, parent_id) else { return } ;
166+ if !self . may_update ( nominal_vis, parent_id) {
167+ return ;
168+ } ;
172169 let inherited_eff_vis = self . effective_vis_or_private ( parent_id) ;
173170 let tcx = self . r . tcx ;
174171 self . changed |= self . import_effective_visibilities . update (
175172 decl,
176173 Some ( nominal_vis) ,
177- || cheap_private_vis . unwrap_or_else ( || self . r . private_vis_import ( decl ) ) ,
174+ self . current_private_vis ,
178175 inherited_eff_vis,
179176 parent_id. level ( ) ,
180177 tcx,
@@ -191,13 +188,15 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
191188 nominal_vis : Visibility ,
192189 parent_id : ParentId < ' ra > ,
193190 ) {
194- let Some ( cheap_private_vis) = self . may_update ( nominal_vis, parent_id) else { return } ;
191+ if !self . may_update ( nominal_vis, parent_id) {
192+ return ;
193+ } ;
195194 let inherited_eff_vis = self . effective_vis_or_private ( parent_id) ;
196195 let tcx = self . r . tcx ;
197196 self . changed |= self . def_effective_visibilities . update (
198197 def_id,
199198 Some ( nominal_vis) ,
200- || cheap_private_vis . unwrap_or_else ( || self . r . private_vis_def ( def_id ) ) ,
199+ self . current_private_vis ,
201200 inherited_eff_vis,
202201 parent_id. level ( ) ,
203202 tcx,
0 commit comments