11use rustc_data_structures:: sync:: Lock ;
22use rustc_hir as hir;
3+ use rustc_hir:: def_id:: LocalDefId ;
34use rustc_hir:: intravisit;
45use rustc_hir:: { HirId , ItemLocalId } ;
56use rustc_index:: bit_set:: GrowableBitSet ;
6- use rustc_middle:: hir:: map:: Map ;
77use rustc_middle:: hir:: nested_filter;
8- use rustc_middle:: ty:: TyCtxt ;
8+ use rustc_middle:: ty:: { DefIdTree , TyCtxt } ;
99
1010pub fn check_crate ( tcx : TyCtxt < ' _ > ) {
1111 tcx. dep_graph . assert_ignored ( ) ;
@@ -17,11 +17,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
1717 #[ cfg( debug_assertions) ]
1818 {
1919 let errors = Lock :: new ( Vec :: new ( ) ) ;
20- let hir_map = tcx. hir ( ) ;
2120
22- hir_map . par_for_each_module ( |module_id| {
21+ tcx . hir ( ) . par_for_each_module ( |module_id| {
2322 let mut v = HirIdValidator {
24- hir_map ,
23+ tcx ,
2524 owner : None ,
2625 hir_ids_seen : Default :: default ( ) ,
2726 errors : & errors,
@@ -40,20 +39,15 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
4039}
4140
4241struct HirIdValidator < ' a , ' hir > {
43- hir_map : Map < ' hir > ,
42+ tcx : TyCtxt < ' hir > ,
4443 owner : Option < hir:: OwnerId > ,
4544 hir_ids_seen : GrowableBitSet < ItemLocalId > ,
4645 errors : & ' a Lock < Vec < String > > ,
4746}
4847
4948impl < ' 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 }
5751 }
5852
5953 #[ cold]
@@ -96,36 +90,69 @@ impl<'a, 'hir> HirIdValidator<'a, 'hir> {
9690 missing_items. push ( format ! (
9791 "[local_id: {}, owner: {}]" ,
9892 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( )
10094 ) ) ;
10195 }
10296 self . error ( || {
10397 format ! (
10498 "ItemLocalIds not assigned densely in {}. \
10599 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( ) ,
107101 max,
108102 missing_items,
109103 self . hir_ids_seen
110104 . iter( )
111105 . 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) ) )
113107 . collect:: <Vec <_>>( )
114108 )
115109 } ) ;
116110 }
117111 }
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+ }
118129}
119130
120131impl < ' a , ' hir > intravisit:: Visitor < ' hir > for HirIdValidator < ' a , ' hir > {
121132 type NestedFilter = nested_filter:: OnlyBodies ;
122133
123134 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 ) ;
125152 }
126153
127154 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 ) ;
129156 inner_visitor. check ( i. owner_id , |this| intravisit:: walk_item ( this, i) ) ;
130157 }
131158
@@ -136,9 +163,9 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
136163 self . error ( || {
137164 format ! (
138165 "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( )
142169 )
143170 } ) ;
144171 }
@@ -147,17 +174,17 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
147174 }
148175
149176 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 ) ;
151178 inner_visitor. check ( i. owner_id , |this| intravisit:: walk_foreign_item ( this, i) ) ;
152179 }
153180
154181 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 ) ;
156183 inner_visitor. check ( i. owner_id , |this| intravisit:: walk_trait_item ( this, i) ) ;
157184 }
158185
159186 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 ) ;
161188 inner_visitor. check ( i. owner_id , |this| intravisit:: walk_impl_item ( this, i) ) ;
162189 }
163190}
0 commit comments