Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
7ffd408d
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
7ffd408d
编写于
1月 20, 2016
作者:
N
Nick Cameron
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix a bug with caching ids in the HIR lowering with nested lowered nodes
Blocks #30884
上级
08886499
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
61 addition
and
52 deletion
+61
-52
src/librustc_front/lowering.rs
src/librustc_front/lowering.rs
+61
-52
未找到文件。
src/librustc_front/lowering.rs
浏览文件 @
7ffd408d
...
...
@@ -87,7 +87,8 @@ pub struct LoweringContext<'a> {
cached_id
:
Cell
<
u32
>
,
// Keep track of gensym'ed idents.
gensym_cache
:
RefCell
<
HashMap
<
(
NodeId
,
&
'static
str
),
hir
::
Ident
>>
,
// A copy of cached_id, but is also set to an id while it is being cached.
// A copy of cached_id, but is also set to an id while a node is lowered for
// the first time.
gensym_key
:
Cell
<
u32
>
,
}
...
...
@@ -114,32 +115,79 @@ pub fn new(id_assigner: &'a NodeIdAssigner, c: Option<&Crate>) -> LoweringContex
}
fn
next_id
(
&
self
)
->
NodeId
{
let
cached
=
self
.cached_id
.get
();
if
cached
==
0
{
let
cached
_id
=
self
.cached_id
.get
();
if
cached
_id
==
0
{
return
self
.id_assigner
.next_node_id
();
}
self
.cached_id
.set
(
cached
+
1
);
cached
self
.cached_id
.set
(
cached
_id
+
1
);
cached
_id
}
fn
str_to_ident
(
&
self
,
s
:
&
'static
str
)
->
hir
::
Ident
{
let
cached_id
=
self
.gensym_key
.get
();
if
cached_id
==
0
{
let
gensym_key
=
self
.gensym_key
.get
();
if
gensym_key
==
0
{
return
hir
::
Ident
::
from_name
(
token
::
gensym
(
s
));
}
let
cached
=
self
.gensym_cache
.borrow
()
.contains_key
(
&
(
cached_id
,
s
));
let
cached
=
self
.gensym_cache
.borrow
()
.contains_key
(
&
(
gensym_key
,
s
));
if
cached
{
self
.gensym_cache
.borrow
()[
&
(
cached_id
,
s
)]
self
.gensym_cache
.borrow
()[
&
(
gensym_key
,
s
)]
}
else
{
let
result
=
hir
::
Ident
::
from_name
(
token
::
gensym
(
s
));
self
.gensym_cache
.borrow_mut
()
.insert
((
cached_id
,
s
),
result
);
self
.gensym_cache
.borrow_mut
()
.insert
((
gensym_key
,
s
),
result
);
result
}
}
}
// Utility fn for setting and unsetting the cached id.
fn
cache_ids
<
'a
,
OP
,
R
>
(
lctx
:
&
LoweringContext
,
expr_id
:
NodeId
,
op
:
OP
)
->
R
where
OP
:
FnOnce
(
&
LoweringContext
)
->
R
{
// Only reset the id if it was previously 0, i.e., was not cached.
// If it was cached, we are in a nested node, but our id count will
// still count towards the parent's count.
let
reset_cached_id
=
lctx
.cached_id
.get
()
==
0
;
// We always reset gensym_key so that if we use the same name in a nested
// node and after that node, they get different values.
let
old_gensym_key
=
lctx
.gensym_key
.get
();
{
let
id_cache
:
&
mut
HashMap
<
_
,
_
>
=
&
mut
lctx
.id_cache
.borrow_mut
();
if
id_cache
.contains_key
(
&
expr_id
)
{
let
cached_id
=
lctx
.cached_id
.get
();
if
cached_id
==
0
{
// We're entering a node where we need to track ids, but are not
// yet tracking.
lctx
.cached_id
.set
(
id_cache
[
&
expr_id
]);
}
else
{
// We're already tracking - check that the tracked id is the same
// as the expected id.
assert
!
(
cached_id
==
id_cache
[
&
expr_id
],
"id mismatch"
);
}
lctx
.gensym_key
.set
(
id_cache
[
&
expr_id
]);
}
else
{
// We've never lowered this node before, remember it for next time.
let
next_id
=
lctx
.id_assigner
.peek_node_id
();
id_cache
.insert
(
expr_id
,
next_id
);
lctx
.gensym_key
.set
(
next_id
);
// self.cached_id is not set when we lower a node for the first time,
// only on re-lowering.
}
}
let
result
=
op
(
lctx
);
if
reset_cached_id
{
lctx
.cached_id
.set
(
0
);
}
lctx
.gensym_key
.set
(
old_gensym_key
);
result
}
pub
fn
lower_ident
(
_
lctx
:
&
LoweringContext
,
ident
:
Ident
)
->
hir
::
Ident
{
hir
::
Ident
{
name
:
mtwt
::
resolve
(
ident
),
...
...
@@ -918,47 +966,6 @@ pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P<hir::Pat> {
})
}
// Utility fn for setting and unsetting the cached id.
fn
cache_ids
<
'a
,
OP
,
R
>
(
lctx
:
&
LoweringContext
,
expr_id
:
NodeId
,
op
:
OP
)
->
R
where
OP
:
FnOnce
(
&
LoweringContext
)
->
R
{
// Only reset the id if it was previously 0, i.e., was not cached.
// If it was cached, we are in a nested node, but our id count will
// still count towards the parent's count.
let
reset_cached_id
=
lctx
.cached_id
.get
()
==
0
;
{
let
id_cache
:
&
mut
HashMap
<
_
,
_
>
=
&
mut
lctx
.id_cache
.borrow_mut
();
if
id_cache
.contains_key
(
&
expr_id
)
{
let
cached_id
=
lctx
.cached_id
.get
();
if
cached_id
==
0
{
// We're entering a node where we need to track ids, but are not
// yet tracking.
lctx
.cached_id
.set
(
id_cache
[
&
expr_id
]);
lctx
.gensym_key
.set
(
id_cache
[
&
expr_id
]);
}
else
{
// We're already tracking - check that the tracked id is the same
// as the expected id.
assert
!
(
cached_id
==
id_cache
[
&
expr_id
],
"id mismatch"
);
}
}
else
{
let
next_id
=
lctx
.id_assigner
.peek_node_id
();
id_cache
.insert
(
expr_id
,
next_id
);
lctx
.gensym_key
.set
(
next_id
);
}
}
let
result
=
op
(
lctx
);
if
reset_cached_id
{
lctx
.cached_id
.set
(
0
);
lctx
.gensym_key
.set
(
0
);
}
result
}
pub
fn
lower_expr
(
lctx
:
&
LoweringContext
,
e
:
&
Expr
)
->
P
<
hir
::
Expr
>
{
P
(
hir
::
Expr
{
id
:
e
.id
,
...
...
@@ -1935,7 +1942,9 @@ fn test_preserves_ids() {
let
ast_while_let
=
assigner
.fold_expr
(
ast_while_let
);
let
ast_for
=
quote_expr!
(
&
cx
,
for
i
in
0
..
10
{
foo
(
i
);
for
j
in
0
..
10
{
foo
(
i
,
j
);
}
});
let
ast_for
=
assigner
.fold_expr
(
ast_for
);
let
ast_in
=
quote_expr!
(
&
cx
,
in
HEAP
{
foo
()
});
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录