Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
ac4c1f58
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
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,发现更多精彩内容 >>
提交
ac4c1f58
编写于
11月 14, 2020
作者:
V
Vadim Petrochenkov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc_resolve: Make `macro_rules` scope chain compression lazy
上级
89bce3e9
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
21 addition
and
36 deletion
+21
-36
compiler/rustc_resolve/src/build_reduced_graph.rs
compiler/rustc_resolve/src/build_reduced_graph.rs
+1
-3
compiler/rustc_resolve/src/lib.rs
compiler/rustc_resolve/src/lib.rs
+17
-10
compiler/rustc_resolve/src/macros.rs
compiler/rustc_resolve/src/macros.rs
+3
-23
未找到文件。
compiler/rustc_resolve/src/build_reduced_graph.rs
浏览文件 @
ac4c1f58
...
...
@@ -1163,9 +1163,7 @@ fn visit_invoc(&mut self, id: NodeId) -> MacroRulesScopeRef<'a> {
let
old_parent_scope
=
self
.r.invocation_parent_scopes
.insert
(
invoc_id
,
self
.parent_scope
);
assert
!
(
old_parent_scope
.is_none
(),
"invocation data is reset for an invocation"
);
let
scope
=
self
.r.arenas
.alloc_macro_rules_scope
(
MacroRulesScope
::
Invocation
(
invoc_id
));
self
.r.invocation_macro_rules_scopes
.entry
(
invoc_id
)
.or_default
()
.insert
(
scope
);
scope
self
.r.arenas
.alloc_macro_rules_scope
(
MacroRulesScope
::
Invocation
(
invoc_id
))
}
fn
proc_macro_stub
(
&
self
,
item
:
&
ast
::
Item
)
->
Option
<
(
MacroKind
,
Ident
,
Span
)
>
{
...
...
compiler/rustc_resolve/src/lib.rs
浏览文件 @
ac4c1f58
...
...
@@ -976,9 +976,6 @@ pub struct Resolver<'a> {
/// `macro_rules` scopes *produced* by expanding the macro invocations,
/// include all the `macro_rules` items and other invocations generated by them.
output_macro_rules_scopes
:
FxHashMap
<
ExpnId
,
MacroRulesScopeRef
<
'a
>>
,
/// References to all `MacroRulesScope::Invocation(invoc_id)`s, used to update such scopes
/// when their corresponding `invoc_id`s get expanded.
invocation_macro_rules_scopes
:
FxHashMap
<
ExpnId
,
FxHashSet
<
MacroRulesScopeRef
<
'a
>>>
,
/// Helper attributes that are in scope for the given expansion.
helper_attrs
:
FxHashMap
<
ExpnId
,
Vec
<
Ident
>>
,
...
...
@@ -1310,7 +1307,6 @@ pub fn new(
non_macro_attrs
:
[
non_macro_attr
(
false
),
non_macro_attr
(
true
)],
invocation_parent_scopes
:
Default
::
default
(),
output_macro_rules_scopes
:
Default
::
default
(),
invocation_macro_rules_scopes
:
Default
::
default
(),
helper_attrs
:
Default
::
default
(),
local_macro_def_scopes
:
FxHashMap
::
default
(),
name_already_seen
:
FxHashMap
::
default
(),
...
...
@@ -1680,7 +1676,20 @@ fn visit_scopes<T>(
!
(
expn_id
==
parent_scope
.expansion
&&
macro_kind
==
Some
(
MacroKind
::
Derive
))
}
Scope
::
DeriveHelpersCompat
=>
true
,
Scope
::
MacroRules
(
..
)
=>
true
,
Scope
::
MacroRules
(
macro_rules_scope
)
=>
{
// Use "path compression" on `macro_rules` scope chains. This is an optimization
// used to avoid long scope chains, see the comments on `MacroRulesScopeRef`.
// As another consequence of this optimization visitors never observe invocation
// scopes for macros that were already expanded.
while
let
MacroRulesScope
::
Invocation
(
invoc_id
)
=
macro_rules_scope
.get
()
{
if
let
Some
(
next_scope
)
=
self
.output_macro_rules_scopes
.get
(
&
invoc_id
)
{
macro_rules_scope
.set
(
next_scope
.get
());
}
else
{
break
;
}
}
true
}
Scope
::
CrateRoot
=>
true
,
Scope
::
Module
(
..
)
=>
true
,
Scope
::
RegisteredAttrs
=>
use_prelude
,
...
...
@@ -1716,11 +1725,9 @@ fn visit_scopes<T>(
MacroRulesScope
::
Binding
(
binding
)
=>
{
Scope
::
MacroRules
(
binding
.parent_macro_rules_scope
)
}
MacroRulesScope
::
Invocation
(
invoc_id
)
=>
Scope
::
MacroRules
(
self
.output_macro_rules_scopes
.get
(
&
invoc_id
)
.cloned
()
.unwrap_or_else
(
||
self
.invocation_parent_scopes
[
&
invoc_id
]
.macro_rules
,
),
),
MacroRulesScope
::
Invocation
(
invoc_id
)
=>
{
Scope
::
MacroRules
(
self
.invocation_parent_scopes
[
&
invoc_id
]
.macro_rules
)
}
MacroRulesScope
::
Empty
=>
Scope
::
Module
(
module
),
},
Scope
::
CrateRoot
=>
match
ns
{
...
...
compiler/rustc_resolve/src/macros.rs
浏览文件 @
ac4c1f58
...
...
@@ -62,8 +62,8 @@ pub enum MacroRulesScope<'a> {
}
/// `macro_rules!` scopes are always kept by reference and inside a cell.
/// The reason is that we update
all
scopes with value `MacroRulesScope::Invocation(invoc_id)`
/// in-place
immediately
after `invoc_id` gets expanded.
/// The reason is that we update scopes with value `MacroRulesScope::Invocation(invoc_id)`
/// in-place after `invoc_id` gets expanded.
/// This helps to avoid uncontrollable growth of `macro_rules!` scope chains,
/// which usually grow lineraly with the number of macro invocations
/// in a module (including derives) and hurt performance.
...
...
@@ -173,22 +173,6 @@ fn visit_ast_fragment_with_placeholders(&mut self, expansion: ExpnId, fragment:
let
output_macro_rules_scope
=
self
.build_reduced_graph
(
fragment
,
parent_scope
);
self
.output_macro_rules_scopes
.insert
(
expansion
,
output_macro_rules_scope
);
// Update all `macro_rules` scopes referring to this invocation. This is an optimization
// used to avoid long scope chains, see the comments on `MacroRulesScopeRef`.
if
let
Some
(
invocation_scopes
)
=
self
.invocation_macro_rules_scopes
.remove
(
&
expansion
)
{
for
invocation_scope
in
&
invocation_scopes
{
invocation_scope
.set
(
output_macro_rules_scope
.get
());
}
// All `macro_rules` scopes that previously referred to `expansion`
// are now rerouted to its output scope, if it's also an invocation.
if
let
MacroRulesScope
::
Invocation
(
invoc_id
)
=
output_macro_rules_scope
.get
()
{
self
.invocation_macro_rules_scopes
.entry
(
invoc_id
)
.or_default
()
.extend
(
invocation_scopes
);
}
}
parent_scope
.module.unexpanded_invocations
.borrow_mut
()
.remove
(
&
expansion
);
}
...
...
@@ -687,11 +671,7 @@ struct Flags: u8 {
{
Ok
((
macro_rules_binding
.binding
,
Flags
::
MACRO_RULES
))
}
MacroRulesScope
::
Invocation
(
invoc_id
)
if
!
this
.output_macro_rules_scopes
.contains_key
(
&
invoc_id
)
=>
{
Err
(
Determinacy
::
Undetermined
)
}
MacroRulesScope
::
Invocation
(
_
)
=>
Err
(
Determinacy
::
Undetermined
),
_
=>
Err
(
Determinacy
::
Determined
),
},
Scope
::
CrateRoot
=>
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录