@@ -325,21 +325,68 @@ 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+ assert ! ( old_deep_binding. ambiguity. is_none( ) ) ;
364+ glob_binding
365+ } else if glob_binding. res ( ) != old_glob_binding. res ( ) {
366+ self . new_ambiguity_binding (
367+ AmbiguityKind :: GlobVsGlob ,
368+ old_glob_binding,
369+ glob_binding,
370+ false ,
371+ )
372+ } else if !old_glob_binding. vis . is_at_least ( glob_binding. vis , self . tcx )
373+ || glob_binding. is_ambiguity_recursive ( )
374+ {
375+ // We are glob-importing the same item but with greater visibility,
376+ // or overwriting with an ambiguous glob import.
377+ glob_binding
378+ } else {
379+ old_glob_binding
380+ }
381+ }
382+
335383 /// Define the name or return the existing binding if there is a collision.
336384 pub ( crate ) fn try_define_local (
337385 & mut self ,
338386 module : Module < ' ra > ,
339387 ident : Ident ,
340388 ns : Namespace ,
341389 binding : NameBinding < ' ra > ,
342- warn_ambiguity : bool ,
343390 ) -> Result < ( ) , NameBinding < ' ra > > {
344391 let res = binding. res ( ) ;
345392 self . check_reserved_macro_name ( ident, res) ;
@@ -351,40 +398,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
351398 module. underscore_disambiguator . update_unchecked ( |d| d + 1 ) ;
352399 module. underscore_disambiguator . get ( )
353400 } ) ;
354- self . update_local_resolution ( module, key, warn_ambiguity , |this, resolution| {
401+ self . update_local_resolution ( module, key, |this, resolution| {
355402 if let Some ( old_binding) = resolution. best_binding ( ) {
403+ assert_ne ! ( binding, old_binding) ;
356404 if res == Res :: Err && old_binding. res ( ) != Res :: Err {
357405 // Do not override real bindings with `Res::Err`s from error recovery.
358406 return Ok ( ( ) ) ;
359407 }
360408 match ( old_binding. is_glob_import ( ) , binding. is_glob_import ( ) ) {
361409 ( 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- }
410+ resolution. glob_binding =
411+ Some ( this. select_glob_binding ( binding, old_binding) )
388412 }
389413 ( old_glob @ true , false ) | ( old_glob @ false , true ) => {
390414 let ( glob_binding, non_glob_binding) =
@@ -403,18 +427,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
403427 resolution. non_glob_binding = Some ( non_glob_binding) ;
404428 }
405429
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- }
430+ if let Some ( old_glob_binding) = resolution. glob_binding
431+ && old_glob_binding != glob_binding
432+ {
433+ resolution. glob_binding =
434+ Some ( this. select_glob_binding ( glob_binding, old_glob_binding) ) ;
418435 } else {
419436 resolution. glob_binding = Some ( glob_binding) ;
420437 }
@@ -440,33 +457,22 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
440457 ambiguity_kind : AmbiguityKind ,
441458 primary_binding : NameBinding < ' ra > ,
442459 secondary_binding : NameBinding < ' ra > ,
443- warn_ambiguity : bool ,
460+ warning : bool ,
444461 ) -> NameBinding < ' ra > {
445- let ambiguity = Some ( ( secondary_binding, ambiguity_kind) ) ;
446- let data = NameBindingData { ambiguity, warn_ambiguity , ..* primary_binding } ;
462+ let ambiguity = Some ( ( secondary_binding, ambiguity_kind, warning ) ) ;
463+ let data = NameBindingData { ambiguity, ..* primary_binding } ;
447464 self . arenas . alloc_name_binding ( data)
448465 }
449466
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-
455467 // Use `f` to mutate the resolution of the name in the module.
456468 // 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
469+ fn update_local_resolution < T , F > ( & mut self , module : Module < ' ra > , key : BindingKey , f : F ) -> T
464470 where
465471 F : FnOnce ( & Resolver < ' ra , ' tcx > , & mut NameResolution < ' ra > ) -> T ,
466472 {
467473 // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
468474 // during which the resolution might end up getting re-defined via a glob cycle.
469- let ( binding, t, warn_ambiguity ) = {
475+ let ( binding, t) = {
470476 let resolution = & mut * self . resolution_or_default ( module, key) . borrow_mut_unchecked ( ) ;
471477 let old_binding = resolution. binding ( ) ;
472478
@@ -475,7 +481,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
475481 if let Some ( binding) = resolution. binding ( )
476482 && old_binding != Some ( binding)
477483 {
478- ( binding, t, warn_ambiguity || old_binding . is_some ( ) )
484+ ( binding, t)
479485 } else {
480486 return t;
481487 }
@@ -500,7 +506,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
500506 ident. 0 ,
501507 key. ns ,
502508 imported_binding,
503- warn_ambiguity,
504509 ) ;
505510 }
506511 }
@@ -521,11 +526,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
521526 let dummy_binding = self . import ( dummy_binding, import) ;
522527 self . per_ns ( |this, ns| {
523528 let module = import. parent_scope . module ;
524- let _ = this. try_define_local ( module, target, ns, dummy_binding, false ) ;
529+ let _ = this. try_define_local ( module, target, ns, dummy_binding) ;
525530 // Don't remove underscores from `single_imports`, they were never added.
526531 if target. name != kw:: Underscore {
527532 let key = BindingKey :: new ( target, ns) ;
528- this. update_local_resolution ( module, key, false , |_, resolution| {
533+ this. update_local_resolution ( module, key, |_, resolution| {
529534 resolution. single_imports . swap_remove ( & import) ;
530535 } )
531536 }
@@ -658,7 +663,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
658663 let Some ( binding) = resolution. best_binding ( ) else { continue } ;
659664
660665 if let NameBindingKind :: Import { import, .. } = binding. kind
661- && let Some ( ( amb_binding, _ ) ) = binding. ambiguity
666+ && let Some ( ( amb_binding, .. ) ) = binding. ambiguity
662667 && binding. res ( ) != Res :: Err
663668 && exported_ambiguities. contains ( & binding)
664669 {
@@ -917,7 +922,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
917922 this. get_mut_unchecked ( ) . update_local_resolution (
918923 parent,
919924 key,
920- false ,
921925 |_, resolution| {
922926 resolution. single_imports . swap_remove ( & import) ;
923927 } ,
@@ -1523,16 +1527,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15231527 } ;
15241528 if self . is_accessible_from ( binding. vis , scope) {
15251529 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 ( ) ) ;
15301530 let _ = self . try_define_local (
15311531 import. parent_scope . module ,
15321532 key. ident . 0 ,
15331533 key. ns ,
15341534 imported_binding,
1535- warn_ambiguity,
15361535 ) ;
15371536 }
15381537 }
0 commit comments