@@ -370,8 +370,17 @@ fn remove_same_import<'ra>(d1: Decl<'ra>, d2: Decl<'ra>) -> (Decl<'ra>, Decl<'ra
370370
371371impl < ' ra , ' tcx > Resolver < ' ra , ' tcx > {
372372 pub ( crate ) fn import_decl_vis ( & self , decl : Decl < ' ra > , import : ImportSummary ) -> Visibility {
373+ self . import_decl_vis_ext ( decl, import, false )
374+ }
375+
376+ pub ( crate ) fn import_decl_vis_ext (
377+ & self ,
378+ decl : Decl < ' ra > ,
379+ import : ImportSummary ,
380+ min : bool ,
381+ ) -> Visibility {
373382 assert ! ( import. vis. is_accessible_from( import. nearest_parent_mod, self . tcx) ) ;
374- let decl_vis = decl. vis ( ) ;
383+ let decl_vis = if min { decl. min_vis ( ) } else { decl . vis ( ) } ;
375384 if decl_vis. partial_cmp ( import. vis , self . tcx ) == Some ( Ordering :: Less )
376385 && decl_vis. is_accessible_from ( import. nearest_parent_mod , self . tcx )
377386 && pub_use_of_private_extern_crate_hack ( import, decl) . is_none ( )
@@ -409,7 +418,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
409418 ambiguity : CmCell :: new ( None ) ,
410419 warn_ambiguity : CmCell :: new ( false ) ,
411420 span : import. span ,
412- vis : CmCell :: new ( vis. to_def_id ( ) ) ,
421+ initial_vis : vis. to_def_id ( ) ,
422+ ambiguity_vis_max : CmCell :: new ( None ) ,
423+ ambiguity_vis_min : CmCell :: new ( None ) ,
413424 expansion : import. parent_scope . expansion ,
414425 parent_module : Some ( import. parent_scope . module ) ,
415426 } )
@@ -434,8 +445,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
434445 // - A glob decl is overwritten by its clone after setting ambiguity in it.
435446 // FIXME: avoid this by removing `warn_ambiguity`, or by triggering glob re-fetch
436447 // with the same decl in some way.
437- // - A glob decl is overwritten by a glob decl with larger visibility.
438- // FIXME: avoid this by updating this visibility in place.
439448 // - A glob decl is overwritten by a glob decl re-fetching an
440449 // overwritten decl from other module (the recursive case).
441450 // Here we are detecting all such re-fetches and overwrite old decls
@@ -449,8 +458,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
449458 // FIXME: reenable the asserts when `warn_ambiguity` is removed (#149195).
450459 // assert_ne!(old_deep_decl, deep_decl);
451460 // assert!(old_deep_decl.is_glob_import());
452- // FIXME: reenable the assert when visibility is updated in place.
453- // assert!(!deep_decl.is_glob_import());
461+ assert ! ( !deep_decl. is_glob_import( ) ) ;
454462 if old_glob_decl. ambiguity . get ( ) . is_some ( ) && glob_decl. ambiguity . get ( ) . is_none ( ) {
455463 // Do not lose glob ambiguities when re-fetching the glob.
456464 glob_decl. ambiguity . set_unchecked ( old_glob_decl. ambiguity . get ( ) ) ;
@@ -470,12 +478,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
470478 // FIXME: remove this when `warn_ambiguity` is removed (#149195).
471479 self . arenas . alloc_decl ( ( * old_glob_decl) . clone ( ) )
472480 }
473- } else if glob_decl. vis ( ) . greater_than ( old_glob_decl. vis ( ) , self . tcx ) {
474- // We are glob-importing the same item but with greater visibility.
481+ } else if let old_vis = old_glob_decl. vis ( )
482+ && let vis = glob_decl. vis ( )
483+ && old_vis != vis
484+ {
485+ // We are glob-importing the same item but with a different visibility.
475486 // All visibilities here are ordered because all of them are ancestors of `module`.
476- // FIXME: Update visibility in place, but without regressions
477- // (#152004, #151124, #152347).
478- glob_decl
487+ if vis. greater_than ( old_vis, self . tcx ) {
488+ old_glob_decl. ambiguity_vis_max . set_unchecked ( Some ( glob_decl) ) ;
489+ } else if let old_min_vis = old_glob_decl. min_vis ( )
490+ && old_min_vis != vis
491+ && old_min_vis. greater_than ( vis, self . tcx )
492+ {
493+ old_glob_decl. ambiguity_vis_min . set_unchecked ( Some ( glob_decl) ) ;
494+ }
495+ old_glob_decl
479496 } else if glob_decl. is_ambiguity_recursive ( ) && !old_glob_decl. is_ambiguity_recursive ( ) {
480497 // Overwriting a non-ambiguous glob import with an ambiguous glob import.
481498 old_glob_decl. ambiguity . set_unchecked ( Some ( glob_decl) ) ;
@@ -498,6 +515,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
498515 ) -> Result < ( ) , Decl < ' ra > > {
499516 assert ! ( !decl. warn_ambiguity. get( ) ) ;
500517 assert ! ( decl. ambiguity. get( ) . is_none( ) ) ;
518+ assert ! ( decl. ambiguity_vis_max. get( ) . is_none( ) ) ;
519+ assert ! ( decl. ambiguity_vis_min. get( ) . is_none( ) ) ;
501520 let module = decl. parent_module . unwrap ( ) . expect_local ( ) ;
502521 assert ! ( self . is_accessible_from( decl. vis( ) , module. to_module( ) ) ) ;
503522 let res = decl. res ( ) ;
@@ -556,11 +575,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
556575 . resolution_or_default ( module. to_module ( ) , key, orig_ident_span)
557576 . borrow_mut_unchecked ( ) ;
558577 let old_decl = resolution. determined_decl ( ) ;
578+ let old_vis = old_decl. map ( |d| d. vis ( ) ) ;
559579
560580 let t = f ( self , resolution) ;
561581
562582 if let Some ( binding) = resolution. determined_decl ( )
563- && old_decl != Some ( binding)
583+ && ( old_decl != Some ( binding) || old_vis != Some ( binding . vis ( ) ) )
564584 {
565585 ( binding, t, warn_ambiguity || old_decl. is_some ( ) )
566586 } else {
0 commit comments