Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
7be2fd85
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,发现更多精彩内容 >>
提交
7be2fd85
编写于
11月 28, 2017
作者:
M
Mikhail Modin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
create a drop ladder for an array if any value is moved out
上级
8bcbf91a
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
87 addition
and
9 deletion
+87
-9
src/librustc_mir/dataflow/drop_flag_effects.rs
src/librustc_mir/dataflow/drop_flag_effects.rs
+6
-1
src/librustc_mir/shim.rs
src/librustc_mir/shim.rs
+3
-0
src/librustc_mir/transform/elaborate_drops.rs
src/librustc_mir/transform/elaborate_drops.rs
+14
-0
src/librustc_mir/util/elaborate_drops.rs
src/librustc_mir/util/elaborate_drops.rs
+27
-7
src/test/run-pass/dynamic-drop.rs
src/test/run-pass/dynamic-drop.rs
+37
-1
未找到文件。
src/librustc_mir/dataflow/drop_flag_effects.rs
浏览文件 @
7be2fd85
...
...
@@ -61,7 +61,12 @@ fn place_contents_drop_state_cannot_differ<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx,
place
:
&
mir
::
Place
<
'tcx
>
)
->
bool
{
let
ty
=
place
.ty
(
mir
,
tcx
)
.to_ty
(
tcx
);
match
ty
.sty
{
ty
::
TyArray
(
..
)
|
ty
::
TySlice
(
..
)
|
ty
::
TyRef
(
..
)
|
ty
::
TyRawPtr
(
..
)
=>
{
ty
::
TyArray
(
..
)
=>
{
debug!
(
"place_contents_drop_state_cannot_differ place: {:?} ty: {:?} => false"
,
place
,
ty
);
false
}
ty
::
TySlice
(
..
)
|
ty
::
TyRef
(
..
)
|
ty
::
TyRawPtr
(
..
)
=>
{
debug!
(
"place_contents_drop_state_cannot_differ place: {:?} ty: {:?} refd => true"
,
place
,
ty
);
true
...
...
src/librustc_mir/shim.rs
浏览文件 @
7be2fd85
...
...
@@ -280,6 +280,9 @@ fn deref_subpath(&self, _path: Self::Path) -> Option<Self::Path> {
fn
downcast_subpath
(
&
self
,
_
path
:
Self
::
Path
,
_
variant
:
usize
)
->
Option
<
Self
::
Path
>
{
Some
(())
}
fn
array_subpath
(
&
self
,
_
path
:
Self
::
Path
,
_
index
:
u32
,
_
size
:
u32
)
->
Option
<
Self
::
Path
>
{
None
}
}
/// Build a `Clone::clone` shim for `self_ty`. Here, `def_id` is `Clone::clone`.
...
...
src/librustc_mir/transform/elaborate_drops.rs
浏览文件 @
7be2fd85
...
...
@@ -257,6 +257,20 @@ fn field_subpath(&self, path: Self::Path, field: Field) -> Option<Self::Path> {
})
}
fn
array_subpath
(
&
self
,
path
:
Self
::
Path
,
index
:
u32
,
size
:
u32
)
->
Option
<
Self
::
Path
>
{
dataflow
::
move_path_children_matching
(
self
.ctxt
.move_data
(),
path
,
|
p
|
{
match
p
{
&
Projection
{
elem
:
ProjectionElem
::
ConstantIndex
{
offset
,
min_length
:
_
,
from_end
:
false
},
..
}
=>
offset
==
index
,
&
Projection
{
elem
:
ProjectionElem
::
ConstantIndex
{
offset
,
min_length
:
_
,
from_end
:
true
},
..
}
=>
size
-
offset
==
index
,
_
=>
false
}
})
}
fn
deref_subpath
(
&
self
,
path
:
Self
::
Path
)
->
Option
<
Self
::
Path
>
{
dataflow
::
move_path_children_matching
(
self
.ctxt
.move_data
(),
path
,
|
p
|
{
match
p
{
...
...
src/librustc_mir/util/elaborate_drops.rs
浏览文件 @
7be2fd85
...
...
@@ -19,7 +19,7 @@
use
rustc_data_structures
::
indexed_vec
::
Idx
;
use
util
::
patch
::
MirPatch
;
use
std
::
iter
;
use
std
::
{
iter
,
u32
}
;
#[derive(Debug,
PartialEq,
Eq,
Copy,
Clone)]
pub
enum
DropFlagState
{
...
...
@@ -95,6 +95,7 @@ pub trait DropElaborator<'a, 'tcx: 'a> : fmt::Debug {
fn
field_subpath
(
&
self
,
path
:
Self
::
Path
,
field
:
Field
)
->
Option
<
Self
::
Path
>
;
fn
deref_subpath
(
&
self
,
path
:
Self
::
Path
)
->
Option
<
Self
::
Path
>
;
fn
downcast_subpath
(
&
self
,
path
:
Self
::
Path
,
variant
:
usize
)
->
Option
<
Self
::
Path
>
;
fn
array_subpath
(
&
self
,
path
:
Self
::
Path
,
index
:
u32
,
size
:
u32
)
->
Option
<
Self
::
Path
>
;
}
#[derive(Debug)]
...
...
@@ -632,8 +633,8 @@ fn drop_loop(&mut self,
loop_block
}
fn
open_drop_for_array
(
&
mut
self
,
ety
:
Ty
<
'tcx
>
)
->
BasicBlock
{
debug!
(
"open_drop_for_array({:?}
)"
,
ety
);
fn
open_drop_for_array
(
&
mut
self
,
ety
:
Ty
<
'tcx
>
,
opt_size
:
Option
<
u64
>
)
->
BasicBlock
{
debug!
(
"open_drop_for_array({:?}
, {:?})"
,
ety
,
opt_size
);
// if size_of::<ety>() == 0 {
// index_based_loop
...
...
@@ -641,9 +642,27 @@ fn open_drop_for_array(&mut self, ety: Ty<'tcx>) -> BasicBlock {
// ptr_based_loop
// }
let
tcx
=
self
.tcx
();
if
let
Some
(
size
)
=
opt_size
{
assert
!
(
size
<=
(
u32
::
MAX
as
u64
),
"move out check doesn't implemented for array bigger then u32"
);
let
size
=
size
as
u32
;
let
fields
:
Vec
<
(
Place
<
'tcx
>
,
Option
<
D
::
Path
>
)
>
=
(
0
..
size
)
.map
(|
i
|
{
(
self
.place
.clone
()
.elem
(
ProjectionElem
::
ConstantIndex
{
offset
:
i
,
min_length
:
size
,
from_end
:
false
}),
self
.elaborator
.array_subpath
(
self
.path
,
i
,
size
))
})
.collect
();
if
fields
.iter
()
.any
(|(
_
,
path
)|
path
.is_some
())
{
let
(
succ
,
unwind
)
=
self
.drop_ladder_bottom
();
return
self
.drop_ladder
(
fields
,
succ
,
unwind
)
.0
}
}
let
move_
=
|
place
:
&
Place
<
'tcx
>
|
Operand
::
Move
(
place
.clone
());
let
tcx
=
self
.tcx
();
let
size
=
&
Place
::
Local
(
self
.new_temp
(
tcx
.types.usize
));
let
size_is_zero
=
&
Place
::
Local
(
self
.new_temp
(
tcx
.types.bool
));
let
base_block
=
BasicBlockData
{
...
...
@@ -779,9 +798,10 @@ fn open_drop<'a>(&mut self) -> BasicBlock {
let
succ
=
self
.succ
;
self
.complete_drop
(
Some
(
DropFlagMode
::
Deep
),
succ
,
unwind
)
}
ty
::
TyArray
(
ety
,
_
)
|
ty
::
TySlice
(
ety
)
=>
{
self
.open_drop_for_array
(
ety
)
}
ty
::
TyArray
(
ety
,
size
)
=>
self
.open_drop_for_array
(
ety
,
size
.val
.to_const_int
()
.and_then
(|
v
|
v
.to_u64
())),
ty
::
TySlice
(
ety
)
=>
self
.open_drop_for_array
(
ety
,
None
),
_
=>
bug!
(
"open drop from non-ADT `{:?}`"
,
ty
)
}
}
...
...
src/test/run-pass/dynamic-drop.rs
浏览文件 @
7be2fd85
...
...
@@ -10,7 +10,7 @@
// ignore-wasm32-bare compiled with panic=abort by default
#![feature(generators,
generator_trait,
untagged_unions)]
#![feature(generators,
generator_trait,
untagged_unions
,
slice_patterns,
advanced_slice_patterns
)]
use
std
::
cell
::{
Cell
,
RefCell
};
use
std
::
ops
::
Generator
;
...
...
@@ -195,6 +195,33 @@ fn vec_unreachable(a: &Allocator) {
let
_
x
=
vec!
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
(),
return
];
}
fn
slice_pattern_first
(
a
:
&
Allocator
)
{
let
[
_
x
,
..
]
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
}
fn
slice_pattern_middle
(
a
:
&
Allocator
)
{
let
[
_
,
_
x
,
_
]
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
}
fn
slice_pattern_two
(
a
:
&
Allocator
)
{
let
[
_
x
,
_
,
_
y
,
_
]
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
}
fn
slice_pattern_last
(
a
:
&
Allocator
)
{
let
[
..
,
_
y
]
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
}
fn
slice_pattern_one_of
(
a
:
&
Allocator
,
i
:
usize
)
{
let
array
=
[
a
.alloc
(),
a
.alloc
(),
a
.alloc
(),
a
.alloc
()];
let
_
x
=
match
i
{
0
=>
{
let
[
a
,
..
]
=
array
;
a
}
1
=>
{
let
[
_
,
a
,
..
]
=
array
;
a
}
2
=>
{
let
[
_
,
_
,
a
,
_
]
=
array
;
a
}
3
=>
{
let
[
_
,
_
,
_
,
a
]
=
array
;
a
}
_
=>
panic!
(
"unmatched"
),
};
}
fn
run_test
<
F
>
(
mut
f
:
F
)
where
F
:
FnMut
(
&
Allocator
)
{
...
...
@@ -264,5 +291,14 @@ fn main() {
run_test
(|
a
|
mixed_drop_and_nondrop
(
a
));
run_test
(|
a
|
slice_pattern_first
(
a
));
run_test
(|
a
|
slice_pattern_middle
(
a
));
run_test
(|
a
|
slice_pattern_two
(
a
));
run_test
(|
a
|
slice_pattern_last
(
a
));
run_test
(|
a
|
slice_pattern_one_of
(
a
,
0
));
run_test
(|
a
|
slice_pattern_one_of
(
a
,
1
));
run_test
(|
a
|
slice_pattern_one_of
(
a
,
2
));
run_test
(|
a
|
slice_pattern_one_of
(
a
,
3
));
run_test_nopanic
(|
a
|
union1
(
a
));
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录