Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
f5370faa
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
f5370faa
编写于
5月 03, 2020
作者:
D
Dylan MacKenzie
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add `CheckLiveDrops` pass
上级
a77f046c
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
126 addition
and
0 deletion
+126
-0
src/librustc_mir/transform/check_consts/mod.rs
src/librustc_mir/transform/check_consts/mod.rs
+1
-0
src/librustc_mir/transform/check_consts/post_drop_elaboration.rs
...rustc_mir/transform/check_consts/post_drop_elaboration.rs
+119
-0
src/librustc_mir/transform/check_consts/validation.rs
src/librustc_mir/transform/check_consts/validation.rs
+6
-0
未找到文件。
src/librustc_mir/transform/check_consts/mod.rs
浏览文件 @
f5370faa
...
...
@@ -12,6 +12,7 @@
pub
use
self
::
qualifs
::
Qualif
;
mod
ops
;
pub
mod
post_drop_elaboration
;
pub
mod
qualifs
;
mod
resolver
;
pub
mod
validation
;
...
...
src/librustc_mir/transform/check_consts/post_drop_elaboration.rs
0 → 100644
浏览文件 @
f5370faa
use
rustc_hir
::
def_id
::
LocalDefId
;
use
rustc_middle
::
mir
::
visit
::
Visitor
;
use
rustc_middle
::
mir
::{
self
,
BasicBlock
,
Location
};
use
rustc_middle
::
ty
::
TyCtxt
;
use
rustc_span
::
Span
;
use
super
::
ops
;
use
super
::
qualifs
::{
NeedsDrop
,
Qualif
};
use
super
::
validation
::
Qualifs
;
use
super
::
ConstCx
;
/// Returns `true` if we should use the more precise live drop checker that runs after drop
/// elaboration.
pub
fn
checking_enabled
(
tcx
:
TyCtxt
<
'tcx
>
)
->
bool
{
tcx
.features
()
.const_precise_live_drops
}
/// Look for live drops in a const context.
///
/// This is separate from the rest of the const checking logic because it must run after drop
/// elaboration.
pub
fn
check_live_drops
(
tcx
:
TyCtxt
<
'tcx
>
,
def_id
:
LocalDefId
,
body
:
&
mir
::
Body
<
'tcx
>
)
{
let
const_kind
=
tcx
.hir
()
.body_const_context
(
def_id
);
if
const_kind
.is_none
()
{
return
;
}
if
!
checking_enabled
(
tcx
)
{
return
;
}
let
ccx
=
ConstCx
{
body
,
tcx
,
def_id
:
def_id
.to_def_id
(),
const_kind
,
param_env
:
tcx
.param_env
(
def_id
),
};
let
mut
visitor
=
CheckLiveDrops
{
ccx
:
&
ccx
,
qualifs
:
Qualifs
::
default
()
};
visitor
.visit_body
(
body
);
}
struct
CheckLiveDrops
<
'mir
,
'tcx
>
{
ccx
:
&
'mir
ConstCx
<
'mir
,
'tcx
>
,
qualifs
:
Qualifs
<
'mir
,
'tcx
>
,
}
// So we can access `body` and `tcx`.
impl
std
::
ops
::
Deref
for
CheckLiveDrops
<
'mir
,
'tcx
>
{
type
Target
=
ConstCx
<
'mir
,
'tcx
>
;
fn
deref
(
&
self
)
->
&
Self
::
Target
{
&
self
.ccx
}
}
impl
CheckLiveDrops
<
'mir
,
'tcx
>
{
fn
check_live_drop
(
&
self
,
span
:
Span
)
{
ops
::
non_const
(
self
.ccx
,
ops
::
LiveDrop
,
span
);
}
}
impl
Visitor
<
'tcx
>
for
CheckLiveDrops
<
'mir
,
'tcx
>
{
fn
visit_basic_block_data
(
&
mut
self
,
bb
:
BasicBlock
,
block
:
&
mir
::
BasicBlockData
<
'tcx
>
)
{
trace!
(
"visit_basic_block_data: bb={:?} is_cleanup={:?}"
,
bb
,
block
.is_cleanup
);
// Ignore drop terminators in cleanup blocks.
if
block
.is_cleanup
{
return
;
}
self
.super_basic_block_data
(
bb
,
block
);
}
fn
visit_terminator
(
&
mut
self
,
terminator
:
&
mir
::
Terminator
<
'tcx
>
,
location
:
Location
)
{
trace!
(
"visit_terminator: terminator={:?} location={:?}"
,
terminator
,
location
);
match
&
terminator
.kind
{
mir
::
TerminatorKind
::
Drop
{
location
:
dropped_place
,
..
}
=>
{
let
dropped_ty
=
dropped_place
.ty
(
self
.body
,
self
.tcx
)
.ty
;
if
!
NeedsDrop
::
in_any_value_of_ty
(
self
.ccx
,
dropped_ty
)
{
return
;
}
if
dropped_place
.is_indirect
()
{
self
.check_live_drop
(
terminator
.source_info.span
);
return
;
}
if
self
.qualifs
.needs_drop
(
self
.ccx
,
dropped_place
.local
,
location
)
{
// Use the span where the dropped local was declared for the error.
let
span
=
self
.body.local_decls
[
dropped_place
.local
]
.source_info.span
;
self
.check_live_drop
(
span
);
}
}
mir
::
TerminatorKind
::
DropAndReplace
{
..
}
=>
span_bug!
(
terminator
.source_info.span
,
"`DropAndReplace` should be removed by drop elaboration"
,
),
mir
::
TerminatorKind
::
Abort
|
mir
::
TerminatorKind
::
Call
{
..
}
|
mir
::
TerminatorKind
::
Assert
{
..
}
|
mir
::
TerminatorKind
::
FalseEdge
{
..
}
|
mir
::
TerminatorKind
::
FalseUnwind
{
..
}
|
mir
::
TerminatorKind
::
GeneratorDrop
|
mir
::
TerminatorKind
::
Goto
{
..
}
|
mir
::
TerminatorKind
::
InlineAsm
{
..
}
|
mir
::
TerminatorKind
::
Resume
|
mir
::
TerminatorKind
::
Return
|
mir
::
TerminatorKind
::
SwitchInt
{
..
}
|
mir
::
TerminatorKind
::
Unreachable
|
mir
::
TerminatorKind
::
Yield
{
..
}
=>
{}
}
}
}
src/librustc_mir/transform/check_consts/validation.rs
浏览文件 @
f5370faa
...
...
@@ -562,6 +562,12 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
// projections that cannot be `NeedsDrop`.
TerminatorKind
::
Drop
{
location
:
dropped_place
,
..
}
|
TerminatorKind
::
DropAndReplace
{
location
:
dropped_place
,
..
}
=>
{
// If we are checking live drops after drop-elaboration, don't emit duplicate
// errors here.
if
super
::
post_drop_elaboration
::
checking_enabled
(
self
.tcx
)
{
return
;
}
let
mut
err_span
=
self
.span
;
// Check to see if the type of this place can ever have a drop impl. If not, this
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录