@@ -3,19 +3,24 @@ use hir::{self, intravisit, HirId, ItemLocalId};
3
3
use syntax:: ast:: NodeId ;
4
4
use hir:: itemlikevisit:: ItemLikeVisitor ;
5
5
use rustc_data_structures:: fx:: FxHashMap ;
6
+ use rustc_data_structures:: sync:: { Lock , ParallelIterator , par_iter} ;
6
7
7
8
pub fn check_crate < ' hir > ( hir_map : & hir:: map:: Map < ' hir > ) {
8
- let mut outer_visitor = OuterVisitor {
9
- hir_map,
10
- errors : vec ! [ ] ,
11
- } ;
12
-
13
9
hir_map. dep_graph . assert_ignored ( ) ;
14
10
15
- hir_map. krate ( ) . visit_all_item_likes ( & mut outer_visitor) ;
16
- if !outer_visitor. errors . is_empty ( ) {
17
- let message = outer_visitor
18
- . errors
11
+ let errors = Lock :: new ( Vec :: new ( ) ) ;
12
+
13
+ par_iter ( & hir_map. krate ( ) . modules ) . for_each ( |( module_id, _) | {
14
+ hir_map. visit_item_likes_in_module ( hir_map. local_def_id ( * module_id) , & mut OuterVisitor {
15
+ hir_map,
16
+ errors : & errors,
17
+ } ) ;
18
+ } ) ;
19
+
20
+ let errors = errors. into_inner ( ) ;
21
+
22
+ if !errors. is_empty ( ) {
23
+ let message = errors
19
24
. iter ( )
20
25
. fold ( String :: new ( ) , |s1, s2| s1 + "\n " + s2) ;
21
26
bug ! ( "{}" , message) ;
@@ -26,12 +31,12 @@ struct HirIdValidator<'a, 'hir: 'a> {
26
31
hir_map : & ' a hir:: map:: Map < ' hir > ,
27
32
owner_def_index : Option < DefIndex > ,
28
33
hir_ids_seen : FxHashMap < ItemLocalId , NodeId > ,
29
- errors : Vec < String > ,
34
+ errors : & ' a Lock < Vec < String > > ,
30
35
}
31
36
32
37
struct OuterVisitor < ' a , ' hir : ' a > {
33
38
hir_map : & ' a hir:: map:: Map < ' hir > ,
34
- errors : Vec < String > ,
39
+ errors : & ' a Lock < Vec < String > > ,
35
40
}
36
41
37
42
impl < ' a , ' hir : ' a > OuterVisitor < ' a , ' hir > {
@@ -42,7 +47,7 @@ impl<'a, 'hir: 'a> OuterVisitor<'a, 'hir> {
42
47
hir_map,
43
48
owner_def_index : None ,
44
49
hir_ids_seen : Default :: default ( ) ,
45
- errors : Vec :: new ( ) ,
50
+ errors : self . errors ,
46
51
}
47
52
}
48
53
}
@@ -51,23 +56,25 @@ impl<'a, 'hir: 'a> ItemLikeVisitor<'hir> for OuterVisitor<'a, 'hir> {
51
56
fn visit_item ( & mut self , i : & ' hir hir:: Item ) {
52
57
let mut inner_visitor = self . new_inner_visitor ( self . hir_map ) ;
53
58
inner_visitor. check ( i. id , |this| intravisit:: walk_item ( this, i) ) ;
54
- self . errors . extend ( inner_visitor. errors . drain ( ..) ) ;
55
59
}
56
60
57
61
fn visit_trait_item ( & mut self , i : & ' hir hir:: TraitItem ) {
58
62
let mut inner_visitor = self . new_inner_visitor ( self . hir_map ) ;
59
63
inner_visitor. check ( i. id , |this| intravisit:: walk_trait_item ( this, i) ) ;
60
- self . errors . extend ( inner_visitor. errors . drain ( ..) ) ;
61
64
}
62
65
63
66
fn visit_impl_item ( & mut self , i : & ' hir hir:: ImplItem ) {
64
67
let mut inner_visitor = self . new_inner_visitor ( self . hir_map ) ;
65
68
inner_visitor. check ( i. id , |this| intravisit:: walk_impl_item ( this, i) ) ;
66
- self . errors . extend ( inner_visitor. errors . drain ( ..) ) ;
67
69
}
68
70
}
69
71
70
72
impl < ' a , ' hir : ' a > HirIdValidator < ' a , ' hir > {
73
+ #[ cold]
74
+ #[ inline( never) ]
75
+ fn error ( & self , f : impl FnOnce ( ) -> String ) {
76
+ self . errors . lock ( ) . push ( f ( ) ) ;
77
+ }
71
78
72
79
fn check < F : FnOnce ( & mut HirIdValidator < ' a , ' hir > ) > ( & mut self ,
73
80
node_id : NodeId ,
@@ -119,7 +126,7 @@ impl<'a, 'hir: 'a> HirIdValidator<'a, 'hir> {
119
126
local_id,
120
127
self . hir_map. node_to_string( node_id) ) ) ;
121
128
}
122
- self . errors . push ( format ! (
129
+ self . error ( || format ! (
123
130
"ItemLocalIds not assigned densely in {}. \
124
131
Max ItemLocalId = {}, missing IDs = {:?}; seens IDs = {:?}",
125
132
self . hir_map. def_path( DefId :: local( owner_def_index) ) . to_string_no_crate( ) ,
@@ -145,14 +152,14 @@ impl<'a, 'hir: 'a> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
145
152
let stable_id = self . hir_map . definitions ( ) . node_to_hir_id [ node_id] ;
146
153
147
154
if stable_id == hir:: DUMMY_HIR_ID {
148
- self . errors . push ( format ! ( "HirIdValidator: No HirId assigned for NodeId {}: {:?}" ,
155
+ self . error ( || format ! ( "HirIdValidator: No HirId assigned for NodeId {}: {:?}" ,
149
156
node_id,
150
157
self . hir_map. node_to_string( node_id) ) ) ;
151
158
return ;
152
159
}
153
160
154
161
if owner != stable_id. owner {
155
- self . errors . push ( format ! (
162
+ self . error ( || format ! (
156
163
"HirIdValidator: The recorded owner of {} is {} instead of {}" ,
157
164
self . hir_map. node_to_string( node_id) ,
158
165
self . hir_map. def_path( DefId :: local( stable_id. owner) ) . to_string_no_crate( ) ,
@@ -161,7 +168,7 @@ impl<'a, 'hir: 'a> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
161
168
162
169
if let Some ( prev) = self . hir_ids_seen . insert ( stable_id. local_id , node_id) {
163
170
if prev != node_id {
164
- self . errors . push ( format ! (
171
+ self . error ( || format ! (
165
172
"HirIdValidator: Same HirId {}/{} assigned for nodes {} and {}" ,
166
173
self . hir_map. def_path( DefId :: local( stable_id. owner) ) . to_string_no_crate( ) ,
167
174
stable_id. local_id. as_usize( ) ,
0 commit comments