@@ -25,7 +25,7 @@ use rustc_span::{Ident, Span, Symbol, kw, sym};
25
25
use smallvec:: SmallVec ;
26
26
use tracing:: debug;
27
27
28
- use crate :: Namespace :: * ;
28
+ use crate :: Namespace :: { self , * } ;
29
29
use crate :: diagnostics:: { DiagMode , Suggestion , import_candidates} ;
30
30
use crate :: errors:: {
31
31
CannotBeReexportedCratePublic , CannotBeReexportedCratePublicNS , CannotBeReexportedPrivate ,
@@ -338,13 +338,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
338
338
pub ( crate ) fn try_define (
339
339
& mut self ,
340
340
module : Module < ' ra > ,
341
- key : BindingKey ,
341
+ ident : Ident ,
342
+ ns : Namespace ,
342
343
binding : NameBinding < ' ra > ,
343
344
warn_ambiguity : bool ,
344
345
) -> Result < ( ) , NameBinding < ' ra > > {
345
346
let res = binding. res ( ) ;
346
- self . check_reserved_macro_name ( key . ident , res) ;
347
+ self . check_reserved_macro_name ( ident, res) ;
347
348
self . set_binding_parent_module ( binding, module) ;
349
+ // Even if underscore names cannot be looked up, we still need to add them to modules,
350
+ // because they can be fetched by glob imports from those modules, and bring traits
351
+ // into scope both directly and through glob imports.
352
+ let key = BindingKey :: new_disambiguated ( ident, ns, || {
353
+ ( module. 0 . 0 . lazy_resolutions . borrow ( ) . len ( ) + 1 ) . try_into ( ) . unwrap ( )
354
+ } ) ;
348
355
self . update_resolution ( module, key, warn_ambiguity, |this, resolution| {
349
356
if let Some ( old_binding) = resolution. best_binding ( ) {
350
357
if res == Res :: Err && old_binding. res ( ) != Res :: Err {
@@ -383,7 +390,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
383
390
( old_glob @ true , false ) | ( old_glob @ false , true ) => {
384
391
let ( glob_binding, non_glob_binding) =
385
392
if old_glob { ( old_binding, binding) } else { ( binding, old_binding) } ;
386
- if key . ns == MacroNS
393
+ if ns == MacroNS
387
394
&& non_glob_binding. expansion != LocalExpnId :: ROOT
388
395
&& glob_binding. res ( ) != non_glob_binding. res ( )
389
396
{
@@ -489,10 +496,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
489
496
} ;
490
497
if self . is_accessible_from ( binding. vis , scope) {
491
498
let imported_binding = self . import ( binding, * import) ;
492
- let key = BindingKey { ident, ..key } ;
493
499
let _ = self . try_define (
494
500
import. parent_scope . module ,
495
- key,
501
+ ident,
502
+ key. ns ,
496
503
imported_binding,
497
504
warn_ambiguity,
498
505
) ;
@@ -514,11 +521,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
514
521
let dummy_binding = self . dummy_binding ;
515
522
let dummy_binding = self . import ( dummy_binding, import) ;
516
523
self . per_ns ( |this, ns| {
517
- let key = BindingKey :: new ( target, ns) ;
518
- let _ = this. try_define ( import. parent_scope . module , key, dummy_binding, false ) ;
519
- this. update_resolution ( import. parent_scope . module , key, false , |_, resolution| {
520
- resolution. single_imports . swap_remove ( & import) ;
521
- } )
524
+ let module = import. parent_scope . module ;
525
+ let _ = this. try_define ( module, target, ns, dummy_binding, false ) ;
526
+ // Don't remove underscores from `single_imports`, they were never added.
527
+ if target. name != kw:: Underscore {
528
+ let key = BindingKey :: new ( target, ns) ;
529
+ this. update_resolution ( module, key, false , |_, resolution| {
530
+ resolution. single_imports . swap_remove ( & import) ;
531
+ } )
532
+ }
522
533
} ) ;
523
534
self . record_use ( target, dummy_binding, Used :: Other ) ;
524
535
} else if import. imported_module . get ( ) . is_none ( ) {
@@ -895,7 +906,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
895
906
PendingBinding :: Ready ( Some ( imported_binding) )
896
907
}
897
908
Err ( Determinacy :: Determined ) => {
898
- // Don't update the resolution for underscores, because it was never added.
909
+ // Don't remove underscores from `single_imports`, they were never added.
899
910
if target. name != kw:: Underscore {
900
911
let key = BindingKey :: new ( target, ns) ;
901
912
this. update_resolution ( parent, key, false , |_, resolution| {
@@ -1510,7 +1521,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
1510
1521
. is_some_and ( |binding| binding. warn_ambiguity_recursive ( ) ) ;
1511
1522
let _ = self . try_define (
1512
1523
import. parent_scope . module ,
1513
- key,
1524
+ key. ident ,
1525
+ key. ns ,
1514
1526
imported_binding,
1515
1527
warn_ambiguity,
1516
1528
) ;
0 commit comments