Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
b25c063c
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,发现更多精彩内容 >>
提交
b25c063c
编写于
11月 10, 2016
作者:
J
Jeffrey Seyfried
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Refactor out `PerNS`.
上级
1bbf7a43
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
186 addition
and
178 deletion
+186
-178
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/build_reduced_graph.rs
+12
-3
src/librustc_resolve/check_unused.rs
src/librustc_resolve/check_unused.rs
+3
-3
src/librustc_resolve/lib.rs
src/librustc_resolve/lib.rs
+83
-61
src/librustc_resolve/resolve_imports.rs
src/librustc_resolve/resolve_imports.rs
+86
-109
src/test/compile-fail/blind-item-block-item-shadow.rs
src/test/compile-fail/blind-item-block-item-shadow.rs
+1
-1
src/test/compile-fail/double-type-import.rs
src/test/compile-fail/double-type-import.rs
+1
-1
未找到文件。
src/librustc_resolve/build_reduced_graph.rs
浏览文件 @
b25c063c
...
...
@@ -15,7 +15,7 @@
use
macros
::{
InvocationData
,
LegacyScope
};
use
resolve_imports
::
ImportDirective
;
use
resolve_imports
::
ImportDirectiveSubclass
::{
self
,
GlobImport
};
use
resolve_imports
::
ImportDirectiveSubclass
::{
self
,
GlobImport
,
SingleImport
};
use
{
Resolver
,
Module
,
ModuleS
,
ModuleKind
,
NameBinding
,
NameBindingKind
,
ToNameBinding
};
use
Namespace
::{
self
,
TypeNS
,
ValueNS
,
MacroNS
};
use
ResolveResult
::
Success
;
...
...
@@ -37,6 +37,7 @@
use
syntax
::
ast
::{
Mutability
,
StmtKind
,
TraitItem
,
TraitItemKind
};
use
syntax
::
ast
::{
Variant
,
ViewPathGlob
,
ViewPathList
,
ViewPathSimple
};
use
syntax
::
ext
::
base
::
SyntaxExtension
;
use
syntax
::
ext
::
base
::
Determinacy
::
Undetermined
;
use
syntax
::
ext
::
expand
::
mark_tts
;
use
syntax
::
ext
::
hygiene
::
Mark
;
use
syntax
::
ext
::
tt
::
macro_rules
;
...
...
@@ -157,7 +158,11 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
.emit
();
}
let
subclass
=
ImportDirectiveSubclass
::
single
(
binding
.name
,
source
.name
);
let
subclass
=
SingleImport
{
target
:
binding
.name
,
source
:
source
.name
,
result
:
self
.per_ns
(|
_
,
_
|
Cell
::
new
(
Err
(
Undetermined
))),
};
self
.add_import_directive
(
module_path
,
subclass
,
view_path
.span
,
item
.id
,
vis
,
expansion
,
);
...
...
@@ -206,7 +211,11 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
(
module_path
.to_vec
(),
name
,
rename
)
}
};
let
subclass
=
ImportDirectiveSubclass
::
single
(
rename
,
name
);
let
subclass
=
SingleImport
{
target
:
rename
,
source
:
name
,
result
:
self
.per_ns
(|
_
,
_
|
Cell
::
new
(
Err
(
Undetermined
))),
};
let
id
=
source_item
.node.id
;
self
.add_import_directive
(
module_path
,
subclass
,
source_item
.span
,
id
,
vis
,
expansion
,
...
...
src/librustc_resolve/check_unused.rs
浏览文件 @
b25c063c
...
...
@@ -22,7 +22,6 @@
use
std
::
ops
::{
Deref
,
DerefMut
};
use
Resolver
;
use
Namespace
::{
TypeNS
,
ValueNS
};
use
rustc
::
lint
;
use
rustc
::
util
::
nodemap
::
NodeMap
;
...
...
@@ -56,8 +55,9 @@ impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> {
// We have information about whether `use` (import) directives are actually
// used now. If an import is not used at all, we signal a lint error.
fn
check_import
(
&
mut
self
,
item_id
:
ast
::
NodeId
,
id
:
ast
::
NodeId
,
span
:
Span
)
{
if
!
self
.used_imports
.contains
(
&
(
id
,
TypeNS
))
&&
!
self
.used_imports
.contains
(
&
(
id
,
ValueNS
))
{
let
mut
used
=
false
;
self
.per_ns
(|
this
,
ns
|
used
|
=
this
.used_imports
.contains
(
&
(
id
,
ns
)));
if
!
used
{
if
self
.maybe_unused_trait_imports
.contains
(
&
id
)
{
// Check later.
return
;
...
...
src/librustc_resolve/lib.rs
浏览文件 @
b25c063c
...
...
@@ -536,6 +536,33 @@ pub enum Namespace {
MacroNS
,
}
#[derive(Clone,
Default,
Debug)]
pub
struct
PerNS
<
T
>
{
value_ns
:
T
,
type_ns
:
T
,
}
impl
<
T
>
::
std
::
ops
::
Index
<
Namespace
>
for
PerNS
<
T
>
{
type
Output
=
T
;
fn
index
(
&
self
,
ns
:
Namespace
)
->
&
T
{
match
ns
{
ValueNS
=>
&
self
.value_ns
,
TypeNS
=>
&
self
.type_ns
,
MacroNS
=>
unreachable!
(),
}
}
}
impl
<
T
>
::
std
::
ops
::
IndexMut
<
Namespace
>
for
PerNS
<
T
>
{
fn
index_mut
(
&
mut
self
,
ns
:
Namespace
)
->
&
mut
T
{
match
ns
{
ValueNS
=>
&
mut
self
.value_ns
,
TypeNS
=>
&
mut
self
.type_ns
,
MacroNS
=>
unreachable!
(),
}
}
}
impl
<
'a
>
Visitor
for
Resolver
<
'a
>
{
fn
visit_item
(
&
mut
self
,
item
:
&
Item
)
{
self
.resolve_item
(
item
);
...
...
@@ -612,7 +639,7 @@ fn visit_fn(&mut self,
};
// Create a value rib for the function.
self
.
value_ribs
.push
(
Rib
::
new
(
rib_kind
));
self
.
ribs
[
ValueNS
]
.push
(
Rib
::
new
(
rib_kind
));
// Create a label rib for the function.
self
.label_ribs
.push
(
Rib
::
new
(
rib_kind
));
...
...
@@ -642,7 +669,7 @@ fn visit_fn(&mut self,
debug!
(
"(resolving function) leaving function"
);
self
.label_ribs
.pop
();
self
.
value_ribs
.pop
();
self
.
ribs
[
ValueNS
]
.pop
();
}
}
...
...
@@ -1049,12 +1076,9 @@ pub struct Resolver<'a> {
// The module that represents the current item scope.
current_module
:
Module
<
'a
>
,
// The current set of local scopes
, for
values.
// The current set of local scopes
for types and
values.
// FIXME #4948: Reuse ribs to avoid allocation.
value_ribs
:
Vec
<
Rib
<
'a
>>
,
// The current set of local scopes, for types.
type_ribs
:
Vec
<
Rib
<
'a
>>
,
ribs
:
PerNS
<
Vec
<
Rib
<
'a
>>>
,
// The current set of local scopes, for labels.
label_ribs
:
Vec
<
Rib
<
'a
>>
,
...
...
@@ -1273,8 +1297,10 @@ pub fn new(session: &'a Session,
indeterminate_imports
:
Vec
::
new
(),
current_module
:
graph_root
,
value_ribs
:
vec!
[
Rib
::
new
(
ModuleRibKind
(
graph_root
))],
type_ribs
:
vec!
[
Rib
::
new
(
ModuleRibKind
(
graph_root
))],
ribs
:
PerNS
{
value_ns
:
vec!
[
Rib
::
new
(
ModuleRibKind
(
graph_root
))],
type_ns
:
vec!
[
Rib
::
new
(
ModuleRibKind
(
graph_root
))],
},
label_ribs
:
Vec
::
new
(),
current_trait_ref
:
None
,
...
...
@@ -1335,6 +1361,13 @@ pub fn arenas() -> ResolverArenas<'a> {
}
}
fn
per_ns
<
T
,
F
:
FnMut
(
&
mut
Self
,
Namespace
)
->
T
>
(
&
mut
self
,
mut
f
:
F
)
->
PerNS
<
T
>
{
PerNS
{
type_ns
:
f
(
self
,
TypeNS
),
value_ns
:
f
(
self
,
ValueNS
),
}
}
/// Entry point to crate resolution.
pub
fn
resolve_crate
(
&
mut
self
,
krate
:
&
Crate
)
{
ImportResolver
{
resolver
:
self
}
.finalize_imports
();
...
...
@@ -1354,14 +1387,6 @@ fn new_module(&self, parent: Module<'a>, kind: ModuleKind, local: bool) -> Modul
})
}
fn
get_ribs
<
'b
>
(
&
'b
mut
self
,
ns
:
Namespace
)
->
&
'b
mut
Vec
<
Rib
<
'a
>>
{
match
ns
{
ValueNS
=>
&
mut
self
.value_ribs
,
TypeNS
=>
&
mut
self
.type_ribs
,
MacroNS
=>
panic!
(
"The macro namespace has no ribs"
),
}
}
fn
record_use
(
&
mut
self
,
name
:
Name
,
ns
:
Namespace
,
binding
:
&
'a
NameBinding
<
'a
>
,
span
:
Span
)
->
bool
/* true if an error was reported */
{
// track extern crates for unused_extern_crate lint
...
...
@@ -1577,8 +1602,8 @@ fn resolve_ident_in_lexical_scope(&mut self,
}
// Walk backwards up the ribs in scope.
for
i
in
(
0
..
self
.
get_ribs
(
ns
)
.len
())
.rev
()
{
if
let
Some
(
def
)
=
self
.
get_ribs
(
ns
)
[
i
]
.bindings
.get
(
&
ident
)
.cloned
()
{
for
i
in
(
0
..
self
.
ribs
[
ns
]
.len
())
.rev
()
{
if
let
Some
(
def
)
=
self
.
ribs
[
ns
]
[
i
]
.bindings
.get
(
&
ident
)
.cloned
()
{
// The ident resolves to a type parameter or local variable.
return
Some
(
LexicalScopeBinding
::
LocalDef
(
LocalDef
{
ribs
:
Some
((
ns
,
i
)),
...
...
@@ -1586,7 +1611,7 @@ fn resolve_ident_in_lexical_scope(&mut self,
}));
}
if
let
ModuleRibKind
(
module
)
=
self
.
get_ribs
(
ns
)
[
i
]
.kind
{
if
let
ModuleRibKind
(
module
)
=
self
.
ribs
[
ns
]
[
i
]
.kind
{
let
name
=
ident
.name
;
let
item
=
self
.resolve_name_in_module
(
module
,
name
,
ns
,
true
,
record_used
);
if
let
Success
(
binding
)
=
item
{
...
...
@@ -1604,7 +1629,7 @@ fn resolve_ident_in_lexical_scope(&mut self,
}
}
if
let
MacroDefinition
(
mac
)
=
self
.
get_ribs
(
ns
)
[
i
]
.kind
{
if
let
MacroDefinition
(
mac
)
=
self
.
ribs
[
ns
]
[
i
]
.kind
{
// If an invocation of this macro created `ident`, give up on `ident`
// and switch to `ident`'s source from the macro definition.
let
(
source_ctxt
,
source_macro
)
=
ident
.ctxt
.source
();
...
...
@@ -1689,14 +1714,14 @@ fn with_scope<F>(&mut self, id: NodeId, f: F)
if
let
Some
(
module
)
=
module
{
// Move down in the graph.
let
orig_module
=
replace
(
&
mut
self
.current_module
,
module
);
self
.
value_ribs
.push
(
Rib
::
new
(
ModuleRibKind
(
module
)));
self
.
type_ribs
.push
(
Rib
::
new
(
ModuleRibKind
(
module
)));
self
.
ribs
[
ValueNS
]
.push
(
Rib
::
new
(
ModuleRibKind
(
module
)));
self
.
ribs
[
TypeNS
]
.push
(
Rib
::
new
(
ModuleRibKind
(
module
)));
f
(
self
);
self
.current_module
=
orig_module
;
self
.
value_ribs
.pop
();
self
.
type_ribs
.pop
();
self
.
ribs
[
ValueNS
]
.pop
();
self
.
ribs
[
TypeNS
]
.pop
();
}
else
{
f
(
self
);
}
...
...
@@ -1871,7 +1896,7 @@ fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<
function_type_rib
.bindings
.insert
(
Ident
::
with_empty_ctxt
(
name
),
def
);
self
.record_def
(
type_parameter
.id
,
PathResolution
::
new
(
def
));
}
self
.
type_ribs
.push
(
function_type_rib
);
self
.
ribs
[
TypeNS
]
.push
(
function_type_rib
);
}
NoTypeParameters
=>
{
...
...
@@ -1882,7 +1907,7 @@ fn with_type_parameter_rib<'b, F>(&'b mut self, type_parameters: TypeParameters<
f
(
self
);
if
let
HasTypeParameters
(
..
)
=
type_parameters
{
self
.
type_ribs
.pop
();
self
.
ribs
[
TypeNS
]
.pop
();
}
}
...
...
@@ -1897,11 +1922,11 @@ fn with_label_rib<F>(&mut self, f: F)
fn
with_constant_rib
<
F
>
(
&
mut
self
,
f
:
F
)
where
F
:
FnOnce
(
&
mut
Resolver
)
{
self
.
value_ribs
.push
(
Rib
::
new
(
ConstantItemRibKind
));
self
.
type_ribs
.push
(
Rib
::
new
(
ConstantItemRibKind
));
self
.
ribs
[
ValueNS
]
.push
(
Rib
::
new
(
ConstantItemRibKind
));
self
.
ribs
[
TypeNS
]
.push
(
Rib
::
new
(
ConstantItemRibKind
));
f
(
self
);
self
.
type_ribs
.pop
();
self
.
value_ribs
.pop
();
self
.
ribs
[
TypeNS
]
.pop
();
self
.
ribs
[
ValueNS
]
.pop
();
}
fn
resolve_trait_reference
(
&
mut
self
,
...
...
@@ -2011,9 +2036,9 @@ fn with_self_rib<F>(&mut self, self_def: Def, f: F)
// plain insert (no renaming, types are not currently hygienic....)
self_type_rib
.bindings
.insert
(
keywords
::
SelfType
.ident
(),
self_def
);
self
.
type_ribs
.push
(
self_type_rib
);
self
.
ribs
[
TypeNS
]
.push
(
self_type_rib
);
f
(
self
);
self
.
type_ribs
.pop
();
self
.
ribs
[
TypeNS
]
.pop
();
}
fn
resolve_implementation
(
&
mut
self
,
...
...
@@ -2167,7 +2192,7 @@ fn check_consistent_bindings(&mut self, arm: &Arm) {
}
fn
resolve_arm
(
&
mut
self
,
arm
:
&
Arm
)
{
self
.
value_ribs
.push
(
Rib
::
new
(
NormalRibKind
));
self
.
ribs
[
ValueNS
]
.push
(
Rib
::
new
(
NormalRibKind
));
let
mut
bindings_list
=
FxHashMap
();
for
pattern
in
&
arm
.pats
{
...
...
@@ -2181,7 +2206,7 @@ fn resolve_arm(&mut self, arm: &Arm) {
walk_list!
(
self
,
visit_expr
,
&
arm
.guard
);
self
.visit_expr
(
&
arm
.body
);
self
.
value_ribs
.pop
();
self
.
ribs
[
ValueNS
]
.pop
();
}
fn
resolve_block
(
&
mut
self
,
block
:
&
Block
)
{
...
...
@@ -2193,11 +2218,11 @@ fn resolve_block(&mut self, block: &Block) {
let
mut
num_macro_definition_ribs
=
0
;
if
let
Some
(
anonymous_module
)
=
anonymous_module
{
debug!
(
"(resolving block) found anonymous module, moving down"
);
self
.
value_ribs
.push
(
Rib
::
new
(
ModuleRibKind
(
anonymous_module
)));
self
.
type_ribs
.push
(
Rib
::
new
(
ModuleRibKind
(
anonymous_module
)));
self
.
ribs
[
ValueNS
]
.push
(
Rib
::
new
(
ModuleRibKind
(
anonymous_module
)));
self
.
ribs
[
TypeNS
]
.push
(
Rib
::
new
(
ModuleRibKind
(
anonymous_module
)));
self
.current_module
=
anonymous_module
;
}
else
{
self
.
value_ribs
.push
(
Rib
::
new
(
NormalRibKind
));
self
.
ribs
[
ValueNS
]
.push
(
Rib
::
new
(
NormalRibKind
));
}
// Descend into the block.
...
...
@@ -2205,7 +2230,7 @@ fn resolve_block(&mut self, block: &Block) {
if
let
Some
(
marks
)
=
self
.macros_at_scope
.remove
(
&
stmt
.id
)
{
num_macro_definition_ribs
+=
marks
.len
()
as
u32
;
for
mark
in
marks
{
self
.
value_ribs
.push
(
Rib
::
new
(
MacroDefinition
(
mark
)));
self
.
ribs
[
ValueNS
]
.push
(
Rib
::
new
(
MacroDefinition
(
mark
)));
self
.label_ribs
.push
(
Rib
::
new
(
MacroDefinition
(
mark
)));
}
}
...
...
@@ -2216,12 +2241,12 @@ fn resolve_block(&mut self, block: &Block) {
// Move back up.
self
.current_module
=
orig_module
;
for
_
in
0
..
num_macro_definition_ribs
{
self
.
value_ribs
.pop
();
self
.
ribs
[
ValueNS
]
.pop
();
self
.label_ribs
.pop
();
}
self
.
value_ribs
.pop
();
self
.
ribs
[
ValueNS
]
.pop
();
if
let
Some
(
_
)
=
anonymous_module
{
self
.
type_ribs
.pop
();
self
.
ribs
[
TypeNS
]
.pop
();
}
debug!
(
"(resolving block) leaving block"
);
}
...
...
@@ -2340,7 +2365,7 @@ fn fresh_binding(&mut self,
Some
(
..
)
if
pat_src
==
PatternSource
::
Match
=>
{
// `Variant1(a) | Variant2(a)`, ok
// Reuse definition from the first `a`.
def
=
self
.
value_ribs
.last_mut
()
.unwrap
()
.bindings
[
&
ident
.node
];
def
=
self
.
ribs
[
ValueNS
]
.last_mut
()
.unwrap
()
.bindings
[
&
ident
.node
];
}
Some
(
..
)
=>
{
span_bug!
(
ident
.span
,
"two bindings with the same name from
\
...
...
@@ -2350,7 +2375,7 @@ fn fresh_binding(&mut self,
// A completely fresh binding, add to the lists if it's valid.
if
ident
.node.name
!=
keywords
::
Invalid
.name
()
{
bindings
.insert
(
ident
.node
,
outer_pat_id
);
self
.
value_ribs
.last_mut
()
.unwrap
()
.bindings
.insert
(
ident
.node
,
def
);
self
.
ribs
[
ValueNS
]
.last_mut
()
.unwrap
()
.bindings
.insert
(
ident
.node
,
def
);
}
}
}
...
...
@@ -2634,9 +2659,8 @@ fn resolve_identifier(&mut self,
// Resolve a local definition, potentially adjusting for closures.
fn
adjust_local_def
(
&
mut
self
,
local_def
:
LocalDef
,
span
:
Span
)
->
Option
<
Def
>
{
let
ribs
=
match
local_def
.ribs
{
Some
((
TypeNS
,
i
))
=>
&
self
.type_ribs
[
i
+
1
..
],
Some
((
ValueNS
,
i
))
=>
&
self
.value_ribs
[
i
+
1
..
],
_
=>
&
[]
as
&
[
_
],
Some
((
ns
,
i
))
=>
&
self
.ribs
[
ns
][
i
+
1
..
],
None
=>
&
[]
as
&
[
_
],
};
let
mut
def
=
local_def
.def
;
match
def
{
...
...
@@ -2798,8 +2822,8 @@ pub fn with_module_lexical_scope<T, F>(&mut self, module: Module<'a>, f: F) -> T
where
F
:
FnOnce
(
&
mut
Resolver
<
'a
>
)
->
T
,
{
self
.with_empty_ribs
(|
this
|
{
this
.
value_ribs
.push
(
Rib
::
new
(
ModuleRibKind
(
module
)));
this
.
type_ribs
.push
(
Rib
::
new
(
ModuleRibKind
(
module
)));
this
.
ribs
[
ValueNS
]
.push
(
Rib
::
new
(
ModuleRibKind
(
module
)));
this
.
ribs
[
TypeNS
]
.push
(
Rib
::
new
(
ModuleRibKind
(
module
)));
f
(
this
)
})
}
...
...
@@ -2807,13 +2831,11 @@ pub fn with_module_lexical_scope<T, F>(&mut self, module: Module<'a>, f: F) -> T
fn
with_empty_ribs
<
T
,
F
>
(
&
mut
self
,
f
:
F
)
->
T
where
F
:
FnOnce
(
&
mut
Resolver
<
'a
>
)
->
T
,
{
let
value_ribs
=
replace
(
&
mut
self
.value_ribs
,
Vec
::
new
());
let
type_ribs
=
replace
(
&
mut
self
.type_ribs
,
Vec
::
new
());
let
ribs
=
replace
(
&
mut
self
.ribs
,
PerNS
::
<
Vec
<
Rib
>>
::
default
());
let
label_ribs
=
replace
(
&
mut
self
.label_ribs
,
Vec
::
new
());
let
result
=
f
(
self
);
self
.value_ribs
=
value_ribs
;
self
.type_ribs
=
type_ribs
;
self
.ribs
=
ribs
;
self
.label_ribs
=
label_ribs
;
result
}
...
...
@@ -2865,7 +2887,7 @@ fn find_best_match(&mut self, name: &str) -> SuggestionType {
return
SuggestionType
::
Macro
(
format!
(
"{}!"
,
macro_name
));
}
let
names
=
self
.
value_ribs
let
names
=
self
.
ribs
[
ValueNS
]
.iter
()
.rev
()
.flat_map
(|
rib
|
rib
.bindings
.keys
()
.map
(|
ident
|
&
ident
.name
));
...
...
@@ -2968,7 +2990,7 @@ fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
}
else
{
let
mut
method_scope
=
false
;
let
mut
is_static
=
false
;
self
.
value_ribs
.iter
()
.rev
()
.all
(|
rib
|
{
self
.
ribs
[
ValueNS
]
.iter
()
.rev
()
.all
(|
rib
|
{
method_scope
=
match
rib
.kind
{
MethodRibKind
(
is_static_
)
=>
{
is_static
=
is_static_
;
...
...
@@ -3079,10 +3101,10 @@ fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
ExprKind
::
IfLet
(
ref
pattern
,
ref
subexpression
,
ref
if_block
,
ref
optional_else
)
=>
{
self
.visit_expr
(
subexpression
);
self
.
value_ribs
.push
(
Rib
::
new
(
NormalRibKind
));
self
.
ribs
[
ValueNS
]
.push
(
Rib
::
new
(
NormalRibKind
));
self
.resolve_pattern
(
pattern
,
PatternSource
::
IfLet
,
&
mut
FxHashMap
());
self
.visit_block
(
if_block
);
self
.
value_ribs
.pop
();
self
.
ribs
[
ValueNS
]
.pop
();
optional_else
.as_ref
()
.map
(|
expr
|
self
.visit_expr
(
expr
));
}
...
...
@@ -3096,22 +3118,22 @@ fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
ExprKind
::
WhileLet
(
ref
pattern
,
ref
subexpression
,
ref
block
,
label
)
=>
{
self
.visit_expr
(
subexpression
);
self
.
value_ribs
.push
(
Rib
::
new
(
NormalRibKind
));
self
.
ribs
[
ValueNS
]
.push
(
Rib
::
new
(
NormalRibKind
));
self
.resolve_pattern
(
pattern
,
PatternSource
::
WhileLet
,
&
mut
FxHashMap
());
self
.resolve_labeled_block
(
label
,
expr
.id
,
block
);
self
.
value_ribs
.pop
();
self
.
ribs
[
ValueNS
]
.pop
();
}
ExprKind
::
ForLoop
(
ref
pattern
,
ref
subexpression
,
ref
block
,
label
)
=>
{
self
.visit_expr
(
subexpression
);
self
.
value_ribs
.push
(
Rib
::
new
(
NormalRibKind
));
self
.
ribs
[
ValueNS
]
.push
(
Rib
::
new
(
NormalRibKind
));
self
.resolve_pattern
(
pattern
,
PatternSource
::
For
,
&
mut
FxHashMap
());
self
.resolve_labeled_block
(
label
,
expr
.id
,
block
);
self
.
value_ribs
.pop
();
self
.
ribs
[
ValueNS
]
.pop
();
}
ExprKind
::
Field
(
ref
subexpression
,
_
)
=>
{
...
...
src/librustc_resolve/resolve_imports.rs
浏览文件 @
b25c063c
...
...
@@ -10,8 +10,8 @@
use
self
::
ImportDirectiveSubclass
::
*
;
use
Module
;
use
Namespace
::{
self
,
TypeNS
,
ValueNS
};
use
{
Module
,
PerNS
}
;
use
Namespace
::{
self
,
TypeNS
};
use
{
NameBinding
,
NameBindingKind
,
PrivacyError
,
ToNameBinding
};
use
ResolveResult
;
use
ResolveResult
::
*
;
...
...
@@ -39,8 +39,7 @@ pub enum ImportDirectiveSubclass<'a> {
SingleImport
{
target
:
Name
,
source
:
Name
,
value_result
:
Cell
<
Result
<&
'a
NameBinding
<
'a
>
,
Determinacy
>>
,
type_result
:
Cell
<
Result
<&
'a
NameBinding
<
'a
>
,
Determinacy
>>
,
result
:
PerNS
<
Cell
<
Result
<&
'a
NameBinding
<
'a
>
,
Determinacy
>>>
,
},
GlobImport
{
is_prelude
:
bool
,
...
...
@@ -50,17 +49,6 @@ pub enum ImportDirectiveSubclass<'a> {
ExternCrate
,
}
impl
<
'a
>
ImportDirectiveSubclass
<
'a
>
{
pub
fn
single
(
target
:
Name
,
source
:
Name
)
->
Self
{
SingleImport
{
target
:
target
,
source
:
source
,
type_result
:
Cell
::
new
(
Err
(
Undetermined
)),
value_result
:
Cell
::
new
(
Err
(
Undetermined
)),
}
}
}
/// One import directive.
#[derive(Debug,Clone)]
pub
struct
ImportDirective
<
'a
>
{
...
...
@@ -276,10 +264,10 @@ pub fn add_import_directive(&mut self,
self
.indeterminate_imports
.push
(
directive
);
match
directive
.subclass
{
SingleImport
{
target
,
..
}
=>
{
for
&
ns
in
&
[
ValueNS
,
TypeNS
]
{
let
mut
resolution
=
self
.resolution
(
current_module
,
target
,
ns
)
.borrow_mut
();
self
.per_ns
(|
this
,
ns
|
{
let
mut
resolution
=
this
.resolution
(
current_module
,
target
,
ns
)
.borrow_mut
();
resolution
.single_imports
.add_directive
(
directive
);
}
}
);
}
// We don't add prelude imports to the globs since they only affect lexical scopes,
// which are not relevant to import resolution.
...
...
@@ -397,6 +385,18 @@ fn update_resolution<T, F>(&mut self, module: Module<'a>, name: Name, ns: Namesp
t
}
// Define a "dummy" resolution containing a Def::Err as a placeholder for a
// failed resolution
fn
import_dummy_binding
(
&
mut
self
,
directive
:
&
'a
ImportDirective
<
'a
>
)
{
if
let
SingleImport
{
target
,
..
}
=
directive
.subclass
{
let
dummy_binding
=
self
.dummy_binding
;
let
dummy_binding
=
self
.import
(
dummy_binding
,
directive
);
self
.per_ns
(|
this
,
ns
|
{
let
_
=
this
.try_define
(
directive
.parent
,
target
,
ns
,
dummy_binding
.clone
());
});
}
}
}
pub
struct
ImportResolver
<
'a
,
'b
:
'a
>
{
...
...
@@ -481,17 +481,6 @@ pub fn finalize_imports(&mut self) {
}
}
// Define a "dummy" resolution containing a Def::Err as a placeholder for a
// failed resolution
fn
import_dummy_binding
(
&
mut
self
,
directive
:
&
'b
ImportDirective
<
'b
>
)
{
if
let
SingleImport
{
target
,
..
}
=
directive
.subclass
{
let
dummy_binding
=
self
.dummy_binding
;
let
dummy_binding
=
self
.import
(
dummy_binding
,
directive
);
let
_
=
self
.try_define
(
directive
.parent
,
target
,
ValueNS
,
dummy_binding
.clone
());
let
_
=
self
.try_define
(
directive
.parent
,
target
,
TypeNS
,
dummy_binding
);
}
}
/// Attempts to resolve the given import. The return value indicates
/// failure if we're certain the name does not exist, indeterminate if we
/// don't know whether the name exists at the moment due to other
...
...
@@ -523,9 +512,8 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResul
};
directive
.imported_module
.set
(
Some
(
module
));
let
(
source
,
target
,
value_result
,
type_result
)
=
match
directive
.subclass
{
SingleImport
{
source
,
target
,
ref
value_result
,
ref
type_result
}
=>
(
source
,
target
,
value_result
,
type_result
),
let
(
source
,
target
,
result
)
=
match
directive
.subclass
{
SingleImport
{
source
,
target
,
ref
result
}
=>
(
source
,
target
,
result
),
GlobImport
{
..
}
=>
{
self
.resolve_glob_import
(
directive
);
return
Success
(());
...
...
@@ -534,46 +522,45 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResul
};
let
mut
indeterminate
=
false
;
for
&
(
ns
,
result
)
in
&
[(
ValueNS
,
value_result
),
(
TypeNS
,
type_result
)]
{
if
let
Err
(
Undetermined
)
=
result
.get
()
{
result
.set
({
match
self
.resolve_name_in_module
(
module
,
source
,
ns
,
false
,
None
)
{
self
.per_ns
(|
this
,
ns
|
{
if
let
Err
(
Undetermined
)
=
result
[
ns
]
.get
()
{
result
[
ns
]
.set
({
match
this
.resolve_name_in_module
(
module
,
source
,
ns
,
false
,
None
)
{
Success
(
binding
)
=>
Ok
(
binding
),
Indeterminate
=>
Err
(
Undetermined
),
Failed
(
_
)
=>
Err
(
Determined
),
}
});
}
else
{
continue
return
};
match
result
.get
()
{
match
result
[
ns
]
.get
()
{
Err
(
Undetermined
)
=>
indeterminate
=
true
,
Err
(
Determined
)
=>
{
self
.update_resolution
(
directive
.parent
,
target
,
ns
,
|
_
,
resolution
|
{
this
.update_resolution
(
directive
.parent
,
target
,
ns
,
|
_
,
resolution
|
{
resolution
.single_imports
.directive_failed
()
});
}
Ok
(
binding
)
if
!
binding
.is_importable
()
=>
{
let
msg
=
format!
(
"`{}` is not directly importable"
,
target
);
struct_span_err!
(
self
.session
,
directive
.span
,
E0253
,
"{}"
,
&
msg
)
struct_span_err!
(
this
.session
,
directive
.span
,
E0253
,
"{}"
,
&
msg
)
.span_label
(
directive
.span
,
&
format!
(
"cannot be imported directly"
))
.emit
();
// Do not import this illegal binding. Import a dummy binding and pretend
// everything is fine
self
.import_dummy_binding
(
directive
);
return
Success
(());
this
.import_dummy_binding
(
directive
);
}
Ok
(
binding
)
=>
{
let
imported_binding
=
self
.import
(
binding
,
directive
);
let
conflict
=
self
.try_define
(
directive
.parent
,
target
,
ns
,
imported_binding
);
let
imported_binding
=
this
.import
(
binding
,
directive
);
let
conflict
=
this
.try_define
(
directive
.parent
,
target
,
ns
,
imported_binding
);
if
let
Err
(
old_binding
)
=
conflict
{
let
binding
=
&
self
.import
(
binding
,
directive
);
self
.report_conflict
(
directive
.parent
,
target
,
ns
,
binding
,
old_binding
);
let
binding
=
&
this
.import
(
binding
,
directive
);
this
.report_conflict
(
directive
.parent
,
target
,
ns
,
binding
,
old_binding
);
}
}
}
}
}
);
if
indeterminate
{
Indeterminate
}
else
{
Success
(())
}
}
...
...
@@ -601,9 +588,8 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResu
},
};
let
(
name
,
value_result
,
type_result
)
=
match
directive
.subclass
{
SingleImport
{
source
,
ref
value_result
,
ref
type_result
,
..
}
=>
(
source
,
value_result
.get
(),
type_result
.get
()),
let
(
name
,
result
)
=
match
directive
.subclass
{
SingleImport
{
source
,
ref
result
,
..
}
=>
(
source
,
result
),
GlobImport
{
..
}
if
module
.def_id
()
==
directive
.parent
.def_id
()
=>
{
// Importing a module into itself is not allowed.
let
msg
=
"Cannot glob-import a module into itself."
.into
();
...
...
@@ -621,21 +607,27 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResu
_
=>
unreachable!
(),
};
for
&
(
ns
,
result
)
in
&
[(
ValueNS
,
value_result
),
(
TypeNS
,
type_result
)]
{
if
let
Ok
(
binding
)
=
result
{
if
self
.record_use
(
name
,
ns
,
binding
,
directive
.span
)
{
self
.resolution
(
module
,
name
,
ns
)
.borrow_mut
()
.binding
=
Some
(
self
.dummy_binding
);
let
mut
all_ns_err
=
true
;
self
.per_ns
(|
this
,
ns
|
{
if
let
Ok
(
binding
)
=
result
[
ns
]
.get
()
{
all_ns_err
=
false
;
if
this
.record_use
(
name
,
ns
,
binding
,
directive
.span
)
{
this
.resolution
(
module
,
name
,
ns
)
.borrow_mut
()
.binding
=
Some
(
this
.dummy_binding
);
}
}
}
}
);
if
value_result
.is_err
()
&&
type_result
.is_err
()
{
let
(
value_result
,
type_result
);
value_result
=
self
.resolve_name_in_module
(
module
,
name
,
ValueNS
,
false
,
Some
(
span
));
type_result
=
self
.resolve_name_in_module
(
module
,
name
,
TypeNS
,
false
,
Some
(
span
));
if
all_ns_err
{
let
mut
all_ns_failed
=
true
;
self
.per_ns
(|
this
,
ns
|
{
match
this
.resolve_name_in_module
(
module
,
name
,
ns
,
false
,
Some
(
span
))
{
Success
(
_
)
=>
all_ns_failed
=
false
,
_
=>
{}
}
});
return
if
let
(
Failed
(
_
),
Failed
(
_
))
=
(
value_result
,
type_result
)
{
return
if
all_ns_failed
{
let
resolutions
=
module
.resolutions
.borrow
();
let
names
=
resolutions
.iter
()
.filter_map
(|(
&
(
ref
n
,
_
),
resolution
)|
{
if
*
n
==
name
{
return
None
;
}
// Never suggest the same name
...
...
@@ -663,64 +655,49 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResu
}
}
let
session
=
self
.session
;
let
reexport_error
=
||
{
let
msg
=
format!
(
"`{}` is private, and cannot be reexported"
,
name
);
let
note_msg
=
format!
(
"consider marking `{}` as `pub` in the imported module"
,
name
);
struct_span_err!
(
session
,
directive
.span
,
E0364
,
"{}"
,
&
msg
)
.span_note
(
directive
.span
,
&
note_msg
)
.emit
();
};
let
extern_crate_lint
=
||
{
let
msg
=
format!
(
"extern crate `{}` is private, and cannot be reexported
\
(error E0364), consider declaring with `pub`"
,
name
);
session
.add_lint
(
PRIVATE_IN_PUBLIC
,
directive
.id
,
directive
.span
,
msg
);
};
match
(
value_result
,
type_result
)
{
// All namespaces must be re-exported with extra visibility for an error to occur.
(
Ok
(
value_binding
),
Ok
(
type_binding
))
=>
{
let
mut
reexport_error
=
None
;
let
mut
any_successful_reexport
=
false
;
self
.per_ns
(|
this
,
ns
|
{
if
let
Ok
(
binding
)
=
result
[
ns
]
.get
()
{
let
vis
=
directive
.vis
.get
();
if
!
value_binding
.pseudo_vis
()
.is_at_least
(
vis
,
self
)
&&
!
type_binding
.pseudo_vis
()
.is_at_least
(
vis
,
self
)
{
reexport_error
();
}
else
if
type_binding
.is_extern_crate
()
&&
!
type_binding
.vis
.is_at_least
(
vis
,
self
)
{
extern_crate_lint
();
}
}
(
Ok
(
binding
),
_
)
if
!
binding
.pseudo_vis
()
.is_at_least
(
directive
.vis
.get
(),
self
)
=>
{
reexport_error
();
}
(
_
,
Ok
(
binding
))
if
!
binding
.pseudo_vis
()
.is_at_least
(
directive
.vis
.get
(),
self
)
=>
{
if
binding
.is_extern_crate
()
{
extern_crate_lint
();
if
!
binding
.pseudo_vis
()
.is_at_least
(
vis
,
this
)
{
reexport_error
=
Some
((
ns
,
binding
));
}
else
{
struct_span_err!
(
self
.session
,
directive
.span
,
E0365
,
"`{}` is private, and cannot be reexported"
,
name
)
.span_label
(
directive
.span
,
&
format!
(
"reexport of private `{}`"
,
name
))
.note
(
&
format!
(
"consider declaring type or module `{}` with `pub`"
,
name
))
.emit
();
any_successful_reexport
=
true
;
}
}
});
_
=>
{}
// All namespaces must be re-exported with extra visibility for an error to occur.
if
!
any_successful_reexport
{
let
(
ns
,
binding
)
=
reexport_error
.unwrap
();
if
ns
==
TypeNS
&&
binding
.is_extern_crate
()
{
let
msg
=
format!
(
"extern crate `{}` is private, and cannot be reexported
\
(error E0364), consider declaring with `pub`"
,
name
);
self
.session
.add_lint
(
PRIVATE_IN_PUBLIC
,
directive
.id
,
directive
.span
,
msg
);
}
else
if
ns
==
TypeNS
{
struct_span_err!
(
self
.session
,
directive
.span
,
E0365
,
"`{}` is private, and cannot be reexported"
,
name
)
.span_label
(
directive
.span
,
&
format!
(
"reexport of private `{}`"
,
name
))
.note
(
&
format!
(
"consider declaring type or module `{}` with `pub`"
,
name
))
.emit
();
}
else
{
let
msg
=
format!
(
"`{}` is private, and cannot be reexported"
,
name
);
let
note_msg
=
format!
(
"consider marking `{}` as `pub` in the imported module"
,
name
);
struct_span_err!
(
self
.session
,
directive
.span
,
E0364
,
"{}"
,
&
msg
)
.span_note
(
directive
.span
,
&
note_msg
)
.emit
();
}
}
// Record what this import resolves to for later uses in documentation,
// this may resolve to either a value or a type, but for documentation
// purposes it's good enough to just favor one over the other.
let
def
=
match
type_result
.ok
()
.map
(
NameBinding
::
def
)
{
Some
(
def
)
=>
def
,
None
=>
value_result
.ok
()
.map
(
NameBinding
::
def
)
.unwrap
(),
};
let
path_resolution
=
PathResolution
::
new
(
def
);
self
.def_map
.insert
(
directive
.id
,
path_resolution
);
self
.per_ns
(|
this
,
ns
|
if
let
Some
(
binding
)
=
result
[
ns
]
.get
()
.ok
()
{
this
.def_map
.entry
(
directive
.id
)
.or_insert
(
PathResolution
::
new
(
binding
.def
()));
});
debug!
(
"(resolving single import) successfully resolved import"
);
return
Success
(());
...
...
src/test/compile-fail/blind-item-block-item-shadow.rs
浏览文件 @
b25c063c
...
...
@@ -14,6 +14,6 @@ fn main() {
{
struct
Bar
;
use
foo
::
Bar
;
//~^ ERROR a
valu
e named `Bar` has already been defined in this block
//~^ ERROR a
typ
e named `Bar` has already been defined in this block
}
}
src/test/compile-fail/double-type-import.rs
浏览文件 @
b25c063c
...
...
@@ -11,7 +11,7 @@
mod
foo
{
pub
use
self
::
bar
::
X
;
use
self
::
bar
::
X
;
//~^ ERROR a
valu
e named `X` has already been imported in this module
//~^ ERROR a
typ
e named `X` has already been imported in this module
mod
bar
{
pub
struct
X
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录