@@ -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,14 +115,19 @@ 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 priv_vis = |this : & Self , parent_id, decl| match parent_id {
119+ ParentId :: Def ( _) => this. current_private_vis ,
120+ ParentId :: Import ( _) => this. r . private_vis_decl ( decl) ,
121+ } ;
120122 let mut parent_id = ParentId :: Def ( module_id) ;
121123 while let DeclKind :: Import { source_decl, .. } = decl. kind {
122- self . update_import ( decl, parent_id) ;
124+ self . update_import ( decl, parent_id, priv_vis ( self , parent_id , decl ) ) ;
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 ( ) ) {
127- self . update_def ( def_id, decl. vis ( ) . expect_local ( ) , parent_id) ;
129+ let priv_vis = priv_vis ( self , parent_id, decl) ;
130+ self . update_def ( def_id, decl. vis ( ) . expect_local ( ) , parent_id, priv_vis) ;
128131 }
129132 }
130133 }
@@ -138,50 +141,46 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
138141 . effective_vis_or_private ( def_id, || self . r . private_vis_def ( def_id) ) ,
139142 ParentId :: Import ( binding) => self
140143 . import_effective_visibilities
141- . effective_vis_or_private ( binding, || self . r . private_vis_import ( binding) ) ,
144+ . effective_vis_or_private ( binding, || self . r . private_vis_decl ( binding) ) ,
142145 }
143146 }
144147
145148 /// All effective visibilities for a node are larger or equal than private visibility
146149 /// for that node (see `check_invariants` in middle/privacy.rs).
147150 /// So if either parent or nominal visibility is the same as private visibility, then
148- /// `min(parent_vis, nominal_vis) <= private_vis `, and the update logic is guaranteed
151+ /// `min(parent_vis, nominal_vis) <= priv_vis `, and the update logic is guaranteed
149152 /// 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.
156153 fn may_update (
157154 & self ,
158155 nominal_vis : Visibility ,
159156 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- }
157+ priv_vis : Visibility ,
158+ ) -> bool {
159+ nominal_vis != priv_vis
160+ && match parent_id {
161+ ParentId :: Def ( def_id ) => self . r . tcx . local_visibility ( def_id ) ,
162+ ParentId :: Import ( decl ) => decl . vis ( ) . expect_local ( ) ,
163+ } != priv_vis
167164 }
168165
169- fn update_import ( & mut self , decl : Decl < ' ra > , parent_id : ParentId < ' ra > ) {
166+ fn update_import ( & mut self , decl : Decl < ' ra > , parent_id : ParentId < ' ra > , priv_vis : Visibility ) {
170167 let nominal_vis = decl. vis ( ) . expect_local ( ) ;
171- let Some ( cheap_private_vis) = self . may_update ( nominal_vis, parent_id) else { return } ;
168+ if !self . may_update ( nominal_vis, parent_id, priv_vis) {
169+ return ;
170+ } ;
172171 let inherited_eff_vis = self . effective_vis_or_private ( parent_id) ;
173172 let tcx = self . r . tcx ;
174173 self . changed |= self . import_effective_visibilities . update (
175174 decl,
176175 Some ( nominal_vis) ,
177- || cheap_private_vis . unwrap_or_else ( || self . r . private_vis_import ( decl ) ) ,
176+ priv_vis ,
178177 inherited_eff_vis,
179178 parent_id. level ( ) ,
180179 tcx,
181180 ) ;
182181 if let Some ( max_vis_decl) = decl. ambiguity_vis_max . get ( ) {
183182 // Avoid the most visible import in an ambiguous glob set being reported as unused.
184- self . update_import ( max_vis_decl, parent_id) ;
183+ self . update_import ( max_vis_decl, parent_id, priv_vis ) ;
185184 }
186185 }
187186
@@ -190,22 +189,26 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
190189 def_id : LocalDefId ,
191190 nominal_vis : Visibility ,
192191 parent_id : ParentId < ' ra > ,
192+ priv_vis : Visibility ,
193193 ) {
194- let Some ( cheap_private_vis) = self . may_update ( nominal_vis, parent_id) else { return } ;
194+ if !self . may_update ( nominal_vis, parent_id, priv_vis) {
195+ return ;
196+ } ;
195197 let inherited_eff_vis = self . effective_vis_or_private ( parent_id) ;
196198 let tcx = self . r . tcx ;
197199 self . changed |= self . def_effective_visibilities . update (
198200 def_id,
199201 Some ( nominal_vis) ,
200- || cheap_private_vis . unwrap_or_else ( || self . r . private_vis_def ( def_id ) ) ,
202+ priv_vis ,
201203 inherited_eff_vis,
202204 parent_id. level ( ) ,
203205 tcx,
204206 ) ;
205207 }
206208
207209 fn update_field ( & mut self , def_id : LocalDefId , parent_id : LocalDefId ) {
208- self . update_def ( def_id, self . r . tcx . local_visibility ( def_id) , ParentId :: Def ( parent_id) ) ;
210+ let nominal_vis = self . r . tcx . local_visibility ( def_id) ;
211+ self . update_def ( def_id, nominal_vis, ParentId :: Def ( parent_id) , self . current_private_vis ) ;
209212 }
210213}
211214
0 commit comments