Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
c57f0a72
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,发现更多精彩内容 >>
提交
c57f0a72
编写于
10月 27, 2018
作者:
V
Vadim Petrochenkov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
resolve: Desugar empty import groups into synthetic dummy imports
so that they are correctly resolved on 2018 edition
上级
1f257bd0
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
51 addition
and
98 deletion
+51
-98
src/librustc/hir/lowering.rs
src/librustc/hir/lowering.rs
+2
-1
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/build_reduced_graph.rs
+29
-4
src/librustc_resolve/lib.rs
src/librustc_resolve/lib.rs
+7
-65
src/test/ui/issues/issue-28388-1.rs
src/test/ui/issues/issue-28388-1.rs
+1
-1
src/test/ui/issues/issue-28388-1.stderr
src/test/ui/issues/issue-28388-1.stderr
+4
-4
src/test/ui/resolve/resolve-bad-import-prefix.rs
src/test/ui/resolve/resolve-bad-import-prefix.rs
+3
-3
src/test/ui/resolve/resolve-bad-import-prefix.stderr
src/test/ui/resolve/resolve-bad-import-prefix.stderr
+5
-20
未找到文件。
src/librustc/hir/lowering.rs
浏览文件 @
c57f0a72
...
...
@@ -3133,7 +3133,8 @@ fn lower_use_tree(
// Privatize the degenerate import base, used only to check
// the stability of `use a::{};`, to avoid it showing up as
// a re-export by accident when `pub`, e.g. in documentation.
let
path
=
P
(
self
.lower_path
(
id
,
&
prefix
,
ParamMode
::
Explicit
));
let
def
=
self
.expect_full_def_from_use
(
id
)
.next
()
.unwrap_or
(
Def
::
Err
);
let
path
=
P
(
self
.lower_path_extra
(
def
,
&
prefix
,
None
,
ParamMode
::
Explicit
,
None
));
*
vis
=
respan
(
prefix
.span
.shrink_to_lo
(),
hir
::
VisibilityKind
::
Inherited
);
hir
::
ItemKind
::
Use
(
path
,
hir
::
UseKind
::
ListStem
)
}
...
...
src/librustc_resolve/build_reduced_graph.rs
浏览文件 @
c57f0a72
...
...
@@ -253,6 +253,10 @@ fn build_reduced_graph_for_use_tree(
uniform_paths_canary_emitted
=
true
;
}
let
empty_for_self
=
|
prefix
:
&
[
Segment
]|
{
prefix
.is_empty
()
||
prefix
.len
()
==
1
&&
prefix
[
0
]
.ident.name
==
keywords
::
CrateRoot
.name
()
};
match
use_tree
.kind
{
ast
::
UseTreeKind
::
Simple
(
rename
,
..
)
=>
{
let
mut
ident
=
use_tree
.ident
();
...
...
@@ -265,10 +269,7 @@ fn build_reduced_graph_for_use_tree(
if
source
.ident.name
==
keywords
::
SelfValue
.name
()
{
type_ns_only
=
true
;
let
empty_prefix
=
module_path
.last
()
.map_or
(
true
,
|
seg
|
{
seg
.ident.name
==
keywords
::
CrateRoot
.name
()
});
if
empty_prefix
{
if
empty_for_self
(
&
module_path
)
{
resolve_error
(
self
,
use_tree
.span
,
...
...
@@ -400,6 +401,30 @@ fn build_reduced_graph_for_use_tree(
parent_scope
.clone
(),
item
,
vis
,
root_span
,
);
}
// Empty groups `a::b::{}` are turned into synthetic `self` imports
// `a::b::c::{self as _}`, so that their prefixes are correctly
// resolved and checked for privacy/stability/etc.
if
items
.is_empty
()
&&
!
empty_for_self
(
&
prefix
)
{
let
new_span
=
prefix
[
prefix
.len
()
-
1
]
.ident.span
;
let
tree
=
ast
::
UseTree
{
prefix
:
ast
::
Path
::
from_ident
(
Ident
::
new
(
keywords
::
SelfValue
.name
(),
new_span
)
),
kind
:
ast
::
UseTreeKind
::
Simple
(
Some
(
Ident
::
new
(
keywords
::
Underscore
.name
()
.gensymed
(),
new_span
)),
ast
::
DUMMY_NODE_ID
,
ast
::
DUMMY_NODE_ID
,
),
span
:
use_tree
.span
,
};
self
.build_reduced_graph_for_use_tree
(
// This particular use tree
&
tree
,
id
,
&
prefix
,
true
,
uniform_paths_canary_emitted
,
// The whole `use` item
parent_scope
.clone
(),
item
,
ty
::
Visibility
::
Invisible
,
root_span
,
);
}
}
}
}
...
...
src/librustc_resolve/lib.rs
浏览文件 @
c57f0a72
...
...
@@ -482,15 +482,13 @@ enum PathSource<'a> {
TraitItem
(
Namespace
),
// Path in `pub(path)`
Visibility
,
// Path in `use a::b::{...};`
ImportPrefix
,
}
impl
<
'a
>
PathSource
<
'a
>
{
fn
namespace
(
self
)
->
Namespace
{
match
self
{
PathSource
::
Type
|
PathSource
::
Trait
(
_
)
|
PathSource
::
Struct
|
PathSource
::
Visibility
|
PathSource
::
ImportPrefix
=>
TypeNS
,
PathSource
::
Visibility
=>
TypeNS
,
PathSource
::
Expr
(
..
)
|
PathSource
::
Pat
|
PathSource
::
TupleStruct
=>
ValueNS
,
PathSource
::
TraitItem
(
ns
)
=>
ns
,
}
...
...
@@ -498,7 +496,7 @@ fn namespace(self) -> Namespace {
fn
global_by_default
(
self
)
->
bool
{
match
self
{
PathSource
::
Visibility
|
PathSource
::
ImportPrefix
=>
true
,
PathSource
::
Visibility
=>
true
,
PathSource
::
Type
|
PathSource
::
Expr
(
..
)
|
PathSource
::
Pat
|
PathSource
::
Struct
|
PathSource
::
TupleStruct
|
PathSource
::
Trait
(
_
)
|
PathSource
::
TraitItem
(
..
)
=>
false
,
...
...
@@ -510,7 +508,7 @@ fn defer_to_typeck(self) -> bool {
PathSource
::
Type
|
PathSource
::
Expr
(
..
)
|
PathSource
::
Pat
|
PathSource
::
Struct
|
PathSource
::
TupleStruct
=>
true
,
PathSource
::
Trait
(
_
)
|
PathSource
::
TraitItem
(
..
)
|
PathSource
::
Visibility
|
PathSource
::
ImportPrefix
=>
false
,
PathSource
::
Visibility
=>
false
,
}
}
...
...
@@ -522,7 +520,6 @@ fn descr_expected(self) -> &'static str {
PathSource
::
Struct
=>
"struct, variant or union type"
,
PathSource
::
TupleStruct
=>
"tuple struct/variant"
,
PathSource
::
Visibility
=>
"module"
,
PathSource
::
ImportPrefix
=>
"module or enum"
,
PathSource
::
TraitItem
(
ns
)
=>
match
ns
{
TypeNS
=>
"associated type"
,
ValueNS
=>
"method or associated constant"
,
...
...
@@ -587,10 +584,6 @@ fn is_expected(self, def: Def) -> bool {
Def
::
AssociatedTy
(
..
)
if
ns
==
TypeNS
=>
true
,
_
=>
false
,
},
PathSource
::
ImportPrefix
=>
match
def
{
Def
::
Mod
(
..
)
|
Def
::
Enum
(
..
)
=>
true
,
_
=>
false
,
},
PathSource
::
Visibility
=>
match
def
{
Def
::
Mod
(
..
)
=>
true
,
_
=>
false
,
...
...
@@ -626,8 +619,8 @@ fn error_code(self, has_unexpected_resolution: bool) -> &'static str {
(
PathSource
::
Pat
,
false
)
|
(
PathSource
::
TupleStruct
,
false
)
=>
"E0531"
,
(
PathSource
::
TraitItem
(
..
),
true
)
=>
"E0575"
,
(
PathSource
::
TraitItem
(
..
),
false
)
=>
"E0576"
,
(
PathSource
::
Visibility
,
true
)
|
(
PathSource
::
ImportPrefix
,
true
)
=>
"E0577"
,
(
PathSource
::
Visibility
,
false
)
|
(
PathSource
::
ImportPrefix
,
false
)
=>
"E0578"
,
(
PathSource
::
Visibility
,
true
)
=>
"E0577"
,
(
PathSource
::
Visibility
,
false
)
=>
"E0578"
,
}
}
}
...
...
@@ -2350,16 +2343,8 @@ fn resolve_item(&mut self, item: &Item) {
});
}
ItemKind
::
Use
(
ref
use_tree
)
=>
{
// Imports are resolved as global by default, add starting root segment.
let
path
=
Path
{
segments
:
use_tree
.prefix
.make_root
()
.into_iter
()
.collect
(),
span
:
use_tree
.span
,
};
self
.resolve_use_tree
(
item
.id
,
use_tree
.span
,
item
.id
,
use_tree
,
&
path
);
}
ItemKind
::
ExternCrate
(
_
)
|
ItemKind
::
MacroDef
(
..
)
|
ItemKind
::
GlobalAsm
(
_
)
=>
{
ItemKind
::
Use
(
..
)
|
ItemKind
::
ExternCrate
(
..
)
|
ItemKind
::
MacroDef
(
..
)
|
ItemKind
::
GlobalAsm
(
..
)
=>
{
// do nothing, these are just around to be encoded
}
...
...
@@ -2367,49 +2352,6 @@ fn resolve_item(&mut self, item: &Item) {
}
}
/// For the most part, use trees are desugared into `ImportDirective` instances
/// when building the reduced graph (see `build_reduced_graph_for_use_tree`). But
/// there is one special case we handle here: an empty nested import like
/// `a::{b::{}}`, which desugares into...no import directives.
fn
resolve_use_tree
(
&
mut
self
,
root_id
:
NodeId
,
root_span
:
Span
,
id
:
NodeId
,
use_tree
:
&
ast
::
UseTree
,
prefix
:
&
Path
,
)
{
match
use_tree
.kind
{
ast
::
UseTreeKind
::
Nested
(
ref
items
)
=>
{
let
path
=
Path
{
segments
:
prefix
.segments
.iter
()
.chain
(
use_tree
.prefix.segments
.iter
())
.cloned
()
.collect
(),
span
:
prefix
.span
.to
(
use_tree
.prefix.span
),
};
if
items
.is_empty
()
{
// Resolve prefix of an import with empty braces (issue #28388).
self
.smart_resolve_path_with_crate_lint
(
id
,
None
,
&
path
,
PathSource
::
ImportPrefix
,
CrateLint
::
UsePath
{
root_id
,
root_span
},
);
}
else
{
for
&
(
ref
tree
,
nested_id
)
in
items
{
self
.resolve_use_tree
(
root_id
,
root_span
,
nested_id
,
tree
,
&
path
);
}
}
}
ast
::
UseTreeKind
::
Simple
(
..
)
=>
{},
ast
::
UseTreeKind
::
Glob
=>
{},
}
}
fn
with_type_parameter_rib
<
'b
,
F
>
(
&
'b
mut
self
,
type_parameters
:
TypeParameters
<
'a
,
'b
>
,
f
:
F
)
where
F
:
FnOnce
(
&
mut
Resolver
)
{
...
...
src/test/ui/issues/issue-28388-1.rs
浏览文件 @
c57f0a72
...
...
@@ -10,6 +10,6 @@
// Prefix in imports with empty braces should be resolved and checked privacy, stability, etc.
use
foo
::{};
//~ ERROR
cannot find module or enum `foo` in the crate root
use
foo
::{};
//~ ERROR
unresolved import `foo`
fn
main
()
{}
src/test/ui/issues/issue-28388-1.stderr
浏览文件 @
c57f0a72
error[E0
578]: cannot find module or enum `foo` in the crate root
error[E0
432]: unresolved import `foo`
--> $DIR/issue-28388-1.rs:13:5
|
LL | use foo::{}; //~ ERROR
cannot find module or enum `foo` in the crate root
| ^^^
not found in the crat
e root
LL | use foo::{}; //~ ERROR
unresolved import `foo`
| ^^^
^^^^ no `foo` in th
e root
error: aborting due to previous error
For more information about this error, try `rustc --explain E0
578
`.
For more information about this error, try `rustc --explain E0
432
`.
src/test/ui/resolve/resolve-bad-import-prefix.rs
浏览文件 @
c57f0a72
...
...
@@ -17,8 +17,8 @@ trait Tr {}
use
::{};
// OK
use
m
::{};
// OK
use
E
::{};
// OK
use
S
::{};
//
~ ERROR expected module or enum, found struct `S`
use
Tr
::{};
//
~ ERROR expected module or enum, found trait `Tr`
use
Nonexistent
::{};
//~ ERROR
cannot find module or enum `Nonexistent` in the crate root
use
S
::{};
//
FIXME, this and `use S::{self};` should be an error
use
Tr
::{};
//
FIXME, this and `use Tr::{self};` should be an error
use
Nonexistent
::{};
//~ ERROR
unresolved import `Nonexistent`
fn
main
()
{}
src/test/ui/resolve/resolve-bad-import-prefix.stderr
浏览文件 @
c57f0a72
error[E0577]: expected module or enum, found struct `S`
--> $DIR/resolve-bad-import-prefix.rs:20:5
|
LL | use S::{}; //~ ERROR expected module or enum, found struct `S`
| -^^^^
| |
| did you mean `E`?
error[E0577]: expected module or enum, found trait `Tr`
--> $DIR/resolve-bad-import-prefix.rs:21:5
|
LL | use Tr::{}; //~ ERROR expected module or enum, found trait `Tr`
| ^^^^^^ not a module or enum
error[E0578]: cannot find module or enum `Nonexistent` in the crate root
error[E0432]: unresolved import `Nonexistent`
--> $DIR/resolve-bad-import-prefix.rs:22:5
|
LL | use Nonexistent::{}; //~ ERROR
cannot find module or enum `Nonexistent` in the crate root
| ^^^^^^^^^^^
not found in the crat
e root
LL | use Nonexistent::{}; //~ ERROR
unresolved import `Nonexistent`
| ^^^^^^^^^^^
^^^^ no `Nonexistent` in th
e root
error: aborting due to
3 previous errors
error: aborting due to
previous error
Some errors occurred: E0577, E0578.
For more information about an error, try `rustc --explain E0577`.
For more information about this error, try `rustc --explain E0432`.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录