Skip to content

Commit 21205f4

Browse files
committed
Cache ids between lowering runs
So that lowering is reproducible
1 parent ce80094 commit 21205f4

File tree

7 files changed

+86
-24
lines changed

7 files changed

+86
-24
lines changed

src/librustc/session/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,10 @@ impl NodeIdAssigner for Session {
318318
fn next_node_id(&self) -> NodeId {
319319
self.reserve_node_ids(1)
320320
}
321+
322+
fn peek_node_id(&self) -> NodeId {
323+
self.next_node_id.get().checked_add(1).unwrap()
324+
}
321325
}
322326

323327
fn split_msg_into_multilines(msg: &str) -> Option<String> {

src/librustc_driver/driver.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,7 @@ pub fn compile_input(sess: Session,
112112

113113
let expanded_crate = assign_node_ids(&sess, expanded_crate);
114114
// Lower ast -> hir.
115-
let foo = &42;
116-
let lcx = LoweringContext::new(foo, &sess, &expanded_crate);
115+
let lcx = LoweringContext::new(&sess, &expanded_crate);
117116
let mut hir_forest = time(sess.time_passes(),
118117
"lowering ast -> hir",
119118
|| hir_map::Forest::new(lower_crate(&lcx, &expanded_crate)));
@@ -282,7 +281,7 @@ pub struct CompileState<'a, 'ast: 'a, 'tcx: 'a> {
282281
pub ast_map: Option<&'a hir_map::Map<'ast>>,
283282
pub analysis: Option<&'a ty::CrateAnalysis>,
284283
pub tcx: Option<&'a ty::ctxt<'tcx>>,
285-
pub lcx: Option<&'a LoweringContext<'a, 'tcx>>,
284+
pub lcx: Option<&'a LoweringContext<'a>>,
286285
pub trans: Option<&'a trans::CrateTranslation>,
287286
}
288287

@@ -340,7 +339,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
340339
krate: &'a ast::Crate,
341340
hir_crate: &'a hir::Crate,
342341
crate_name: &'a str,
343-
lcx: &'a LoweringContext<'a, 'tcx>)
342+
lcx: &'a LoweringContext<'a>)
344343
-> CompileState<'a, 'ast, 'tcx> {
345344
CompileState {
346345
crate_name: Some(crate_name),
@@ -359,7 +358,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
359358
hir_crate: &'a hir::Crate,
360359
analysis: &'a ty::CrateAnalysis,
361360
tcx: &'a ty::ctxt<'tcx>,
362-
lcx: &'a LoweringContext<'a, 'tcx>)
361+
lcx: &'a LoweringContext<'a>)
363362
-> CompileState<'a, 'ast, 'tcx> {
364363
CompileState {
365364
analysis: Some(analysis),

src/librustc_driver/pretty.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -670,8 +670,7 @@ pub fn pretty_print_input(sess: Session,
670670
// There is some twisted, god-forsaken tangle of lifetimes here which makes
671671
// the ordering of stuff super-finicky.
672672
let mut hir_forest;
673-
let foo = &42;
674-
let lcx = LoweringContext::new(foo, &sess, &krate);
673+
let lcx = LoweringContext::new(&sess, &krate);
675674
let arenas = ty::CtxtArenas::new();
676675
let ast_map = if compute_ast_map {
677676
hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate));

src/librustc_front/lowering.rs

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,26 @@
1212

1313
use hir;
1414

15+
use std::collections::HashMap;
16+
1517
use syntax::ast::*;
1618
use syntax::ptr::P;
1719
use syntax::codemap::{respan, Spanned, Span};
1820
use syntax::owned_slice::OwnedSlice;
1921
use syntax::parse::token::{self, str_to_ident};
2022
use syntax::std_inject;
2123

22-
pub struct LoweringContext<'a, 'hir> {
23-
// TODO
24-
foo: &'hir i32,
25-
id_assigner: &'a NodeIdAssigner,
24+
use std::cell::{Cell, RefCell};
25+
26+
pub struct LoweringContext<'a> {
2627
crate_root: Option<&'static str>,
28+
id_cache: RefCell<HashMap<NodeId, NodeId>>,
29+
id_assigner: &'a NodeIdAssigner,
30+
cached_id: Cell<u32>,
2731
}
2832

29-
impl<'a, 'hir> LoweringContext<'a, 'hir> {
30-
pub fn new(foo: &'hir i32, id_assigner: &'a NodeIdAssigner, c: &Crate) -> LoweringContext<'a, 'hir> {
33+
impl<'a, 'hir> LoweringContext<'a> {
34+
pub fn new(id_assigner: &'a NodeIdAssigner, c: &Crate) -> LoweringContext<'a> {
3135
let crate_root = if std_inject::no_core(c) {
3236
None
3337
} else if std_inject::no_std(c) {
@@ -37,14 +41,21 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
3741
};
3842

3943
LoweringContext {
40-
foo: foo,
41-
id_assigner: id_assigner,
4244
crate_root: crate_root,
45+
id_cache: RefCell::new(HashMap::new()),
46+
id_assigner: id_assigner,
47+
cached_id: Cell::new(0),
4348
}
4449
}
4550

4651
fn next_id(&self) -> NodeId {
47-
self.id_assigner.next_node_id()
52+
let cached = self.cached_id.get();
53+
if cached == 0 {
54+
return self.id_assigner.next_node_id()
55+
}
56+
57+
self.cached_id.set(cached + 1);
58+
cached
4859
}
4960
}
5061

@@ -745,6 +756,49 @@ pub fn lower_pat(_lctx: &LoweringContext, p: &Pat) -> P<hir::Pat> {
745756
})
746757
}
747758

759+
// RAII utility for setting and unsetting the cached id.
760+
struct CachedIdSetter<'a> {
761+
reset: bool,
762+
lctx: &'a LoweringContext<'a>,
763+
}
764+
765+
impl<'a> CachedIdSetter<'a> {
766+
fn new(lctx: &'a LoweringContext, expr_id: NodeId) -> CachedIdSetter<'a> {
767+
let id_cache: &mut HashMap<_, _> = &mut lctx.id_cache.borrow_mut();
768+
769+
if id_cache.contains_key(&expr_id) {
770+
let cached_id = lctx.cached_id.get();
771+
if cached_id == 0 {
772+
// We're entering a node where we need to track ids, but are not
773+
// yet tracking.
774+
lctx.cached_id.set(id_cache[&expr_id]);
775+
} else {
776+
// We're already tracking - check that the tracked id is the same
777+
// as the expected id.
778+
assert!(cached_id == id_cache[&expr_id], "id mismatch");
779+
}
780+
} else {
781+
id_cache.insert(expr_id, lctx.id_assigner.peek_node_id());
782+
}
783+
784+
CachedIdSetter {
785+
// Only reset the id if it was previously 0, i.e., was not cached.
786+
// If it was cached, we are in a nested node, but our id count will
787+
// still count towards the parent's count.
788+
reset: lctx.cached_id.get() == 0,
789+
lctx: lctx,
790+
}
791+
}
792+
}
793+
794+
impl<'a> Drop for CachedIdSetter<'a> {
795+
fn drop(&mut self) {
796+
if self.reset {
797+
self.lctx.cached_id.set(0);
798+
}
799+
}
800+
}
801+
748802
pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
749803
P(hir::Expr {
750804
id: e.id,
@@ -780,9 +834,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
780834
// std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
781835
// InPlace::finalize(place)
782836
// })
783-
784-
// TODO
785-
println!("{}", lctx.foo);
837+
let _old_cached = CachedIdSetter::new(lctx, e.id);
786838

787839
let placer_expr = lower_expr(lctx, placer);
788840
let value_expr = lower_expr(lctx, value_expr);
@@ -903,6 +955,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
903955
// might be `if let`.
904956
ExprIf(ref cond, ref blk, ref else_opt) => {
905957
let else_opt = else_opt.as_ref().map(|els| match els.node {
958+
let _old_cached = CachedIdSetter::new(lctx, e.id);
906959
ExprIfLet(..) => {
907960
// wrap the if-let expr in a block
908961
let span = els.span;
@@ -1019,6 +1072,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
10191072
// [_ if <else_opt_if_cond> => <else_opt_if_body>,]
10201073
// _ => [<else_opt> | ()]
10211074
// }
1075+
1076+
let _old_cached = CachedIdSetter::new(lctx, e.id);
10221077

10231078
// `<pat> => <body>`
10241079
let pat_arm = {
@@ -1098,6 +1153,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
10981153
// }
10991154
// }
11001155

1156+
let _old_cached = CachedIdSetter::new(lctx, e.id);
1157+
11011158
// `<pat> => <body>`
11021159
let pat_arm = {
11031160
let body_expr = expr_block(lctx, lower_block(lctx, body));
@@ -1141,6 +1198,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
11411198
// result
11421199
// }
11431200

1201+
let _old_cached = CachedIdSetter::new(lctx, e.id);
1202+
11441203
// expand <head>
11451204
let head = lower_expr(lctx, head);
11461205

src/librustc_trans/save/dump_csv.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ pub struct DumpCsvVisitor<'l, 'tcx: 'l> {
7676

7777
impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
7878
pub fn new(tcx: &'l ty::ctxt<'tcx>,
79-
lcx: &'l LoweringContext<'l, 'tcx>,
79+
lcx: &'l LoweringContext<'l>,
8080
analysis: &'l ty::CrateAnalysis,
8181
output_file: Box<File>)
8282
-> DumpCsvVisitor<'l, 'tcx> {

src/librustc_trans/save/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ mod dump_csv;
3838

3939
pub struct SaveContext<'l, 'tcx: 'l> {
4040
tcx: &'l ty::ctxt<'tcx>,
41-
lcx: &'l lowering::LoweringContext<'l, 'tcx>,
41+
lcx: &'l lowering::LoweringContext<'l>,
4242
span_utils: SpanUtils<'l>,
4343
}
4444

@@ -178,14 +178,14 @@ pub struct MethodCallData {
178178

179179
impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
180180
pub fn new(tcx: &'l ty::ctxt<'tcx>,
181-
lcx: &'l lowering::LoweringContext<'l, 'tcx>)
181+
lcx: &'l lowering::LoweringContext<'l>)
182182
-> SaveContext<'l, 'tcx> {
183183
let span_utils = SpanUtils::new(&tcx.sess);
184184
SaveContext::from_span_utils(tcx, lcx, span_utils)
185185
}
186186

187187
pub fn from_span_utils(tcx: &'l ty::ctxt<'tcx>,
188-
lcx: &'l lowering::LoweringContext<'l, 'tcx>,
188+
lcx: &'l lowering::LoweringContext<'l>,
189189
span_utils: SpanUtils<'l>)
190190
-> SaveContext<'l, 'tcx> {
191191
SaveContext {
@@ -711,7 +711,7 @@ impl<'v> Visitor<'v> for PathCollector {
711711
}
712712

713713
pub fn process_crate<'l, 'tcx>(tcx: &'l ty::ctxt<'tcx>,
714-
lcx: &'l lowering::LoweringContext<'l, 'tcx>,
714+
lcx: &'l lowering::LoweringContext<'l>,
715715
krate: &ast::Crate,
716716
analysis: &ty::CrateAnalysis,
717717
odir: Option<&Path>) {

src/libsyntax/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ pub const DUMMY_NODE_ID: NodeId = !0;
377377

378378
pub trait NodeIdAssigner {
379379
fn next_node_id(&self) -> NodeId;
380+
fn peek_node_id(&self) -> NodeId;
380381
}
381382

382383
/// The AST represents all type param bounds as types.

0 commit comments

Comments
 (0)