1
1
use rustc_data_structures:: sync:: Lock ;
2
2
use rustc_hir as hir;
3
+ use rustc_hir:: def_id:: LocalDefId ;
3
4
use rustc_hir:: intravisit;
4
5
use rustc_hir:: { HirId , ItemLocalId } ;
5
6
use rustc_index:: bit_set:: GrowableBitSet ;
6
- use rustc_middle:: hir:: map:: Map ;
7
7
use rustc_middle:: hir:: nested_filter;
8
- use rustc_middle:: ty:: TyCtxt ;
8
+ use rustc_middle:: ty:: { DefIdTree , TyCtxt } ;
9
9
10
10
pub fn check_crate ( tcx : TyCtxt < ' _ > ) {
11
11
tcx. dep_graph . assert_ignored ( ) ;
@@ -17,11 +17,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
17
17
#[ cfg( debug_assertions) ]
18
18
{
19
19
let errors = Lock :: new ( Vec :: new ( ) ) ;
20
- let hir_map = tcx. hir ( ) ;
21
20
22
- hir_map . par_for_each_module ( |module_id| {
21
+ tcx . hir ( ) . par_for_each_module ( |module_id| {
23
22
let mut v = HirIdValidator {
24
- hir_map ,
23
+ tcx ,
25
24
owner : None ,
26
25
hir_ids_seen : Default :: default ( ) ,
27
26
errors : & errors,
@@ -40,20 +39,15 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
40
39
}
41
40
42
41
struct HirIdValidator < ' a , ' hir > {
43
- hir_map : Map < ' hir > ,
42
+ tcx : TyCtxt < ' hir > ,
44
43
owner : Option < hir:: OwnerId > ,
45
44
hir_ids_seen : GrowableBitSet < ItemLocalId > ,
46
45
errors : & ' a Lock < Vec < String > > ,
47
46
}
48
47
49
48
impl < ' a , ' hir > HirIdValidator < ' a , ' hir > {
50
- fn new_visitor ( & self , hir_map : Map < ' hir > ) -> HirIdValidator < ' a , ' hir > {
51
- HirIdValidator {
52
- hir_map,
53
- owner : None ,
54
- hir_ids_seen : Default :: default ( ) ,
55
- errors : self . errors ,
56
- }
49
+ fn new_visitor ( & self , tcx : TyCtxt < ' hir > ) -> HirIdValidator < ' a , ' hir > {
50
+ HirIdValidator { tcx, owner : None , hir_ids_seen : Default :: default ( ) , errors : self . errors }
57
51
}
58
52
59
53
#[ cold]
@@ -96,36 +90,69 @@ impl<'a, 'hir> HirIdValidator<'a, 'hir> {
96
90
missing_items. push ( format ! (
97
91
"[local_id: {}, owner: {}]" ,
98
92
local_id,
99
- self . hir_map . def_path( owner. def_id) . to_string_no_crate_verbose( )
93
+ self . tcx . hir ( ) . def_path( owner. def_id) . to_string_no_crate_verbose( )
100
94
) ) ;
101
95
}
102
96
self . error ( || {
103
97
format ! (
104
98
"ItemLocalIds not assigned densely in {}. \
105
99
Max ItemLocalId = {}, missing IDs = {:#?}; seens IDs = {:#?}",
106
- self . hir_map . def_path( owner. def_id) . to_string_no_crate_verbose( ) ,
100
+ self . tcx . hir ( ) . def_path( owner. def_id) . to_string_no_crate_verbose( ) ,
107
101
max,
108
102
missing_items,
109
103
self . hir_ids_seen
110
104
. iter( )
111
105
. map( |local_id| HirId { owner, local_id } )
112
- . map( |h| format!( "({:?} {})" , h, self . hir_map . node_to_string( h) ) )
106
+ . map( |h| format!( "({:?} {})" , h, self . tcx . hir ( ) . node_to_string( h) ) )
113
107
. collect:: <Vec <_>>( )
114
108
)
115
109
} ) ;
116
110
}
117
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
+ }
128
+ }
118
129
}
119
130
120
131
impl < ' a , ' hir > intravisit:: Visitor < ' hir > for HirIdValidator < ' a , ' hir > {
121
132
type NestedFilter = nested_filter:: OnlyBodies ;
122
133
123
134
fn nested_visit_map ( & mut self ) -> Self :: Map {
124
- self . hir_map
135
+ self . tcx . hir ( )
136
+ }
137
+
138
+ fn visit_nested_item ( & mut self , id : hir:: ItemId ) {
139
+ self . check_nested_id ( id. owner_id . def_id ) ;
140
+ }
141
+
142
+ fn visit_nested_trait_item ( & mut self , id : hir:: TraitItemId ) {
143
+ self . check_nested_id ( id. owner_id . def_id ) ;
144
+ }
145
+
146
+ fn visit_nested_impl_item ( & mut self , id : hir:: ImplItemId ) {
147
+ self . check_nested_id ( id. owner_id . def_id ) ;
148
+ }
149
+
150
+ fn visit_nested_foreign_item ( & mut self , id : hir:: ForeignItemId ) {
151
+ self . check_nested_id ( id. owner_id . def_id ) ;
125
152
}
126
153
127
154
fn visit_item ( & mut self , i : & ' hir hir:: Item < ' hir > ) {
128
- let mut inner_visitor = self . new_visitor ( self . hir_map ) ;
155
+ let mut inner_visitor = self . new_visitor ( self . tcx ) ;
129
156
inner_visitor. check ( i. owner_id , |this| intravisit:: walk_item ( this, i) ) ;
130
157
}
131
158
@@ -136,9 +163,9 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
136
163
self . error ( || {
137
164
format ! (
138
165
"HirIdValidator: The recorded owner of {} is {} instead of {}" ,
139
- self . hir_map . node_to_string( hir_id) ,
140
- self . hir_map . def_path( hir_id. owner. def_id) . to_string_no_crate_verbose( ) ,
141
- self . hir_map . def_path( owner. def_id) . to_string_no_crate_verbose( )
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( )
142
169
)
143
170
} ) ;
144
171
}
@@ -147,17 +174,17 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
147
174
}
148
175
149
176
fn visit_foreign_item ( & mut self , i : & ' hir hir:: ForeignItem < ' hir > ) {
150
- let mut inner_visitor = self . new_visitor ( self . hir_map ) ;
177
+ let mut inner_visitor = self . new_visitor ( self . tcx ) ;
151
178
inner_visitor. check ( i. owner_id , |this| intravisit:: walk_foreign_item ( this, i) ) ;
152
179
}
153
180
154
181
fn visit_trait_item ( & mut self , i : & ' hir hir:: TraitItem < ' hir > ) {
155
- let mut inner_visitor = self . new_visitor ( self . hir_map ) ;
182
+ let mut inner_visitor = self . new_visitor ( self . tcx ) ;
156
183
inner_visitor. check ( i. owner_id , |this| intravisit:: walk_trait_item ( this, i) ) ;
157
184
}
158
185
159
186
fn visit_impl_item ( & mut self , i : & ' hir hir:: ImplItem < ' hir > ) {
160
- let mut inner_visitor = self . new_visitor ( self . hir_map ) ;
187
+ let mut inner_visitor = self . new_visitor ( self . tcx ) ;
161
188
inner_visitor. check ( i. owner_id , |this| intravisit:: walk_impl_item ( this, i) ) ;
162
189
}
163
190
}
0 commit comments