Skip to content

Commit 4349cda

Browse files
committed
Auto merge of #31037 - nrc:cached-ids, r=nikomatsakis
Blocks #30884 r? @nikomatsakis cc @durka
2 parents 51108b6 + 7ffd408 commit 4349cda

File tree

1 file changed

+61
-52
lines changed

1 file changed

+61
-52
lines changed

src/librustc_front/lowering.rs

+61-52
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ pub struct LoweringContext<'a> {
8787
cached_id: Cell<u32>,
8888
// Keep track of gensym'ed idents.
8989
gensym_cache: RefCell<HashMap<(NodeId, &'static str), hir::Ident>>,
90-
// A copy of cached_id, but is also set to an id while it is being cached.
90+
// A copy of cached_id, but is also set to an id while a node is lowered for
91+
// the first time.
9192
gensym_key: Cell<u32>,
9293
}
9394

@@ -114,32 +115,79 @@ impl<'a, 'hir> LoweringContext<'a> {
114115
}
115116

116117
fn next_id(&self) -> NodeId {
117-
let cached = self.cached_id.get();
118-
if cached == 0 {
118+
let cached_id = self.cached_id.get();
119+
if cached_id == 0 {
119120
return self.id_assigner.next_node_id();
120121
}
121122

122-
self.cached_id.set(cached + 1);
123-
cached
123+
self.cached_id.set(cached_id + 1);
124+
cached_id
124125
}
125126

126127
fn str_to_ident(&self, s: &'static str) -> hir::Ident {
127-
let cached_id = self.gensym_key.get();
128-
if cached_id == 0 {
128+
let gensym_key = self.gensym_key.get();
129+
if gensym_key == 0 {
129130
return hir::Ident::from_name(token::gensym(s));
130131
}
131132

132-
let cached = self.gensym_cache.borrow().contains_key(&(cached_id, s));
133+
let cached = self.gensym_cache.borrow().contains_key(&(gensym_key, s));
133134
if cached {
134-
self.gensym_cache.borrow()[&(cached_id, s)]
135+
self.gensym_cache.borrow()[&(gensym_key, s)]
135136
} else {
136137
let result = hir::Ident::from_name(token::gensym(s));
137-
self.gensym_cache.borrow_mut().insert((cached_id, s), result);
138+
self.gensym_cache.borrow_mut().insert((gensym_key, s), result);
138139
result
139140
}
140141
}
141142
}
142143

144+
// Utility fn for setting and unsetting the cached id.
145+
fn cache_ids<'a, OP, R>(lctx: &LoweringContext, expr_id: NodeId, op: OP) -> R
146+
where OP: FnOnce(&LoweringContext) -> R
147+
{
148+
// Only reset the id if it was previously 0, i.e., was not cached.
149+
// If it was cached, we are in a nested node, but our id count will
150+
// still count towards the parent's count.
151+
let reset_cached_id = lctx.cached_id.get() == 0;
152+
// We always reset gensym_key so that if we use the same name in a nested
153+
// node and after that node, they get different values.
154+
let old_gensym_key = lctx.gensym_key.get();
155+
156+
{
157+
let id_cache: &mut HashMap<_, _> = &mut lctx.id_cache.borrow_mut();
158+
159+
if id_cache.contains_key(&expr_id) {
160+
let cached_id = lctx.cached_id.get();
161+
if cached_id == 0 {
162+
// We're entering a node where we need to track ids, but are not
163+
// yet tracking.
164+
lctx.cached_id.set(id_cache[&expr_id]);
165+
} else {
166+
// We're already tracking - check that the tracked id is the same
167+
// as the expected id.
168+
assert!(cached_id == id_cache[&expr_id], "id mismatch");
169+
}
170+
lctx.gensym_key.set(id_cache[&expr_id]);
171+
} else {
172+
// We've never lowered this node before, remember it for next time.
173+
let next_id = lctx.id_assigner.peek_node_id();
174+
id_cache.insert(expr_id, next_id);
175+
lctx.gensym_key.set(next_id);
176+
// self.cached_id is not set when we lower a node for the first time,
177+
// only on re-lowering.
178+
}
179+
}
180+
181+
let result = op(lctx);
182+
183+
if reset_cached_id {
184+
lctx.cached_id.set(0);
185+
}
186+
lctx.gensym_key.set(old_gensym_key);
187+
188+
result
189+
}
190+
143191
pub fn lower_ident(_lctx: &LoweringContext, ident: Ident) -> hir::Ident {
144192
hir::Ident {
145193
name: mtwt::resolve(ident),
@@ -918,47 +966,6 @@ pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P<hir::Pat> {
918966
})
919967
}
920968

921-
// Utility fn for setting and unsetting the cached id.
922-
fn cache_ids<'a, OP, R>(lctx: &LoweringContext, expr_id: NodeId, op: OP) -> R
923-
where OP: FnOnce(&LoweringContext) -> R
924-
{
925-
// Only reset the id if it was previously 0, i.e., was not cached.
926-
// If it was cached, we are in a nested node, but our id count will
927-
// still count towards the parent's count.
928-
let reset_cached_id = lctx.cached_id.get() == 0;
929-
930-
{
931-
let id_cache: &mut HashMap<_, _> = &mut lctx.id_cache.borrow_mut();
932-
933-
if id_cache.contains_key(&expr_id) {
934-
let cached_id = lctx.cached_id.get();
935-
if cached_id == 0 {
936-
// We're entering a node where we need to track ids, but are not
937-
// yet tracking.
938-
lctx.cached_id.set(id_cache[&expr_id]);
939-
lctx.gensym_key.set(id_cache[&expr_id]);
940-
} else {
941-
// We're already tracking - check that the tracked id is the same
942-
// as the expected id.
943-
assert!(cached_id == id_cache[&expr_id], "id mismatch");
944-
}
945-
} else {
946-
let next_id = lctx.id_assigner.peek_node_id();
947-
id_cache.insert(expr_id, next_id);
948-
lctx.gensym_key.set(next_id);
949-
}
950-
}
951-
952-
let result = op(lctx);
953-
954-
if reset_cached_id {
955-
lctx.cached_id.set(0);
956-
lctx.gensym_key.set(0);
957-
}
958-
959-
result
960-
}
961-
962969
pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
963970
P(hir::Expr {
964971
id: e.id,
@@ -1935,7 +1942,9 @@ mod test {
19351942
let ast_while_let = assigner.fold_expr(ast_while_let);
19361943
let ast_for = quote_expr!(&cx,
19371944
for i in 0..10 {
1938-
foo(i);
1945+
for j in 0..10 {
1946+
foo(i, j);
1947+
}
19391948
});
19401949
let ast_for = assigner.fold_expr(ast_for);
19411950
let ast_in = quote_expr!(&cx, in HEAP { foo() });

0 commit comments

Comments
 (0)