@@ -3,19 +3,24 @@ use hir::{self, intravisit, HirId, ItemLocalId};
33use syntax:: ast:: NodeId ;
44use hir:: itemlikevisit:: ItemLikeVisitor ;
55use rustc_data_structures:: fx:: FxHashMap ;
6+ use rustc_data_structures:: sync:: { Lock , ParallelIterator , par_iter} ;
67
78pub fn check_crate < ' hir > ( hir_map : & hir:: map:: Map < ' hir > ) {
8- let mut outer_visitor = OuterVisitor {
9- hir_map,
10- errors : vec ! [ ] ,
11- } ;
12-
139 hir_map. dep_graph . assert_ignored ( ) ;
1410
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
1924 . iter ( )
2025 . fold ( String :: new ( ) , |s1, s2| s1 + "\n " + s2) ;
2126 bug ! ( "{}" , message) ;
@@ -26,12 +31,12 @@ struct HirIdValidator<'a, 'hir: 'a> {
2631 hir_map : & ' a hir:: map:: Map < ' hir > ,
2732 owner_def_index : Option < DefIndex > ,
2833 hir_ids_seen : FxHashMap < ItemLocalId , NodeId > ,
29- errors : Vec < String > ,
34+ errors : & ' a Lock < Vec < String > > ,
3035}
3136
3237struct OuterVisitor < ' a , ' hir : ' a > {
3338 hir_map : & ' a hir:: map:: Map < ' hir > ,
34- errors : Vec < String > ,
39+ errors : & ' a Lock < Vec < String > > ,
3540}
3641
3742impl < ' a , ' hir : ' a > OuterVisitor < ' a , ' hir > {
@@ -42,7 +47,7 @@ impl<'a, 'hir: 'a> OuterVisitor<'a, 'hir> {
4247 hir_map,
4348 owner_def_index : None ,
4449 hir_ids_seen : Default :: default ( ) ,
45- errors : Vec :: new ( ) ,
50+ errors : self . errors ,
4651 }
4752 }
4853}
@@ -51,23 +56,25 @@ impl<'a, 'hir: 'a> ItemLikeVisitor<'hir> for OuterVisitor<'a, 'hir> {
5156 fn visit_item ( & mut self , i : & ' hir hir:: Item ) {
5257 let mut inner_visitor = self . new_inner_visitor ( self . hir_map ) ;
5358 inner_visitor. check ( i. id , |this| intravisit:: walk_item ( this, i) ) ;
54- self . errors . extend ( inner_visitor. errors . drain ( ..) ) ;
5559 }
5660
5761 fn visit_trait_item ( & mut self , i : & ' hir hir:: TraitItem ) {
5862 let mut inner_visitor = self . new_inner_visitor ( self . hir_map ) ;
5963 inner_visitor. check ( i. id , |this| intravisit:: walk_trait_item ( this, i) ) ;
60- self . errors . extend ( inner_visitor. errors . drain ( ..) ) ;
6164 }
6265
6366 fn visit_impl_item ( & mut self , i : & ' hir hir:: ImplItem ) {
6467 let mut inner_visitor = self . new_inner_visitor ( self . hir_map ) ;
6568 inner_visitor. check ( i. id , |this| intravisit:: walk_impl_item ( this, i) ) ;
66- self . errors . extend ( inner_visitor. errors . drain ( ..) ) ;
6769 }
6870}
6971
7072impl < ' 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+ }
7178
7279 fn check < F : FnOnce ( & mut HirIdValidator < ' a , ' hir > ) > ( & mut self ,
7380 node_id : NodeId ,
@@ -119,7 +126,7 @@ impl<'a, 'hir: 'a> HirIdValidator<'a, 'hir> {
119126 local_id,
120127 self . hir_map. node_to_string( node_id) ) ) ;
121128 }
122- self . errors . push ( format ! (
129+ self . error ( || format ! (
123130 "ItemLocalIds not assigned densely in {}. \
124131 Max ItemLocalId = {}, missing IDs = {:?}; seens IDs = {:?}",
125132 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> {
145152 let stable_id = self . hir_map . definitions ( ) . node_to_hir_id [ node_id] ;
146153
147154 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 {}: {:?}" ,
149156 node_id,
150157 self . hir_map. node_to_string( node_id) ) ) ;
151158 return ;
152159 }
153160
154161 if owner != stable_id. owner {
155- self . errors . push ( format ! (
162+ self . error ( || format ! (
156163 "HirIdValidator: The recorded owner of {} is {} instead of {}" ,
157164 self . hir_map. node_to_string( node_id) ,
158165 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> {
161168
162169 if let Some ( prev) = self . hir_ids_seen . insert ( stable_id. local_id , node_id) {
163170 if prev != node_id {
164- self . errors . push ( format ! (
171+ self . error ( || format ! (
165172 "HirIdValidator: Same HirId {}/{} assigned for nodes {} and {}" ,
166173 self . hir_map. def_path( DefId :: local( stable_id. owner) ) . to_string_no_crate( ) ,
167174 stable_id. local_id. as_usize( ) ,
0 commit comments