Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
a24edb9b
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,发现更多精彩内容 >>
未验证
提交
a24edb9b
编写于
11月 16, 2017
作者:
O
Oliver Schneider
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add structured suggestions for trait imports
上级
ef94d5c1
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
166 addition
and
38 deletion
+166
-38
src/librustc_resolve/lib.rs
src/librustc_resolve/lib.rs
+14
-7
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/method/suggest.rs
+108
-9
src/test/ui/impl-trait/no-method-suggested-traits.stderr
src/test/ui/impl-trait/no-method-suggested-traits.stderr
+36
-18
src/test/ui/issue-35976.stderr
src/test/ui/issue-35976.stderr
+4
-2
src/test/ui/trait-method-private.stderr
src/test/ui/trait-method-private.stderr
+4
-2
未找到文件。
src/librustc_resolve/lib.rs
浏览文件 @
a24edb9b
...
...
@@ -588,6 +588,18 @@ struct UsePlacementFinder {
found_use
:
bool
,
}
impl
UsePlacementFinder
{
fn
check
(
krate
:
&
Crate
,
target_module
:
NodeId
)
->
(
Option
<
Span
>
,
bool
)
{
let
mut
finder
=
UsePlacementFinder
{
target_module
,
span
:
None
,
found_use
:
false
,
};
visit
::
walk_crate
(
&
mut
finder
,
krate
);
(
finder
.span
,
finder
.found_use
)
}
}
impl
<
'tcx
>
Visitor
<
'tcx
>
for
UsePlacementFinder
{
fn
visit_mod
(
&
mut
self
,
...
...
@@ -3588,14 +3600,9 @@ fn report_errors(&mut self, krate: &Crate) {
fn
report_with_use_injections
(
&
mut
self
,
krate
:
&
Crate
)
{
for
UseError
{
mut
err
,
candidates
,
node_id
,
better
}
in
self
.use_injections
.drain
(
..
)
{
let
mut
finder
=
UsePlacementFinder
{
target_module
:
node_id
,
span
:
None
,
found_use
:
false
,
};
visit
::
walk_crate
(
&
mut
finder
,
krate
);
let
(
span
,
found_use
)
=
UsePlacementFinder
::
check
(
krate
,
node_id
);
if
!
candidates
.is_empty
()
{
show_candidates
(
&
mut
err
,
finder
.span
,
&
candidates
,
better
,
finder
.
found_use
);
show_candidates
(
&
mut
err
,
span
,
&
candidates
,
better
,
found_use
);
}
err
.emit
();
}
...
...
src/librustc_typeck/check/method/suggest.rs
浏览文件 @
a24edb9b
...
...
@@ -340,16 +340,35 @@ fn suggest_use_candidates(&self,
err
:
&
mut
DiagnosticBuilder
,
mut
msg
:
String
,
candidates
:
Vec
<
DefId
>
)
{
let
limit
=
if
candidates
.len
()
==
5
{
5
}
else
{
4
};
for
(
i
,
trait_did
)
in
candidates
.iter
()
.take
(
limit
)
.enumerate
()
{
msg
.push_str
(
&
format!
(
"
\n
candidate #{}: `use {};`"
,
i
+
1
,
self
.tcx
.item_path_str
(
*
trait_did
)));
}
if
candidates
.len
()
>
limit
{
msg
.push_str
(
&
format!
(
"
\n
and {} others"
,
candidates
.len
()
-
limit
));
let
module_did
=
self
.tcx.hir
.get_module_parent
(
self
.body_id
);
let
module_id
=
self
.tcx.hir
.as_local_node_id
(
module_did
)
.unwrap
();
let
krate
=
self
.tcx.hir
.krate
();
let
(
span
,
found_use
)
=
UsePlacementFinder
::
check
(
self
.tcx
,
krate
,
module_id
);
if
let
Some
(
span
)
=
span
{
let
path_strings
=
candidates
.iter
()
.map
(|
did
|
{
// produce an additional newline to separate the new use statement
// from the directly following item.
let
additional_newline
=
if
found_use
{
""
}
else
{
"
\n
"
};
format!
(
"use {};
\n
{}"
,
self
.tcx
.item_path_str
(
*
did
),
additional_newline
)
})
.collect
();
err
.span_suggestions
(
span
,
&
msg
,
path_strings
);
}
else
{
let
limit
=
if
candidates
.len
()
==
5
{
5
}
else
{
4
};
for
(
i
,
trait_did
)
in
candidates
.iter
()
.take
(
limit
)
.enumerate
()
{
msg
.push_str
(
&
format!
(
"
\n
candidate #{}: `use {};`"
,
i
+
1
,
self
.tcx
.item_path_str
(
*
trait_did
)));
}
if
candidates
.len
()
>
limit
{
msg
.push_str
(
&
format!
(
"
\n
and {} others"
,
candidates
.len
()
-
limit
));
}
err
.note
(
&
msg
[
..
]);
}
err
.note
(
&
msg
[
..
]);
}
fn
suggest_valid_traits
(
&
self
,
...
...
@@ -604,3 +623,83 @@ fn next(&mut self) -> Option<TraitInfo> {
})
}
}
struct
UsePlacementFinder
<
'a
,
'tcx
:
'a
,
'gcx
:
'tcx
>
{
target_module
:
ast
::
NodeId
,
span
:
Option
<
Span
>
,
found_use
:
bool
,
tcx
:
TyCtxt
<
'a
,
'gcx
,
'tcx
>
}
impl
<
'a
,
'tcx
,
'gcx
>
UsePlacementFinder
<
'a
,
'tcx
,
'gcx
>
{
fn
check
(
tcx
:
TyCtxt
<
'a
,
'gcx
,
'tcx
>
,
krate
:
&
'tcx
hir
::
Crate
,
target_module
:
ast
::
NodeId
,
)
->
(
Option
<
Span
>
,
bool
)
{
let
mut
finder
=
UsePlacementFinder
{
target_module
,
span
:
None
,
found_use
:
false
,
tcx
,
};
hir
::
intravisit
::
walk_crate
(
&
mut
finder
,
krate
);
(
finder
.span
,
finder
.found_use
)
}
}
impl
<
'a
,
'tcx
,
'gcx
>
hir
::
intravisit
::
Visitor
<
'tcx
>
for
UsePlacementFinder
<
'a
,
'tcx
,
'gcx
>
{
fn
visit_mod
(
&
mut
self
,
module
:
&
'tcx
hir
::
Mod
,
_
:
Span
,
node_id
:
ast
::
NodeId
,
)
{
if
self
.span
.is_some
()
{
return
;
}
if
node_id
!=
self
.target_module
{
hir
::
intravisit
::
walk_mod
(
self
,
module
,
node_id
);
return
;
}
// find a use statement
for
item_id
in
&
module
.item_ids
{
let
item
=
self
.tcx.hir
.expect_item
(
item_id
.id
);
match
item
.node
{
hir
::
ItemUse
(
..
)
=>
{
// don't suggest placing a use before the prelude
// import or other generated ones
if
item
.span
.ctxt
()
.outer
()
.expn_info
()
.is_none
()
{
self
.span
=
Some
(
item
.span
.with_hi
(
item
.span
.lo
()));
self
.found_use
=
true
;
return
;
}
},
// don't place use before extern crate
hir
::
ItemExternCrate
(
_
)
=>
{}
// but place them before the first other item
_
=>
if
self
.span
.map_or
(
true
,
|
span
|
item
.span
<
span
)
{
if
item
.span
.ctxt
()
.outer
()
.expn_info
()
.is_none
()
{
// don't insert between attributes and an item
if
item
.attrs
.is_empty
()
{
self
.span
=
Some
(
item
.span
.with_hi
(
item
.span
.lo
()));
}
else
{
// find the first attribute on the item
for
attr
in
&
item
.attrs
{
if
self
.span
.map_or
(
true
,
|
span
|
attr
.span
<
span
)
{
self
.span
=
Some
(
attr
.span
.with_hi
(
attr
.span
.lo
()));
}
}
}
}
},
}
}
}
fn
nested_visit_map
<
'this
>
(
&
'this
mut
self
)
->
hir
::
intravisit
::
NestedVisitorMap
<
'this
,
'tcx
>
{
hir
::
intravisit
::
NestedVisitorMap
::
None
}
}
src/test/ui/impl-trait/no-method-suggested-traits.stderr
浏览文件 @
a24edb9b
...
...
@@ -5,11 +5,16 @@ error[E0599]: no method named `method` found for type `u32` in the current scope
| ^^^^^^
|
= help: items from traits can only be used if the trait is in scope
= note: the following traits are implemented but not in scope, perhaps add a `use` for one of them:
candidate #1: `use foo::Bar;`
candidate #2: `use no_method_suggested_traits::foo::PubPub;`
candidate #3: `use no_method_suggested_traits::qux::PrivPub;`
candidate #4: `use no_method_suggested_traits::Reexported;`
help: the following traits are implemented but not in scope, perhaps add a `use` for one of them:
|
14 | use foo::Bar;
|
14 | use no_method_suggested_traits::foo::PubPub;
|
14 | use no_method_suggested_traits::qux::PrivPub;
|
14 | use no_method_suggested_traits::Reexported;
|
error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&u32>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:38:44
...
...
@@ -18,11 +23,16 @@ error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::box
| ^^^^^^
|
= help: items from traits can only be used if the trait is in scope
= note: the following traits are implemented but not in scope, perhaps add a `use` for one of them:
candidate #1: `use foo::Bar;`
candidate #2: `use no_method_suggested_traits::foo::PubPub;`
candidate #3: `use no_method_suggested_traits::qux::PrivPub;`
candidate #4: `use no_method_suggested_traits::Reexported;`
help: the following traits are implemented but not in scope, perhaps add a `use` for one of them:
|
14 | use foo::Bar;
|
14 | use no_method_suggested_traits::foo::PubPub;
|
14 | use no_method_suggested_traits::qux::PrivPub;
|
14 | use no_method_suggested_traits::Reexported;
|
error[E0599]: no method named `method` found for type `char` in the current scope
--> $DIR/no-method-suggested-traits.rs:44:9
...
...
@@ -31,8 +41,10 @@ error[E0599]: no method named `method` found for type `char` in the current scop
| ^^^^^^
|
= help: items from traits can only be used if the trait is in scope
= note: the following trait is implemented but not in scope, perhaps add a `use` for it:
candidate #1: `use foo::Bar;`
help: the following trait is implemented but not in scope, perhaps add a `use` for it:
|
14 | use foo::Bar;
|
error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&char>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:48:43
...
...
@@ -41,8 +53,10 @@ error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::box
| ^^^^^^
|
= help: items from traits can only be used if the trait is in scope
= note: the following trait is implemented but not in scope, perhaps add a `use` for it:
candidate #1: `use foo::Bar;`
help: the following trait is implemented but not in scope, perhaps add a `use` for it:
|
14 | use foo::Bar;
|
error[E0599]: no method named `method` found for type `i32` in the current scope
--> $DIR/no-method-suggested-traits.rs:53:10
...
...
@@ -51,8 +65,10 @@ error[E0599]: no method named `method` found for type `i32` in the current scope
| ^^^^^^
|
= help: items from traits can only be used if the trait is in scope
= note: the following trait is implemented but not in scope, perhaps add a `use` for it:
candidate #1: `use no_method_suggested_traits::foo::PubPub;`
help: the following trait is implemented but not in scope, perhaps add a `use` for it:
|
14 | use no_method_suggested_traits::foo::PubPub;
|
error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&i32>>` in the current scope
--> $DIR/no-method-suggested-traits.rs:57:44
...
...
@@ -61,8 +77,10 @@ error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::box
| ^^^^^^
|
= help: items from traits can only be used if the trait is in scope
= note: the following trait is implemented but not in scope, perhaps add a `use` for it:
candidate #1: `use no_method_suggested_traits::foo::PubPub;`
help: the following trait is implemented but not in scope, perhaps add a `use` for it:
|
14 | use no_method_suggested_traits::foo::PubPub;
|
error[E0599]: no method named `method` found for type `Foo` in the current scope
--> $DIR/no-method-suggested-traits.rs:62:9
...
...
src/test/ui/issue-35976.stderr
浏览文件 @
a24edb9b
...
...
@@ -4,8 +4,10 @@ error: the `wait` method cannot be invoked on a trait object
24 | arg.wait();
| ^^^^
|
= note: another candidate was found in the following trait, perhaps add a `use` for it:
candidate #1: `use private::Future;`
help: another candidate was found in the following trait, perhaps add a `use` for it:
|
11 | use private::Future;
|
error: aborting due to previous error
src/test/ui/trait-method-private.stderr
浏览文件 @
a24edb9b
...
...
@@ -5,8 +5,10 @@ error[E0624]: method `method` is private
| ^^^^^^
|
= help: items from traits can only be used if the trait is in scope
= note: the following trait is implemented but not in scope, perhaps add a `use` for it:
candidate #1: `use inner::Bar;`
help: the following trait is implemented but not in scope, perhaps add a `use` for it:
|
11 | use inner::Bar;
|
error: aborting due to previous error
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录