1
- use rustc_data_structures:: sync:: Lock ;
2
- use rustc_hir as hir;
3
- use rustc_hir:: def_id:: LocalDefId ;
4
- use rustc_hir:: intravisit;
5
- use rustc_hir:: { HirId , ItemLocalId } ;
6
- use rustc_index:: bit_set:: GrowableBitSet ;
7
- use rustc_middle:: hir:: nested_filter;
8
1
use rustc_middle:: ty:: TyCtxt ;
9
2
10
3
pub fn check_crate ( tcx : TyCtxt < ' _ > ) {
@@ -13,7 +6,20 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
13
6
}
14
7
15
8
#[ cfg( debug_assertions) ]
16
- {
9
+ validator:: check_crate ( tcx) ;
10
+ }
11
+
12
+ #[ cfg( debug_assertions) ]
13
+ mod validator {
14
+ use rustc_data_structures:: sync:: Lock ;
15
+ use rustc_hir as hir;
16
+ use rustc_hir:: def_id:: LocalDefId ;
17
+ use rustc_hir:: { intravisit, HirId , ItemLocalId } ;
18
+ use rustc_index:: bit_set:: GrowableBitSet ;
19
+ use rustc_middle:: hir:: nested_filter;
20
+ use rustc_middle:: ty:: TyCtxt ;
21
+
22
+ pub fn check_crate ( tcx : TyCtxt < ' _ > ) {
17
23
let errors = Lock :: new ( Vec :: new ( ) ) ;
18
24
19
25
tcx. hir ( ) . par_for_each_module ( |module_id| {
@@ -34,143 +40,152 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
34
40
tcx. dcx ( ) . delayed_bug ( message) ;
35
41
}
36
42
}
37
- }
38
-
39
- struct HirIdValidator < ' a , ' hir > {
40
- tcx : TyCtxt < ' hir > ,
41
- owner : Option < hir:: OwnerId > ,
42
- hir_ids_seen : GrowableBitSet < ItemLocalId > ,
43
- errors : & ' a Lock < Vec < String > > ,
44
- }
45
-
46
- impl < ' a , ' hir > HirIdValidator < ' a , ' hir > {
47
- fn new_visitor ( & self , tcx : TyCtxt < ' hir > ) -> HirIdValidator < ' a , ' hir > {
48
- HirIdValidator { tcx, owner : None , hir_ids_seen : Default :: default ( ) , errors : self . errors }
49
- }
50
43
51
- #[ cold]
52
- #[ inline( never) ]
53
- fn error ( & self , f : impl FnOnce ( ) -> String ) {
54
- self . errors . lock ( ) . push ( f ( ) ) ;
44
+ struct HirIdValidator < ' a , ' hir > {
45
+ tcx : TyCtxt < ' hir > ,
46
+ owner : Option < hir:: OwnerId > ,
47
+ hir_ids_seen : GrowableBitSet < ItemLocalId > ,
48
+ errors : & ' a Lock < Vec < String > > ,
55
49
}
56
50
57
- fn check < F : FnOnce ( & mut HirIdValidator < ' a , ' hir > ) > ( & mut self , owner : hir:: OwnerId , walk : F ) {
58
- assert ! ( self . owner. is_none( ) ) ;
59
- self . owner = Some ( owner) ;
60
- walk ( self ) ;
51
+ impl < ' a , ' hir > HirIdValidator < ' a , ' hir > {
52
+ fn new_visitor ( & self , tcx : TyCtxt < ' hir > ) -> HirIdValidator < ' a , ' hir > {
53
+ HirIdValidator {
54
+ tcx,
55
+ owner : None ,
56
+ hir_ids_seen : Default :: default ( ) ,
57
+ errors : self . errors ,
58
+ }
59
+ }
61
60
62
- if owner == hir:: CRATE_OWNER_ID {
63
- return ;
61
+ #[ cold]
62
+ #[ inline( never) ]
63
+ fn error ( & self , f : impl FnOnce ( ) -> String ) {
64
+ self . errors . lock ( ) . push ( f ( ) ) ;
64
65
}
65
66
66
- // There's always at least one entry for the owning item itself
67
- let max = self
68
- . hir_ids_seen
69
- . iter ( )
70
- . map ( |local_id| local_id. as_usize ( ) )
71
- . max ( )
72
- . expect ( "owning item has no entry" ) ;
73
-
74
- if max != self . hir_ids_seen . len ( ) - 1 {
75
- let hir = self . tcx . hir ( ) ;
76
- let pretty_owner = hir. def_path ( owner. def_id ) . to_string_no_crate_verbose ( ) ;
77
-
78
- let missing_items: Vec < _ > = ( 0 ..=max as u32 )
79
- . map ( |i| ItemLocalId :: from_u32 ( i) )
80
- . filter ( |& local_id| !self . hir_ids_seen . contains ( local_id) )
81
- . map ( |local_id| hir. node_to_string ( HirId { owner, local_id } ) )
82
- . collect ( ) ;
83
-
84
- let seen_items: Vec < _ > = self
67
+ fn check < F : FnOnce ( & mut HirIdValidator < ' a , ' hir > ) > (
68
+ & mut self ,
69
+ owner : hir:: OwnerId ,
70
+ walk : F ,
71
+ ) {
72
+ assert ! ( self . owner. is_none( ) ) ;
73
+ self . owner = Some ( owner) ;
74
+ walk ( self ) ;
75
+
76
+ if owner == hir:: CRATE_OWNER_ID {
77
+ return ;
78
+ }
79
+
80
+ // There's always at least one entry for the owning item itself
81
+ let max = self
85
82
. hir_ids_seen
86
83
. iter ( )
87
- . map ( |local_id| hir. node_to_string ( HirId { owner, local_id } ) )
88
- . collect ( ) ;
89
-
90
- self . error ( || {
84
+ . map ( |local_id| local_id. as_usize ( ) )
85
+ . max ( )
86
+ . expect ( "owning item has no entry" ) ;
87
+
88
+ if max != self . hir_ids_seen . len ( ) - 1 {
89
+ let hir = self . tcx . hir ( ) ;
90
+ let pretty_owner = hir. def_path ( owner. def_id ) . to_string_no_crate_verbose ( ) ;
91
+
92
+ let missing_items: Vec < _ > = ( 0 ..=max as u32 )
93
+ . map ( |i| ItemLocalId :: from_u32 ( i) )
94
+ . filter ( |& local_id| !self . hir_ids_seen . contains ( local_id) )
95
+ . map ( |local_id| hir. node_to_string ( HirId { owner, local_id } ) )
96
+ . collect ( ) ;
97
+
98
+ let seen_items: Vec < _ > = self
99
+ . hir_ids_seen
100
+ . iter ( )
101
+ . map ( |local_id| hir. node_to_string ( HirId { owner, local_id } ) )
102
+ . collect ( ) ;
103
+
104
+ self . error ( || {
91
105
format ! (
92
106
"ItemLocalIds not assigned densely in {pretty_owner}. \
93
107
Max ItemLocalId = {max}, missing IDs = {missing_items:#?}; seen IDs = {seen_items:#?}"
94
108
)
95
109
} ) ;
110
+ }
96
111
}
97
- }
98
112
99
- fn check_nested_id ( & mut self , id : LocalDefId ) {
100
- let Some ( owner) = self . owner else { return } ;
101
- let def_parent = self . tcx . local_parent ( id) ;
102
- let def_parent_hir_id = self . tcx . local_def_id_to_hir_id ( def_parent) ;
103
- if def_parent_hir_id. owner != owner {
104
- self . error ( || {
105
- format ! (
106
- "inconsistent Def parent at `{:?}` for `{:?}`:\n expected={:?}\n found={:?}" ,
107
- self . tcx. def_span( id) ,
108
- id,
109
- owner,
110
- def_parent_hir_id
111
- )
112
- } ) ;
113
+ fn check_nested_id ( & mut self , id : LocalDefId ) {
114
+ let Some ( owner) = self . owner else { return } ;
115
+ let def_parent = self . tcx . local_parent ( id) ;
116
+ let def_parent_hir_id = self . tcx . local_def_id_to_hir_id ( def_parent) ;
117
+ if def_parent_hir_id. owner != owner {
118
+ self . error ( || {
119
+ format ! (
120
+ "inconsistent Def parent at `{:?}` for `{:?}`:\n expected={:?}\n found={:?}" ,
121
+ self . tcx. def_span( id) ,
122
+ id,
123
+ owner,
124
+ def_parent_hir_id
125
+ )
126
+ } ) ;
127
+ }
113
128
}
114
129
}
115
- }
116
-
117
- impl < ' a , ' hir > intravisit:: Visitor < ' hir > for HirIdValidator < ' a , ' hir > {
118
- type NestedFilter = nested_filter:: OnlyBodies ;
119
-
120
- fn nested_visit_map ( & mut self ) -> Self :: Map {
121
- self . tcx . hir ( )
122
- }
123
130
124
- fn visit_nested_item ( & mut self , id : hir:: ItemId ) {
125
- self . check_nested_id ( id. owner_id . def_id ) ;
126
- }
131
+ impl < ' a , ' hir > intravisit:: Visitor < ' hir > for HirIdValidator < ' a , ' hir > {
132
+ type NestedFilter = nested_filter:: OnlyBodies ;
127
133
128
- fn visit_nested_trait_item ( & mut self , id : hir :: TraitItemId ) {
129
- self . check_nested_id ( id . owner_id . def_id ) ;
130
- }
134
+ fn nested_visit_map ( & mut self ) -> Self :: Map {
135
+ self . tcx . hir ( )
136
+ }
131
137
132
- fn visit_nested_impl_item ( & mut self , id : hir:: ImplItemId ) {
133
- self . check_nested_id ( id. owner_id . def_id ) ;
134
- }
138
+ fn visit_nested_item ( & mut self , id : hir:: ItemId ) {
139
+ self . check_nested_id ( id. owner_id . def_id ) ;
140
+ }
135
141
136
- fn visit_nested_foreign_item ( & mut self , id : hir:: ForeignItemId ) {
137
- self . check_nested_id ( id. owner_id . def_id ) ;
138
- }
142
+ fn visit_nested_trait_item ( & mut self , id : hir:: TraitItemId ) {
143
+ self . check_nested_id ( id. owner_id . def_id ) ;
144
+ }
139
145
140
- fn visit_item ( & mut self , i : & ' hir hir:: Item < ' hir > ) {
141
- let mut inner_visitor = self . new_visitor ( self . tcx ) ;
142
- inner_visitor. check ( i. owner_id , |this| intravisit:: walk_item ( this, i) ) ;
143
- }
146
+ fn visit_nested_impl_item ( & mut self , id : hir:: ImplItemId ) {
147
+ self . check_nested_id ( id. owner_id . def_id ) ;
148
+ }
144
149
145
- fn visit_id ( & mut self , hir_id : HirId ) {
146
- let owner = self . owner . expect ( "no owner" ) ;
150
+ fn visit_nested_foreign_item ( & mut self , id : hir:: ForeignItemId ) {
151
+ self . check_nested_id ( id. owner_id . def_id ) ;
152
+ }
147
153
148
- if owner != hir_id. owner {
149
- self . error ( || {
150
- format ! (
151
- "HirIdValidator: The recorded owner of {} is {} instead of {}" ,
152
- self . tcx. hir( ) . node_to_string( hir_id) ,
153
- self . tcx. hir( ) . def_path( hir_id. owner. def_id) . to_string_no_crate_verbose( ) ,
154
- self . tcx. hir( ) . def_path( owner. def_id) . to_string_no_crate_verbose( )
155
- )
156
- } ) ;
154
+ fn visit_item ( & mut self , i : & ' hir hir:: Item < ' hir > ) {
155
+ let mut inner_visitor = self . new_visitor ( self . tcx ) ;
156
+ inner_visitor. check ( i. owner_id , |this| intravisit:: walk_item ( this, i) ) ;
157
157
}
158
158
159
- self . hir_ids_seen . insert ( hir_id. local_id ) ;
160
- }
159
+ fn visit_id ( & mut self , hir_id : HirId ) {
160
+ let owner = self . owner . expect ( "no owner" ) ;
161
+
162
+ if owner != hir_id. owner {
163
+ self . error ( || {
164
+ format ! (
165
+ "HirIdValidator: The recorded owner of {} is {} instead of {}" ,
166
+ self . tcx. hir( ) . node_to_string( hir_id) ,
167
+ self . tcx. hir( ) . def_path( hir_id. owner. def_id) . to_string_no_crate_verbose( ) ,
168
+ self . tcx. hir( ) . def_path( owner. def_id) . to_string_no_crate_verbose( )
169
+ )
170
+ } ) ;
171
+ }
172
+
173
+ self . hir_ids_seen . insert ( hir_id. local_id ) ;
174
+ }
161
175
162
- fn visit_foreign_item ( & mut self , i : & ' hir hir:: ForeignItem < ' hir > ) {
163
- let mut inner_visitor = self . new_visitor ( self . tcx ) ;
164
- inner_visitor. check ( i. owner_id , |this| intravisit:: walk_foreign_item ( this, i) ) ;
165
- }
176
+ fn visit_foreign_item ( & mut self , i : & ' hir hir:: ForeignItem < ' hir > ) {
177
+ let mut inner_visitor = self . new_visitor ( self . tcx ) ;
178
+ inner_visitor. check ( i. owner_id , |this| intravisit:: walk_foreign_item ( this, i) ) ;
179
+ }
166
180
167
- fn visit_trait_item ( & mut self , i : & ' hir hir:: TraitItem < ' hir > ) {
168
- let mut inner_visitor = self . new_visitor ( self . tcx ) ;
169
- inner_visitor. check ( i. owner_id , |this| intravisit:: walk_trait_item ( this, i) ) ;
170
- }
181
+ fn visit_trait_item ( & mut self , i : & ' hir hir:: TraitItem < ' hir > ) {
182
+ let mut inner_visitor = self . new_visitor ( self . tcx ) ;
183
+ inner_visitor. check ( i. owner_id , |this| intravisit:: walk_trait_item ( this, i) ) ;
184
+ }
171
185
172
- fn visit_impl_item ( & mut self , i : & ' hir hir:: ImplItem < ' hir > ) {
173
- let mut inner_visitor = self . new_visitor ( self . tcx ) ;
174
- inner_visitor. check ( i. owner_id , |this| intravisit:: walk_impl_item ( this, i) ) ;
186
+ fn visit_impl_item ( & mut self , i : & ' hir hir:: ImplItem < ' hir > ) {
187
+ let mut inner_visitor = self . new_visitor ( self . tcx ) ;
188
+ inner_visitor. check ( i. owner_id , |this| intravisit:: walk_impl_item ( this, i) ) ;
189
+ }
175
190
}
176
191
}
0 commit comments