@@ -212,7 +212,7 @@ pub struct CommonTypes<'tcx> {
212
212
}
213
213
214
214
pub struct LocalTableInContext < ' a , V : ' a > {
215
- local_id_root : DefId ,
215
+ local_id_root : Option < DefId > ,
216
216
data : & ' a ItemLocalMap < V >
217
217
}
218
218
@@ -223,11 +223,13 @@ pub struct LocalTableInContext<'a, V: 'a> {
223
223
/// would be in a different frame of reference and using its `local_id`
224
224
/// would result in lookup errors, or worse, in silently wrong data being
225
225
/// 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 ) {
227
229
#[ cfg( debug_assertions) ]
228
230
{
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 {
231
233
ty:: tls:: with ( |tcx| {
232
234
let node_id = tcx. hir
233
235
. definitions ( )
@@ -237,21 +239,30 @@ fn validate_hir_id_for_typeck_tables(table_id_root: DefId, hir_id: hir::HirId) {
237
239
TypeckTables with local_id_root {:?}",
238
240
tcx. hir. node_to_string( node_id) ,
239
241
DefId :: local( hir_id. owner) ,
240
- table_id_root )
242
+ local_id_root )
241
243
} ) ;
242
244
}
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
+ }
243
254
}
244
255
}
245
256
}
246
257
247
258
impl < ' a , V > LocalTableInContext < ' a , V > {
248
259
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 ) ;
250
261
self . data . contains_key ( & id. local_id )
251
262
}
252
263
253
264
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 ) ;
255
266
self . data . get ( & id. local_id )
256
267
}
257
268
@@ -269,37 +280,37 @@ impl<'a, V> ::std::ops::Index<hir::HirId> for LocalTableInContext<'a, V> {
269
280
}
270
281
271
282
pub struct LocalTableInContextMut < ' a , V : ' a > {
272
- local_id_root : DefId ,
283
+ local_id_root : Option < DefId > ,
273
284
data : & ' a mut ItemLocalMap < V >
274
285
}
275
286
276
287
impl < ' a , V > LocalTableInContextMut < ' a , V > {
277
288
278
289
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 ) ;
280
291
self . data . get_mut ( & id. local_id )
281
292
}
282
293
283
294
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 ) ;
285
296
self . data . entry ( id. local_id )
286
297
}
287
298
288
299
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 ) ;
290
301
self . data . insert ( id. local_id , val)
291
302
}
292
303
293
304
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 ) ;
295
306
self . data . remove ( & id. local_id )
296
307
}
297
308
}
298
309
299
310
#[ derive( RustcEncodable , RustcDecodable ) ]
300
311
pub struct TypeckTables < ' tcx > {
301
312
/// The HirId::owner all ItemLocalIds in this table are relative to.
302
- pub local_id_root : DefId ,
313
+ pub local_id_root : Option < DefId > ,
303
314
304
315
/// Resolved definitions for `<T>::X` associated paths and
305
316
/// method calls, including those of overloaded operators.
@@ -363,7 +374,7 @@ pub struct TypeckTables<'tcx> {
363
374
}
364
375
365
376
impl < ' tcx > TypeckTables < ' tcx > {
366
- pub fn empty ( local_id_root : DefId ) -> TypeckTables < ' tcx > {
377
+ pub fn empty ( local_id_root : Option < DefId > ) -> TypeckTables < ' tcx > {
367
378
TypeckTables {
368
379
local_id_root,
369
380
type_dependent_defs : ItemLocalMap ( ) ,
@@ -388,7 +399,7 @@ impl<'tcx> TypeckTables<'tcx> {
388
399
match * qpath {
389
400
hir:: QPath :: Resolved ( _, ref path) => path. def ,
390
401
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 ) ;
392
403
self . type_dependent_defs . get ( & id. local_id ) . cloned ( ) . unwrap_or ( Def :: Err )
393
404
}
394
405
}
@@ -436,7 +447,7 @@ impl<'tcx> TypeckTables<'tcx> {
436
447
}
437
448
438
449
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 ) ;
440
451
self . node_types . get ( & id. local_id ) . cloned ( )
441
452
}
442
453
@@ -448,12 +459,12 @@ impl<'tcx> TypeckTables<'tcx> {
448
459
}
449
460
450
461
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 ) ;
452
463
self . node_substs . get ( & id. local_id ) . cloned ( ) . unwrap_or ( Substs :: empty ( ) )
453
464
}
454
465
455
466
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 ) ;
457
468
self . node_substs . get ( & id. local_id ) . cloned ( )
458
469
}
459
470
@@ -502,7 +513,7 @@ impl<'tcx> TypeckTables<'tcx> {
502
513
503
514
pub fn expr_adjustments ( & self , expr : & hir:: Expr )
504
515
-> & [ 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 ) ;
506
517
self . adjustments . get ( & expr. hir_id . local_id ) . map_or ( & [ ] , |a| & a[ ..] )
507
518
}
508
519
@@ -663,6 +674,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Typeck
663
674
closure_expr_id
664
675
} = * up_var_id;
665
676
677
+ let local_id_root =
678
+ local_id_root. expect ( "trying to hash invalid TypeckTables" ) ;
679
+
666
680
let var_def_id = DefId {
667
681
krate : local_id_root. krate ,
668
682
index : var_id,
0 commit comments