@@ -125,26 +125,42 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
125125 fn set_bindings_effective_visibilities ( & mut self , module_id : LocalDefId ) {
126126 let module = self . r . expect_module ( module_id. to_def_id ( ) ) ;
127127 for ( _, name_resolution) in self . r . resolutions ( module) . borrow ( ) . iter ( ) {
128- let Some ( mut decl) = name_resolution. borrow ( ) . best_decl ( ) else {
128+ let Some ( decl) = name_resolution. borrow ( ) . best_decl ( ) else {
129129 continue ;
130130 } ;
131- // Set the given effective visibility level to `Level::Direct` and
132- // sets the rest of the `use` chain to `Level::Reexported` until
133- // we hit the actual exported item.
134- let priv_vis = |this : & Self , parent_id, decl| match parent_id {
135- ParentId :: Def ( _) => this. current_private_vis ,
136- ParentId :: Import ( _) => this. r . private_vis_decl ( decl) ,
137- } ;
138- let mut parent_id = ParentId :: Def ( module_id) ;
139- while let DeclKind :: Import { source_decl, .. } = decl. kind {
140- self . update_import ( decl, parent_id, priv_vis ( self , parent_id, decl) ) ;
141- parent_id = ParentId :: Import ( decl) ;
142- decl = source_decl;
143- }
144- if let Some ( def_id) = decl. res ( ) . opt_def_id ( ) . and_then ( |id| id. as_local ( ) ) {
145- let priv_vis = priv_vis ( self , parent_id, decl) ;
146- self . update_def ( def_id, decl. vis ( ) . expect_local ( ) , parent_id, priv_vis) ;
131+ self . update_decl_chain ( decl, ParentId :: Def ( module_id) ) ;
132+ }
133+ }
134+
135+ /// Update effective visibilities for the whole reexport chain of a declaration.
136+ /// Set the given effective visibility level to `Level::Direct` and
137+ /// sets the rest of the `use` chain to `Level::Reexported` until
138+ /// we hit the actual exported item.
139+ fn update_decl_chain ( & mut self , mut decl : Decl < ' ra > , mut parent_id : ParentId < ' ra > ) {
140+ let priv_vis = |this : & Self , parent_id, decl| match parent_id {
141+ ParentId :: Def ( _) => this. current_private_vis ,
142+ ParentId :: Import ( _) => this. r . private_vis_decl ( decl) ,
143+ } ;
144+ while let DeclKind :: Import { source_decl, .. } = decl. kind {
145+ self . update_import ( decl, parent_id, priv_vis ( self , parent_id, decl) ) ;
146+ if let Some ( max_vis_decl) = decl. ambiguity_vis_max . get ( ) {
147+ // The name is exported with the visibility of the most visible declaration
148+ // in its ambiguous glob set (see `DeclData::vis`), so everything on that
149+ // declaration's reexport chain, including the final item, must get its
150+ // effective visibility from that declaration as well. Otherwise the item
151+ // would be considered unreachable by dead code analysis and metadata
152+ // encoding despite being exported (see the regression test
153+ // `ambiguous-import-visibility-globglob-mir.rs`).
154+ // This also avoids the most visible import in an ambiguous glob set
155+ // being reported as unused.
156+ self . update_decl_chain ( max_vis_decl, parent_id) ;
147157 }
158+ parent_id = ParentId :: Import ( decl) ;
159+ decl = source_decl;
160+ }
161+ if let Some ( def_id) = decl. res ( ) . opt_def_id ( ) . and_then ( |id| id. as_local ( ) ) {
162+ let priv_vis = priv_vis ( self , parent_id, decl) ;
163+ self . update_def ( def_id, decl. vis ( ) . expect_local ( ) , parent_id, priv_vis) ;
148164 }
149165 }
150166
@@ -194,10 +210,6 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
194210 parent_id. level ( ) ,
195211 tcx,
196212 ) ;
197- if let Some ( max_vis_decl) = decl. ambiguity_vis_max . get ( ) {
198- // Avoid the most visible import in an ambiguous glob set being reported as unused.
199- self . update_import ( max_vis_decl, parent_id, priv_vis) ;
200- }
201213 }
202214
203215 fn update_def (
0 commit comments