@@ -212,7 +212,7 @@ pub struct CommonTypes<'tcx> {
212212}
213213
214214pub struct LocalTableInContext < ' a , V : ' a > {
215- local_id_root : DefId ,
215+ local_id_root : Option < DefId > ,
216216 data : & ' a ItemLocalMap < V >
217217}
218218
@@ -223,11 +223,13 @@ pub struct LocalTableInContext<'a, V: 'a> {
223223/// would be in a different frame of reference and using its `local_id`
224224/// would result in lookup errors, or worse, in silently wrong data being
225225/// stored/returned.
226- fn validate_hir_id_for_typeck_tables ( table_id_root : DefId , hir_id : hir:: HirId ) {
226+ fn validate_hir_id_for_typeck_tables ( local_id_root : Option < DefId > ,
227+ hir_id : hir:: HirId ,
228+ mut_access : bool ) {
227229 #[ cfg( debug_assertions) ]
228230 {
229- if table_id_root . is_local ( ) {
230- if hir_id. owner != table_id_root . index {
231+ if let Some ( local_id_root ) = local_id_root {
232+ if hir_id. owner != local_id_root . index {
231233 ty:: tls:: with ( |tcx| {
232234 let node_id = tcx. hir
233235 . definitions ( )
@@ -237,21 +239,30 @@ fn validate_hir_id_for_typeck_tables(table_id_root: DefId, hir_id: hir::HirId) {
237239 TypeckTables with local_id_root {:?}",
238240 tcx. hir. node_to_string( node_id) ,
239241 DefId :: local( hir_id. owner) ,
240- table_id_root )
242+ local_id_root )
241243 } ) ;
242244 }
245+ } else {
246+ // We use "Null Object" TypeckTables in some of the analysis passes.
247+ // These are just expected to be empty and their `local_id_root` is
248+ // `None`. Therefore we cannot verify whether a given `HirId` would
249+ // be a valid key for the given table. Instead we make sure that
250+ // nobody tries to write to such a Null Object table.
251+ if mut_access {
252+ bug ! ( "access to invalid TypeckTables" )
253+ }
243254 }
244255 }
245256}
246257
247258impl < ' a , V > LocalTableInContext < ' a , V > {
248259 pub fn contains_key ( & self , id : hir:: HirId ) -> bool {
249- validate_hir_id_for_typeck_tables ( self . local_id_root , id) ;
260+ validate_hir_id_for_typeck_tables ( self . local_id_root , id, false ) ;
250261 self . data . contains_key ( & id. local_id )
251262 }
252263
253264 pub fn get ( & self , id : hir:: HirId ) -> Option < & V > {
254- validate_hir_id_for_typeck_tables ( self . local_id_root , id) ;
265+ validate_hir_id_for_typeck_tables ( self . local_id_root , id, false ) ;
255266 self . data . get ( & id. local_id )
256267 }
257268
@@ -269,37 +280,37 @@ impl<'a, V> ::std::ops::Index<hir::HirId> for LocalTableInContext<'a, V> {
269280}
270281
271282pub struct LocalTableInContextMut < ' a , V : ' a > {
272- local_id_root : DefId ,
283+ local_id_root : Option < DefId > ,
273284 data : & ' a mut ItemLocalMap < V >
274285}
275286
276287impl < ' a , V > LocalTableInContextMut < ' a , V > {
277288
278289 pub fn get_mut ( & mut self , id : hir:: HirId ) -> Option < & mut V > {
279- validate_hir_id_for_typeck_tables ( self . local_id_root , id) ;
290+ validate_hir_id_for_typeck_tables ( self . local_id_root , id, true ) ;
280291 self . data . get_mut ( & id. local_id )
281292 }
282293
283294 pub fn entry ( & mut self , id : hir:: HirId ) -> Entry < hir:: ItemLocalId , V > {
284- validate_hir_id_for_typeck_tables ( self . local_id_root , id) ;
295+ validate_hir_id_for_typeck_tables ( self . local_id_root , id, true ) ;
285296 self . data . entry ( id. local_id )
286297 }
287298
288299 pub fn insert ( & mut self , id : hir:: HirId , val : V ) -> Option < V > {
289- validate_hir_id_for_typeck_tables ( self . local_id_root , id) ;
300+ validate_hir_id_for_typeck_tables ( self . local_id_root , id, true ) ;
290301 self . data . insert ( id. local_id , val)
291302 }
292303
293304 pub fn remove ( & mut self , id : hir:: HirId ) -> Option < V > {
294- validate_hir_id_for_typeck_tables ( self . local_id_root , id) ;
305+ validate_hir_id_for_typeck_tables ( self . local_id_root , id, true ) ;
295306 self . data . remove ( & id. local_id )
296307 }
297308}
298309
299310#[ derive( RustcEncodable , RustcDecodable ) ]
300311pub struct TypeckTables < ' tcx > {
301312 /// The HirId::owner all ItemLocalIds in this table are relative to.
302- pub local_id_root : DefId ,
313+ pub local_id_root : Option < DefId > ,
303314
304315 /// Resolved definitions for `<T>::X` associated paths and
305316 /// method calls, including those of overloaded operators.
@@ -363,7 +374,7 @@ pub struct TypeckTables<'tcx> {
363374}
364375
365376impl < ' tcx > TypeckTables < ' tcx > {
366- pub fn empty ( local_id_root : DefId ) -> TypeckTables < ' tcx > {
377+ pub fn empty ( local_id_root : Option < DefId > ) -> TypeckTables < ' tcx > {
367378 TypeckTables {
368379 local_id_root,
369380 type_dependent_defs : ItemLocalMap ( ) ,
@@ -388,7 +399,7 @@ impl<'tcx> TypeckTables<'tcx> {
388399 match * qpath {
389400 hir:: QPath :: Resolved ( _, ref path) => path. def ,
390401 hir:: QPath :: TypeRelative ( ..) => {
391- validate_hir_id_for_typeck_tables ( self . local_id_root , id) ;
402+ validate_hir_id_for_typeck_tables ( self . local_id_root , id, false ) ;
392403 self . type_dependent_defs . get ( & id. local_id ) . cloned ( ) . unwrap_or ( Def :: Err )
393404 }
394405 }
@@ -436,7 +447,7 @@ impl<'tcx> TypeckTables<'tcx> {
436447 }
437448
438449 pub fn node_id_to_type_opt ( & self , id : hir:: HirId ) -> Option < Ty < ' tcx > > {
439- validate_hir_id_for_typeck_tables ( self . local_id_root , id) ;
450+ validate_hir_id_for_typeck_tables ( self . local_id_root , id, false ) ;
440451 self . node_types . get ( & id. local_id ) . cloned ( )
441452 }
442453
@@ -448,12 +459,12 @@ impl<'tcx> TypeckTables<'tcx> {
448459 }
449460
450461 pub fn node_substs ( & self , id : hir:: HirId ) -> & ' tcx Substs < ' tcx > {
451- validate_hir_id_for_typeck_tables ( self . local_id_root , id) ;
462+ validate_hir_id_for_typeck_tables ( self . local_id_root , id, false ) ;
452463 self . node_substs . get ( & id. local_id ) . cloned ( ) . unwrap_or ( Substs :: empty ( ) )
453464 }
454465
455466 pub fn node_substs_opt ( & self , id : hir:: HirId ) -> Option < & ' tcx Substs < ' tcx > > {
456- validate_hir_id_for_typeck_tables ( self . local_id_root , id) ;
467+ validate_hir_id_for_typeck_tables ( self . local_id_root , id, false ) ;
457468 self . node_substs . get ( & id. local_id ) . cloned ( )
458469 }
459470
@@ -502,7 +513,7 @@ impl<'tcx> TypeckTables<'tcx> {
502513
503514 pub fn expr_adjustments ( & self , expr : & hir:: Expr )
504515 -> & [ ty:: adjustment:: Adjustment < ' tcx > ] {
505- validate_hir_id_for_typeck_tables ( self . local_id_root , expr. hir_id ) ;
516+ validate_hir_id_for_typeck_tables ( self . local_id_root , expr. hir_id , false ) ;
506517 self . adjustments . get ( & expr. hir_id . local_id ) . map_or ( & [ ] , |a| & a[ ..] )
507518 }
508519
@@ -663,6 +674,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Typeck
663674 closure_expr_id
664675 } = * up_var_id;
665676
677+ let local_id_root =
678+ local_id_root. expect ( "trying to hash invalid TypeckTables" ) ;
679+
666680 let var_def_id = DefId {
667681 krate : local_id_root. krate ,
668682 index : var_id,
0 commit comments