@@ -88,8 +88,9 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext,
88
88
rbml_w. writer. seek( SeekFrom :: Current ( 0 ) ) ) ;
89
89
90
90
// Folding could be avoided with a smarter encoder.
91
- let ii = simplify_ast ( ii) ;
91
+ let ( ii , expected_id_range ) = simplify_ast ( ii) ;
92
92
let id_range = inlined_item_id_range ( & ii) ;
93
+ assert_eq ! ( expected_id_range, id_range) ;
93
94
94
95
rbml_w. start_tag ( c:: tag_ast as usize ) ;
95
96
id_range. encode ( rbml_w) ;
@@ -186,6 +187,10 @@ impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> {
186
187
pub fn tr_id ( & self , id : ast:: NodeId ) -> ast:: NodeId {
187
188
// from_id_range should be non-empty
188
189
assert ! ( !self . from_id_range. empty( ) ) ;
190
+ // Make sure that translating the NodeId will actually yield a
191
+ // meaningful result
192
+ assert ! ( self . from_id_range. contains( id) ) ;
193
+
189
194
// Use wrapping arithmetic because otherwise it introduces control flow.
190
195
// Maybe we should just have the control flow? -- aatch
191
196
( id. wrapping_sub ( self . from_id_range . min ) . wrapping_add ( self . to_id_range . min ) )
@@ -279,9 +284,23 @@ fn encode_ast(rbml_w: &mut Encoder, item: &InlinedItem) {
279
284
rbml_w. end_tag ( ) ;
280
285
}
281
286
282
- struct NestedItemsDropper ;
287
+ struct NestedItemsDropper {
288
+ id_range : IdRange
289
+ }
283
290
284
291
impl Folder for NestedItemsDropper {
292
+
293
+ // The unit tests below run on HIR with NodeIds not properly assigned. That
294
+ // causes an integer overflow. So we just don't track the id_range when
295
+ // building the unit tests.
296
+ #[ cfg( not( test) ) ]
297
+ fn new_id ( & mut self , id : ast:: NodeId ) -> ast:: NodeId {
298
+ // Record the range of NodeIds we are visiting, so we can do a sanity
299
+ // check later
300
+ self . id_range . add ( id) ;
301
+ id
302
+ }
303
+
285
304
fn fold_block ( & mut self , blk : P < hir:: Block > ) -> P < hir:: Block > {
286
305
blk. and_then ( |hir:: Block { id, stmts, expr, rules, span, ..} | {
287
306
let stmts_sans_items = stmts. into_iter ( ) . filter_map ( |stmt| {
@@ -322,10 +341,12 @@ impl Folder for NestedItemsDropper {
322
341
// As it happens, trans relies on the fact that we do not export
323
342
// nested items, as otherwise it would get confused when translating
324
343
// inlined items.
325
- fn simplify_ast ( ii : InlinedItemRef ) -> InlinedItem {
326
- let mut fld = NestedItemsDropper ;
344
+ fn simplify_ast ( ii : InlinedItemRef ) -> ( InlinedItem , IdRange ) {
345
+ let mut fld = NestedItemsDropper {
346
+ id_range : IdRange :: max ( )
347
+ } ;
327
348
328
- match ii {
349
+ let ii = match ii {
329
350
// HACK we're not dropping items.
330
351
InlinedItemRef :: Item ( i) => {
331
352
InlinedItem :: Item ( P ( fold:: noop_fold_item ( i. clone ( ) , & mut fld) ) )
@@ -339,7 +360,9 @@ fn simplify_ast(ii: InlinedItemRef) -> InlinedItem {
339
360
InlinedItemRef :: Foreign ( i) => {
340
361
InlinedItem :: Foreign ( P ( fold:: noop_fold_foreign_item ( i. clone ( ) , & mut fld) ) )
341
362
}
342
- }
363
+ } ;
364
+
365
+ ( ii, fld. id_range )
343
366
}
344
367
345
368
fn decode_ast ( item_doc : rbml:: Doc ) -> InlinedItem {
@@ -361,8 +384,18 @@ impl tr for Def {
361
384
match * self {
362
385
Def :: Fn ( did) => Def :: Fn ( did. tr ( dcx) ) ,
363
386
Def :: Method ( did) => Def :: Method ( did. tr ( dcx) ) ,
364
- Def :: SelfTy ( opt_did, impl_id) => { Def :: SelfTy ( opt_did. map ( |did| did. tr ( dcx) ) ,
365
- impl_id. map ( |id| dcx. tr_id ( id) ) ) }
387
+ Def :: SelfTy ( opt_did, impl_id) => {
388
+ // Since the impl_id will never lie within the reserved range of
389
+ // imported NodeIds, it does not make sense to translate it.
390
+ // The result would not make any sense within the importing crate.
391
+ // We also don't allow for impl items to be inlined (just their
392
+ // members), so even if we had a DefId here, we wouldn't be able
393
+ // to do much with it.
394
+ // So, we set the id to DUMMY_NODE_ID. That way we make it
395
+ // explicit that this is no usable NodeId.
396
+ Def :: SelfTy ( opt_did. map ( |did| did. tr ( dcx) ) ,
397
+ impl_id. map ( |_| ast:: DUMMY_NODE_ID ) )
398
+ }
366
399
Def :: Mod ( did) => { Def :: Mod ( did. tr ( dcx) ) }
367
400
Def :: ForeignMod ( did) => { Def :: ForeignMod ( did. tr ( dcx) ) }
368
401
Def :: Static ( did, m) => { Def :: Static ( did. tr ( dcx) , m) }
@@ -1361,7 +1394,7 @@ fn test_simplification() {
1361
1394
with_testing_context ( |lcx| {
1362
1395
let hir_item = lcx. lower_item ( & item) ;
1363
1396
let item_in = InlinedItemRef :: Item ( & hir_item) ;
1364
- let item_out = simplify_ast ( item_in) ;
1397
+ let ( item_out, _ ) = simplify_ast ( item_in) ;
1365
1398
let item_exp = InlinedItem :: Item ( P ( lcx. lower_item ( & quote_item ! ( & cx,
1366
1399
fn new_int_alist<B >( ) -> alist<isize , B > {
1367
1400
return alist { eq_fn: eq_int, data: Vec :: new( ) } ;
0 commit comments