@@ -325,21 +325,67 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
325325 self . arenas . alloc_name_binding ( NameBindingData {
326326 kind : NameBindingKind :: Import { binding, import } ,
327327 ambiguity : None ,
328- warn_ambiguity : false ,
329328 span : import. span ,
330329 vis,
331330 expansion : import. parent_scope . expansion ,
332331 } )
333332 }
334333
334+ fn select_glob_binding (
335+ & self ,
336+ glob_binding : NameBinding < ' ra > ,
337+ old_glob_binding : NameBinding < ' ra > ,
338+ ) -> NameBinding < ' ra > {
339+ assert ! ( glob_binding. is_glob_import( ) ) ;
340+ assert ! ( old_glob_binding. is_glob_import( ) ) ;
341+ assert_ne ! ( glob_binding, old_glob_binding) ;
342+ // `best_binding` with a given key in a module may be overwritten in a
343+ // number of cases (all of them can be seen below in this `match`),
344+ // all these overwrites will be re-fetched by glob imports importing
345+ // from that module without generating new ambiguities.
346+ // - A glob binding is overwritten by a non-glob binding arriving later.
347+ // - A glob binding is overwritten by an ambiguous glob binding.
348+ // FIXME: avoid this by putting `NameBindingData::ambiguity` under a
349+ // cell and updating it in place.
350+ // - A glob binding is overwritten by a glob binding with larger visibility.
351+ // FIXME: avoid this by putting `NameBindingData::vis` under a cell
352+ // and updating it in place.
353+ // - A glob binding is overwritten by a glob binding re-fetching an
354+ // overwritten binding from other module (the recursive case).
355+ // Here we are detecting all such re-fetches and overwrite old bindings
356+ // with the re-fetched bindings.
357+ let ( deep_binding, old_deep_binding) =
358+ Self :: remove_same_import ( glob_binding, old_glob_binding) ;
359+ if deep_binding != glob_binding {
360+ assert_ne ! ( old_deep_binding, old_glob_binding) ;
361+ assert_ne ! ( old_deep_binding, deep_binding) ;
362+ assert ! ( old_deep_binding. is_glob_import( ) ) ;
363+ glob_binding
364+ } else if glob_binding. res ( ) != old_glob_binding. res ( ) {
365+ self . new_ambiguity_binding (
366+ AmbiguityKind :: GlobVsGlob ,
367+ old_glob_binding,
368+ glob_binding,
369+ false ,
370+ )
371+ } else if !old_glob_binding. vis . is_at_least ( glob_binding. vis , self . tcx )
372+ || glob_binding. is_ambiguity_recursive ( )
373+ {
374+ // We are glob-importing the same item but with greater visibility,
375+ // or overwriting with an ambiguous glob import.
376+ glob_binding
377+ } else {
378+ old_glob_binding
379+ }
380+ }
381+
335382 /// Define the name or return the existing binding if there is a collision.
336383 pub ( crate ) fn try_define_local (
337384 & mut self ,
338385 module : Module < ' ra > ,
339386 ident : Ident ,
340387 ns : Namespace ,
341388 binding : NameBinding < ' ra > ,
342- warn_ambiguity : bool ,
343389 ) -> Result < ( ) , NameBinding < ' ra > > {
344390 let res = binding. res ( ) ;
345391 self . check_reserved_macro_name ( ident, res) ;
@@ -351,40 +397,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
351397 module. underscore_disambiguator . update_unchecked ( |d| d + 1 ) ;
352398 module. underscore_disambiguator . get ( )
353399 } ) ;
354- self . update_local_resolution ( module, key, warn_ambiguity , |this, resolution| {
400+ self . update_local_resolution ( module, key, |this, resolution| {
355401 if let Some ( old_binding) = resolution. best_binding ( ) {
402+ assert_ne ! ( binding, old_binding) ;
356403 if res == Res :: Err && old_binding. res ( ) != Res :: Err {
357404 // Do not override real bindings with `Res::Err`s from error recovery.
358405 return Ok ( ( ) ) ;
359406 }
360407 match ( old_binding. is_glob_import ( ) , binding. is_glob_import ( ) ) {
361408 ( true , true ) => {
362- let ( glob_binding, old_glob_binding) = ( binding, old_binding) ;
363- // FIXME: remove `!binding.is_ambiguity_recursive()` after delete the warning ambiguity.
364- if !binding. is_ambiguity_recursive ( )
365- && let NameBindingKind :: Import { import : old_import, .. } =
366- old_glob_binding. kind
367- && let NameBindingKind :: Import { import, .. } = glob_binding. kind
368- && old_import == import
369- {
370- // When imported from the same glob-import statement, we should replace
371- // `old_glob_binding` with `glob_binding`, regardless of whether
372- // they have the same resolution or not.
373- resolution. glob_binding = Some ( glob_binding) ;
374- } else if res != old_glob_binding. res ( ) {
375- resolution. glob_binding = Some ( this. new_ambiguity_binding (
376- AmbiguityKind :: GlobVsGlob ,
377- old_glob_binding,
378- glob_binding,
379- warn_ambiguity,
380- ) ) ;
381- } else if !old_binding. vis . is_at_least ( binding. vis , this. tcx ) {
382- // We are glob-importing the same item but with greater visibility.
383- resolution. glob_binding = Some ( glob_binding) ;
384- } else if binding. is_ambiguity_recursive ( ) {
385- resolution. glob_binding =
386- Some ( this. new_warn_ambiguity_binding ( glob_binding) ) ;
387- }
409+ resolution. glob_binding =
410+ Some ( this. select_glob_binding ( binding, old_binding) )
388411 }
389412 ( old_glob @ true , false ) | ( old_glob @ false , true ) => {
390413 let ( glob_binding, non_glob_binding) =
@@ -403,18 +426,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
403426 resolution. non_glob_binding = Some ( non_glob_binding) ;
404427 }
405428
406- if let Some ( old_glob_binding) = resolution. glob_binding {
407- assert ! ( old_glob_binding. is_glob_import( ) ) ;
408- if glob_binding. res ( ) != old_glob_binding. res ( ) {
409- resolution. glob_binding = Some ( this. new_ambiguity_binding (
410- AmbiguityKind :: GlobVsGlob ,
411- old_glob_binding,
412- glob_binding,
413- false ,
414- ) ) ;
415- } else if !old_glob_binding. vis . is_at_least ( binding. vis , this. tcx ) {
416- resolution. glob_binding = Some ( glob_binding) ;
417- }
429+ if let Some ( old_glob_binding) = resolution. glob_binding
430+ && old_glob_binding != glob_binding
431+ {
432+ resolution. glob_binding =
433+ Some ( this. select_glob_binding ( glob_binding, old_glob_binding) ) ;
418434 } else {
419435 resolution. glob_binding = Some ( glob_binding) ;
420436 }
@@ -440,33 +456,22 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
440456 ambiguity_kind : AmbiguityKind ,
441457 primary_binding : NameBinding < ' ra > ,
442458 secondary_binding : NameBinding < ' ra > ,
443- warn_ambiguity : bool ,
459+ warning : bool ,
444460 ) -> NameBinding < ' ra > {
445- let ambiguity = Some ( ( secondary_binding, ambiguity_kind) ) ;
446- let data = NameBindingData { ambiguity, warn_ambiguity , ..* primary_binding } ;
461+ let ambiguity = Some ( ( secondary_binding, ambiguity_kind, warning ) ) ;
462+ let data = NameBindingData { ambiguity, ..* primary_binding } ;
447463 self . arenas . alloc_name_binding ( data)
448464 }
449465
450- fn new_warn_ambiguity_binding ( & self , binding : NameBinding < ' ra > ) -> NameBinding < ' ra > {
451- assert ! ( binding. is_ambiguity_recursive( ) ) ;
452- self . arenas . alloc_name_binding ( NameBindingData { warn_ambiguity : true , ..* binding } )
453- }
454-
455466 // Use `f` to mutate the resolution of the name in the module.
456467 // If the resolution becomes a success, define it in the module's glob importers.
457- fn update_local_resolution < T , F > (
458- & mut self ,
459- module : Module < ' ra > ,
460- key : BindingKey ,
461- warn_ambiguity : bool ,
462- f : F ,
463- ) -> T
468+ fn update_local_resolution < T , F > ( & mut self , module : Module < ' ra > , key : BindingKey , f : F ) -> T
464469 where
465470 F : FnOnce ( & Resolver < ' ra , ' tcx > , & mut NameResolution < ' ra > ) -> T ,
466471 {
467472 // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
468473 // during which the resolution might end up getting re-defined via a glob cycle.
469- let ( binding, t, warn_ambiguity ) = {
474+ let ( binding, t) = {
470475 let resolution = & mut * self . resolution_or_default ( module, key) . borrow_mut_unchecked ( ) ;
471476 let old_binding = resolution. binding ( ) ;
472477
@@ -475,7 +480,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
475480 if let Some ( binding) = resolution. binding ( )
476481 && old_binding != Some ( binding)
477482 {
478- ( binding, t, warn_ambiguity || old_binding . is_some ( ) )
483+ ( binding, t)
479484 } else {
480485 return t;
481486 }
@@ -500,7 +505,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
500505 ident. 0 ,
501506 key. ns ,
502507 imported_binding,
503- warn_ambiguity,
504508 ) ;
505509 }
506510 }
@@ -521,11 +525,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
521525 let dummy_binding = self . import ( dummy_binding, import) ;
522526 self . per_ns ( |this, ns| {
523527 let module = import. parent_scope . module ;
524- let _ = this. try_define_local ( module, target, ns, dummy_binding, false ) ;
528+ let _ = this. try_define_local ( module, target, ns, dummy_binding) ;
525529 // Don't remove underscores from `single_imports`, they were never added.
526530 if target. name != kw:: Underscore {
527531 let key = BindingKey :: new ( target, ns) ;
528- this. update_local_resolution ( module, key, false , |_, resolution| {
532+ this. update_local_resolution ( module, key, |_, resolution| {
529533 resolution. single_imports . swap_remove ( & import) ;
530534 } )
531535 }
@@ -658,7 +662,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
658662 let Some ( binding) = resolution. best_binding ( ) else { continue } ;
659663
660664 if let NameBindingKind :: Import { import, .. } = binding. kind
661- && let Some ( ( amb_binding, _ ) ) = binding. ambiguity
665+ && let Some ( ( amb_binding, .. ) ) = binding. ambiguity
662666 && binding. res ( ) != Res :: Err
663667 && exported_ambiguities. contains ( & binding)
664668 {
@@ -917,7 +921,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
917921 this. get_mut_unchecked ( ) . update_local_resolution (
918922 parent,
919923 key,
920- false ,
921924 |_, resolution| {
922925 resolution. single_imports . swap_remove ( & import) ;
923926 } ,
@@ -1523,16 +1526,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15231526 } ;
15241527 if self . is_accessible_from ( binding. vis , scope) {
15251528 let imported_binding = self . import ( binding, import) ;
1526- let warn_ambiguity = self
1527- . resolution ( import. parent_scope . module , key)
1528- . and_then ( |r| r. binding ( ) )
1529- . is_some_and ( |binding| binding. warn_ambiguity_recursive ( ) ) ;
15301529 let _ = self . try_define_local (
15311530 import. parent_scope . module ,
15321531 key. ident . 0 ,
15331532 key. ns ,
15341533 imported_binding,
1535- warn_ambiguity,
15361534 ) ;
15371535 }
15381536 }
0 commit comments