Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
078fc52c
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,发现更多精彩内容 >>
提交
078fc52c
编写于
9月 27, 2018
作者:
V
Vadim Petrochenkov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
resolve: Prefer `macro_rules` definitions to in-module macro definitions in some cases
上级
4cf11765
变更
7
显示空白变更内容
内联
并排
Showing
7 changed file
with
130 addition
and
23 deletion
+130
-23
src/librustc_resolve/lib.rs
src/librustc_resolve/lib.rs
+40
-3
src/librustc_resolve/macros.rs
src/librustc_resolve/macros.rs
+4
-1
src/librustc_resolve/resolve_imports.rs
src/librustc_resolve/resolve_imports.rs
+1
-0
src/test/ui/imports/macros.rs
src/test/ui/imports/macros.rs
+1
-1
src/test/ui/imports/macros.stderr
src/test/ui/imports/macros.stderr
+1
-18
src/test/ui/macros/ambiguity-legacy-vs-modern.rs
src/test/ui/macros/ambiguity-legacy-vs-modern.rs
+46
-0
src/test/ui/macros/ambiguity-legacy-vs-modern.stderr
src/test/ui/macros/ambiguity-legacy-vs-modern.stderr
+37
-0
未找到文件。
src/librustc_resolve/lib.rs
浏览文件 @
078fc52c
...
...
@@ -72,11 +72,10 @@
use
errors
::{
Applicability
,
DiagnosticBuilder
,
DiagnosticId
};
use
std
::
cell
::{
Cell
,
RefCell
};
use
std
::
cmp
;
use
std
::
{
cmp
,
fmt
,
iter
,
ptr
}
;
use
std
::
collections
::
BTreeSet
;
use
std
::
fmt
;
use
std
::
iter
;
use
std
::
mem
::
replace
;
use
rustc_data_structures
::
ptr_key
::
PtrKey
;
use
rustc_data_structures
::
sync
::
Lrc
;
use
resolve_imports
::{
ImportDirective
,
ImportDirectiveSubclass
,
NameResolution
,
ImportResolver
};
...
...
@@ -1114,6 +1113,17 @@ fn is_local(&self) -> bool {
fn
nearest_item_scope
(
&
'a
self
)
->
Module
<
'a
>
{
if
self
.is_trait
()
{
self
.parent
.unwrap
()
}
else
{
self
}
}
fn
is_ancestor_of
(
&
self
,
mut
other
:
&
Self
)
->
bool
{
while
!
ptr
::
eq
(
self
,
other
)
{
if
let
Some
(
parent
)
=
other
.parent
{
other
=
parent
;
}
else
{
return
false
;
}
}
true
}
}
impl
<
'a
>
fmt
::
Debug
for
ModuleData
<
'a
>
{
...
...
@@ -1411,6 +1421,7 @@ pub struct Resolver<'a, 'b: 'a> {
block_map
:
NodeMap
<
Module
<
'a
>>
,
module_map
:
FxHashMap
<
DefId
,
Module
<
'a
>>
,
extern_module_map
:
FxHashMap
<
(
DefId
,
bool
/* MacrosOnly? */
),
Module
<
'a
>>
,
binding_parent_modules
:
FxHashMap
<
PtrKey
<
'a
,
NameBinding
<
'a
>>
,
Module
<
'a
>>
,
pub
make_glob_map
:
bool
,
/// Maps imports to the names of items actually imported (this actually maps
...
...
@@ -1714,6 +1725,7 @@ pub fn new(session: &'a Session,
module_map
,
block_map
:
NodeMap
(),
extern_module_map
:
FxHashMap
(),
binding_parent_modules
:
FxHashMap
(),
make_glob_map
:
make_glob_map
==
MakeGlobMap
::
Yes
,
glob_map
:
NodeMap
(),
...
...
@@ -4596,6 +4608,31 @@ fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool {
vis
.is_accessible_from
(
module
.normal_ancestor_id
,
self
)
}
fn
set_binding_parent_module
(
&
mut
self
,
binding
:
&
'a
NameBinding
<
'a
>
,
module
:
Module
<
'a
>
)
{
if
let
Some
(
old_module
)
=
self
.binding_parent_modules
.insert
(
PtrKey
(
binding
),
module
)
{
if
!
ptr
::
eq
(
module
,
old_module
)
{
span_bug!
(
binding
.span
,
"parent module is reset for binding"
);
}
}
}
fn
disambiguate_legacy_vs_modern
(
&
self
,
legacy
:
&
'a
NameBinding
<
'a
>
,
modern
:
&
'a
NameBinding
<
'a
>
,
)
->
bool
{
// Some non-controversial subset of ambiguities "modern macro name" vs "macro_rules"
// is disambiguated to mitigate regressions from macro modularization.
// Scoping for `macro_rules` behaves like scoping for `let` at module level, in general.
match
(
self
.binding_parent_modules
.get
(
&
PtrKey
(
legacy
)),
self
.binding_parent_modules
.get
(
&
PtrKey
(
modern
)))
{
(
Some
(
legacy
),
Some
(
modern
))
=>
legacy
.normal_ancestor_id
==
modern
.normal_ancestor_id
&&
modern
.is_ancestor_of
(
legacy
),
_
=>
false
,
}
}
fn
report_ambiguity_error
(
&
self
,
ident
:
Ident
,
b1
:
&
NameBinding
,
b2
:
&
NameBinding
)
{
let
participle
=
|
is_import
:
bool
|
if
is_import
{
"imported"
}
else
{
"defined"
};
let
msg1
=
...
...
src/librustc_resolve/macros.rs
浏览文件 @
078fc52c
...
...
@@ -957,11 +957,13 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
},
(
Some
(
legacy_binding
),
Ok
((
binding
,
FromPrelude
(
from_prelude
))))
if
legacy_binding
.def
()
!=
binding
.def_ignoring_ambiguity
()
&&
(
!
from_prelude
||
(
!
from_prelude
&&
!
self
.disambiguate_legacy_vs_modern
(
legacy_binding
,
binding
)
||
legacy_binding
.may_appear_after
(
parent_scope
.expansion
,
binding
))
=>
{
self
.report_ambiguity_error
(
ident
,
legacy_binding
,
binding
);
},
// OK, non-macro-expanded legacy wins over prelude even if defs are different
// Also, non-macro-expanded legacy wins over modern from the same module
// Also, legacy and modern can co-exist if their defs are same
(
Some
(
legacy_binding
),
Ok
(
_
))
|
// OK, unambiguous resolution
...
...
@@ -1097,6 +1099,7 @@ pub fn define_macro(&mut self,
let
def
=
Def
::
Macro
(
def_id
,
MacroKind
::
Bang
);
let
vis
=
ty
::
Visibility
::
Invisible
;
// Doesn't matter for legacy bindings
let
binding
=
(
def
,
vis
,
item
.span
,
expansion
)
.to_name_binding
(
self
.arenas
);
self
.set_binding_parent_module
(
binding
,
self
.current_module
);
let
legacy_binding
=
self
.arenas
.alloc_legacy_binding
(
LegacyBinding
{
parent_legacy_scope
:
*
current_legacy_scope
,
binding
,
ident
});
...
...
src/librustc_resolve/resolve_imports.rs
浏览文件 @
078fc52c
...
...
@@ -478,6 +478,7 @@ pub fn try_define(&mut self,
binding
:
&
'a
NameBinding
<
'a
>
)
->
Result
<
(),
&
'a
NameBinding
<
'a
>>
{
self
.check_reserved_macro_name
(
ident
,
ns
);
self
.set_binding_parent_module
(
binding
,
module
);
self
.update_resolution
(
module
,
ident
,
ns
,
|
this
,
resolution
|
{
if
let
Some
(
old_binding
)
=
resolution
.binding
{
if
binding
.is_glob_import
()
{
...
...
src/test/ui/imports/macros.rs
浏览文件 @
078fc52c
...
...
@@ -45,7 +45,7 @@ fn g() {
mod
m4
{
macro_rules!
m
{
()
=>
{}
}
use
two_macros
::
m
;
m!
();
//~ ERROR ambiguous
m!
();
}
fn
main
()
{}
src/test/ui/imports/macros.stderr
浏览文件 @
078fc52c
error[E0659]: `m` is ambiguous
--> $DIR/macros.rs:48:5
|
LL | m!(); //~ ERROR ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
--> $DIR/macros.rs:46:5
|
LL | macro_rules! m { () => {} }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `m` could also refer to the name imported here
--> $DIR/macros.rs:47:9
|
LL | use two_macros::m;
| ^^^^^^^^^^^^^
error[E0659]: `m` is ambiguous
--> $DIR/macros.rs:26:5
|
...
...
@@ -51,6 +34,6 @@ LL | use two_macros::m;
| ^^^^^^^^^^^^^
= note: macro-expanded macro imports do not shadow
error: aborting due to
3
previous errors
error: aborting due to
2
previous errors
For more information about this error, try `rustc --explain E0659`.
src/test/ui/macros/ambiguity-legacy-vs-modern.rs
0 → 100644
浏览文件 @
078fc52c
// Some non-controversial subset of ambiguities "modern macro name" vs "macro_rules"
// is disambiguated to mitigate regressions from macro modularization.
// Scoping for `macro_rules` behaves like scoping for `let` at module level, in general.
#![feature(decl_macro)]
fn
same_unnamed_mod
()
{
macro
m
()
{
0
}
macro_rules!
m
{
()
=>
(())
}
m!
()
// OK
}
fn
nested_unnamed_mod
()
{
macro
m
()
{
0
}
{
macro_rules!
m
{
()
=>
(())
}
m!
()
// OK
}
}
fn
nested_unnamed_mod_fail
()
{
macro_rules!
m
{
()
=>
(())
}
{
macro
m
()
{
0
}
m!
()
//~ ERROR `m` is ambiguous
}
}
fn
nexted_named_mod_fail
()
{
macro
m
()
{
0
}
#[macro_use]
mod
inner
{
macro_rules!
m
{
()
=>
(())
}
}
m!
()
//~ ERROR `m` is ambiguous
}
fn
main
()
{}
src/test/ui/macros/ambiguity-legacy-vs-modern.stderr
0 → 100644
浏览文件 @
078fc52c
error[E0659]: `m` is ambiguous
--> $DIR/ambiguity-legacy-vs-modern.rs:31:9
|
LL | m!() //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
--> $DIR/ambiguity-legacy-vs-modern.rs:26:5
|
LL | macro_rules! m { () => (()) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `m` could also refer to the name defined here
--> $DIR/ambiguity-legacy-vs-modern.rs:29:9
|
LL | macro m() { 0 }
| ^^^^^^^^^^^^^^^
error[E0659]: `m` is ambiguous
--> $DIR/ambiguity-legacy-vs-modern.rs:43:5
|
LL | m!() //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
--> $DIR/ambiguity-legacy-vs-modern.rs:40:9
|
LL | macro_rules! m { () => (()) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `m` could also refer to the name defined here
--> $DIR/ambiguity-legacy-vs-modern.rs:36:5
|
LL | macro m() { 0 }
| ^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0659`.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录