Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
90f54d00
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,发现更多精彩内容 >>
提交
90f54d00
编写于
8月 06, 2017
作者:
G
Guillaume Gomez
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Improve union unused field detection
上级
59fcac6f
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
43 addition
and
42 deletion
+43
-42
src/librustc/hir/intravisit.rs
src/librustc/hir/intravisit.rs
+1
-1
src/librustc/middle/dead.rs
src/librustc/middle/dead.rs
+26
-29
src/test/ui/union-fields.rs
src/test/ui/union-fields.rs
+16
-12
未找到文件。
src/librustc/hir/intravisit.rs
浏览文件 @
90f54d00
...
...
@@ -877,7 +877,7 @@ pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'
pub
fn
walk_struct_def
<
'v
,
V
:
Visitor
<
'v
>>
(
visitor
:
&
mut
V
,
struct_definition
:
&
'v
VariantData
)
{
visitor
.visit_id
(
struct_definition
.id
());
walk_list!
(
visitor
,
visit_struct_field
,
struct_definition
.fields
()
.iter
()
.rev
()
);
walk_list!
(
visitor
,
visit_struct_field
,
struct_definition
.fields
());
}
pub
fn
walk_struct_field
<
'v
,
V
:
Visitor
<
'v
>>
(
visitor
:
&
mut
V
,
struct_field
:
&
'v
StructField
)
{
...
...
src/librustc/middle/dead.rs
浏览文件 @
90f54d00
...
...
@@ -189,6 +189,24 @@ fn visit_node(&mut self, node: &hir_map::Node<'tcx>) {
self
.struct_has_extern_repr
=
had_extern_repr
;
self
.inherited_pub_visibility
=
had_inherited_pub_visibility
;
}
fn
mark_as_used_if_union
(
&
mut
self
,
did
:
DefId
)
{
if
let
Some
(
node_id
)
=
self
.tcx.hir
.as_local_node_id
(
did
)
{
match
self
.tcx.hir
.find
(
node_id
)
{
Some
(
hir_map
::
NodeItem
(
item
))
=>
match
item
.node
{
Item_
::
ItemUnion
(
ref
variant
,
_
)
=>
{
if
variant
.fields
()
.len
()
>
1
{
for
field
in
variant
.fields
()
{
self
.live_symbols
.insert
(
field
.id
);
}
}
}
_
=>
{}
},
_
=>
{}
}
}
}
}
impl
<
'a
,
'tcx
>
Visitor
<
'tcx
>
for
MarkSymbolVisitor
<
'a
,
'tcx
>
{
...
...
@@ -221,6 +239,11 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
hir
::
ExprPath
(
ref
qpath
@
hir
::
QPath
::
TypeRelative
(
..
))
=>
{
let
def
=
self
.tables
.qpath_def
(
qpath
,
expr
.id
);
self
.handle_definition
(
def
);
self
.mark_as_used_if_union
(
def
.def_id
());
}
hir
::
ExprPath
(
ref
qpath
@
hir
::
QPath
::
Resolved
(
..
))
=>
{
let
def
=
self
.tables
.qpath_def
(
qpath
,
expr
.id
);
self
.mark_as_used_if_union
(
def
.def_id
());
}
hir
::
ExprMethodCall
(
..
)
=>
{
self
.lookup_and_handle_method
(
expr
.id
);
...
...
@@ -422,7 +445,6 @@ fn get_struct_ctor_id(item: &hir::Item) -> Option<ast::NodeId> {
struct
DeadVisitor
<
'a
,
'tcx
:
'a
>
{
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
live_symbols
:
Box
<
FxHashSet
<
ast
::
NodeId
>>
,
need_check_next_union_field
:
bool
,
}
impl
<
'a
,
'tcx
>
DeadVisitor
<
'a
,
'tcx
>
{
...
...
@@ -538,16 +560,6 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
}
}
fn
visit_variant_data
(
&
mut
self
,
s
:
&
'tcx
hir
::
VariantData
,
_
:
ast
::
Name
,
_
:
&
'tcx
hir
::
Generics
,
_
parent_id
:
ast
::
NodeId
,
_
:
syntax_pos
::
Span
)
{
self
.need_check_next_union_field
=
true
;
intravisit
::
walk_struct_def
(
self
,
s
)
}
fn
visit_variant
(
&
mut
self
,
variant
:
&
'tcx
hir
::
Variant
,
g
:
&
'tcx
hir
::
Generics
,
...
...
@@ -568,23 +580,9 @@ fn visit_foreign_item(&mut self, fi: &'tcx hir::ForeignItem) {
}
fn
visit_struct_field
(
&
mut
self
,
field
:
&
'tcx
hir
::
StructField
)
{
if
self
.need_check_next_union_field
{
if
self
.should_warn_about_field
(
&
field
)
{
self
.warn_dead_code
(
field
.id
,
field
.span
,
field
.name
,
"field"
);
}
else
{
let
did
=
self
.tcx.hir
.get_parent_did
(
field
.id
);
if
let
Some
(
node_id
)
=
self
.tcx.hir
.as_local_node_id
(
did
)
{
match
self
.tcx.hir
.find
(
node_id
)
{
Some
(
hir_map
::
NodeItem
(
item
))
=>
match
item
.node
{
// If this is an union's field, it means all previous fields
// have been used as well so no need to check further.
Item_
::
ItemUnion
(
_
,
_
)
=>
self
.need_check_next_union_field
=
false
,
_
=>
{}
},
_
=>
{}
}
}
}
if
self
.should_warn_about_field
(
&
field
)
{
self
.warn_dead_code
(
field
.id
,
field
.span
,
field
.name
,
"field"
);
}
intravisit
::
walk_struct_field
(
self
,
field
);
}
...
...
@@ -630,7 +628,6 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let
mut
visitor
=
DeadVisitor
{
tcx
:
tcx
,
live_symbols
:
live_symbols
,
need_check_next_union_field
:
true
,
};
intravisit
::
walk_crate
(
&
mut
visitor
,
krate
);
}
src/test/ui/union-fields.rs
浏览文件 @
90f54d00
...
...
@@ -10,20 +10,24 @@
#![deny(dead_code)]
union
U
{
x
:
u32
,
y
:
f32
,
union
U1
{
a
:
u8
,
// should not be reported
b
:
u8
,
// should not be reported
c
:
u8
,
// should be reported
}
struct
V
{
x
:
u32
,
y
:
u32
,
union
U2
{
a
:
u8
,
// should be reported
b
:
u8
,
// should not be reported
c
:
u8
,
// should not be reported
}
union
NoDropLike
{
a
:
u8
}
// should be reported as unused
fn
main
()
{
let
u
=
U
{
x
:
0x3f800000
};
let
_
f
=
unsafe
{
u
.y
};
let
v
=
V
{
x
:
0
,
y
:
0
};
println!
(
"{}"
,
v
.x
);
}
let
u
=
U1
{
a
:
0
};
let
_
a
=
unsafe
{
u
.b
};
let
u
=
U2
{
c
:
0
};
let
_
b
=
unsafe
{
u
.b
};
let
_u
=
NoDropLike
{
a
:
10
};
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录