@@ -5,7 +5,7 @@ use std::mem;
5
5
use std:: ops:: Deref ;
6
6
7
7
use rustc_ast:: NodeId ;
8
- use rustc_data_structures:: fx:: { FxHashSet , FxIndexSet } ;
8
+ use rustc_data_structures:: fx:: { FxHashSet , FxIndexMap , FxIndexSet } ;
9
9
use rustc_data_structures:: intern:: Interned ;
10
10
use rustc_errors:: codes:: * ;
11
11
use rustc_errors:: { Applicability , MultiSpan , pluralize, struct_span_code_err} ;
@@ -47,16 +47,20 @@ pub(crate) struct ImportResolver<'r, 'ra, 'tcx> {
47
47
batch : Vec < Import < ' ra > > , // a.k.a. indeterminate_imports, also treated as output
48
48
49
49
// outputs
50
+ prelude : Option < Module < ' ra > > ,
50
51
determined_imports : Vec < Import < ' ra > > ,
51
- glob_import_outputs : Vec < ( Module < ' ra > , BindingKey , NameBinding < ' ra > , bool ) > ,
52
+ module_glob_importers : FxIndexMap < Module < ' ra > , Vec < Import < ' ra > > > ,
53
+ glob_import_bindings : Vec < ( Module < ' ra > , BindingKey , NameBinding < ' ra > , bool ) > ,
52
54
glob_res_outputs : Vec < ( NodeId , PartialRes ) > ,
53
55
import_bindings : PerNS < Vec < ( Module < ' ra > , Import < ' ra > , PendingBinding < ' ra > ) > > ,
54
56
}
55
57
56
58
struct ImportResolutionOutputs < ' ra > {
59
+ prelude : Option < Module < ' ra > > ,
57
60
indeterminate_imports : Vec < Import < ' ra > > ,
58
61
determined_imports : Vec < Import < ' ra > > ,
59
- glob_import_outputs : Vec < ( Module < ' ra > , BindingKey , NameBinding < ' ra > , bool ) > ,
62
+ module_glob_importers : FxIndexMap < Module < ' ra > , Vec < Import < ' ra > > > ,
63
+ glob_import_bindings : Vec < ( Module < ' ra > , BindingKey , NameBinding < ' ra > , bool ) > ,
60
64
glob_res_outputs : Vec < ( NodeId , PartialRes ) > ,
61
65
import_bindings : PerNS < Vec < ( Module < ' ra > , Import < ' ra > , PendingBinding < ' ra > ) > > ,
62
66
}
@@ -66,20 +70,24 @@ impl<'r, 'ra, 'tcx> ImportResolver<'r, 'ra, 'tcx> {
66
70
ImportResolver {
67
71
r : cmr,
68
72
batch,
69
- determined_imports : Vec :: new ( ) ,
70
- import_bindings : PerNS :: default ( ) ,
71
- glob_import_outputs : Vec :: new ( ) ,
72
- glob_res_outputs : Vec :: new ( ) ,
73
+ prelude : None ,
74
+ determined_imports : Default :: default ( ) ,
75
+ module_glob_importers : Default :: default ( ) ,
76
+ glob_import_bindings : Default :: default ( ) ,
77
+ glob_res_outputs : Default :: default ( ) ,
78
+ import_bindings : Default :: default ( ) ,
73
79
}
74
80
}
75
81
76
82
fn into_outputs ( self ) -> ImportResolutionOutputs < ' ra > {
77
83
ImportResolutionOutputs {
84
+ prelude : self . prelude ,
78
85
indeterminate_imports : self . batch ,
79
86
determined_imports : self . determined_imports ,
80
- import_bindings : self . import_bindings ,
81
- glob_import_outputs : self . glob_import_outputs ,
87
+ module_glob_importers : self . module_glob_importers ,
88
+ glob_import_bindings : self . glob_import_bindings ,
82
89
glob_res_outputs : self . glob_res_outputs ,
90
+ import_bindings : self . import_bindings ,
83
91
}
84
92
}
85
93
}
@@ -89,7 +97,17 @@ impl<'ra> ImportResolutionOutputs<'ra> {
89
97
r. indeterminate_imports = self . indeterminate_imports ;
90
98
r. determined_imports . extend ( self . determined_imports ) ;
91
99
92
- for ( module, key, binding, warn_ambiguity) in self . glob_import_outputs {
100
+ // It's possible this particular round didn't set the prelude, so we should not
101
+ // unset it in the main resolver.
102
+ if self . prelude . is_some ( ) {
103
+ r. prelude = self . prelude ;
104
+ }
105
+
106
+ for ( module, glob_importers) in self . module_glob_importers {
107
+ module. glob_importers . borrow_mut ( ) . extend ( glob_importers) ;
108
+ }
109
+
110
+ for ( module, key, binding, warn_ambiguity) in self . glob_import_bindings {
93
111
let _ = r. try_define_local ( module, key. ident . 0 , key. ns , binding, warn_ambiguity) ;
94
112
}
95
113
@@ -648,12 +666,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
648
666
let mut prev_indeterminate_count = usize:: MAX ;
649
667
let mut indeterminate_count = self . indeterminate_imports . len ( ) * 3 ;
650
668
while indeterminate_count < prev_indeterminate_count {
651
- self . assert_speculative = true ;
652
669
prev_indeterminate_count = indeterminate_count;
653
670
let batch = mem:: take ( & mut self . indeterminate_imports ) ;
671
+ self . assert_speculative = true ;
654
672
let ( outputs, count) = ImportResolver :: new ( self . cm ( ) , batch) . resolve_batch ( ) ;
655
- indeterminate_count = count;
656
673
self . assert_speculative = false ;
674
+ indeterminate_count = count;
657
675
outputs. commit ( self ) ;
658
676
}
659
677
}
@@ -1589,12 +1607,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
1589
1607
if module == import. parent_scope . module {
1590
1608
return ;
1591
1609
} else if is_prelude {
1592
- self . r . prelude . set ( Some ( module) ) ;
1610
+ self . prelude = Some ( module) ;
1593
1611
return ;
1594
1612
}
1595
1613
1596
1614
// Add to module's glob_importers
1597
- module . glob_importers . borrow_mut ( ) . push ( import) ;
1615
+ self . module_glob_importers . entry ( module ) . or_default ( ) . push ( import) ;
1598
1616
1599
1617
// Ensure that `resolutions` isn't borrowed during `try_define`,
1600
1618
// since it might get updated via a glob cycle.
@@ -1618,7 +1636,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
1618
1636
. resolution ( import. parent_scope . module , key)
1619
1637
. and_then ( |r| r. binding ( ) )
1620
1638
. is_some_and ( |binding| binding. warn_ambiguity_recursive ( ) ) ;
1621
- self . glob_import_outputs . push ( (
1639
+ self . glob_import_bindings . push ( (
1622
1640
import. parent_scope . module ,
1623
1641
key,
1624
1642
imported_binding,
0 commit comments