Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
1af86635
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,发现更多精彩内容 >>
提交
1af86635
编写于
7月 04, 2014
作者:
L
Luqman Aden
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
librustc: Make sure to run destructors in the right order when matching on moved value.
上级
5d5c2064
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
116 addition
and
8 deletion
+116
-8
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/_match.rs
+11
-5
src/librustc/middle/trans/cleanup.rs
src/librustc/middle/trans/cleanup.rs
+41
-3
src/test/run-pass/order-drop-with-match.rs
src/test/run-pass/order-drop-with-match.rs
+64
-0
未找到文件。
src/librustc/middle/trans/_match.rs
浏览文件 @
1af86635
...
...
@@ -962,8 +962,8 @@ fn compare_str<'a>(cx: &'a Block<'a>,
}
}
fn
insert_lllocals
<
'a
>
(
mut
bcx
:
&
'a
Block
<
'a
>
,
bindings_map
:
&
BindingsMap
)
fn
insert_lllocals
<
'a
>
(
mut
bcx
:
&
'a
Block
<
'a
>
,
bindings_map
:
&
BindingsMap
,
cs
:
Option
<
cleanup
::
ScopeId
>
)
->
&
'a
Block
<
'a
>
{
/*!
* For each binding in `data.bindings_map`, adds an appropriate entry into
...
...
@@ -990,6 +990,10 @@ fn insert_lllocals<'a>(mut bcx: &'a Block<'a>,
};
let
datum
=
Datum
::
new
(
llval
,
binding_info
.ty
,
Lvalue
);
match
cs
{
Some
(
cs
)
=>
bcx
.fcx
.schedule_drop_and_zero_mem
(
cs
,
llval
,
binding_info
.ty
),
_
=>
{}
}
debug!
(
"binding {:?} to {}"
,
binding_info
.id
,
...
...
@@ -1021,7 +1025,7 @@ fn compile_guard<'a, 'b>(
vec_map_to_str
(
vals
,
|
v
|
bcx
.val_to_str
(
*
v
)));
let
_
indenter
=
indenter
();
let
mut
bcx
=
insert_lllocals
(
bcx
,
&
data
.bindings_map
);
let
mut
bcx
=
insert_lllocals
(
bcx
,
&
data
.bindings_map
,
None
);
let
val
=
unpack_datum!
(
bcx
,
expr
::
trans
(
bcx
,
guard_expr
));
let
val
=
val
.to_llbool
(
bcx
);
...
...
@@ -1475,9 +1479,11 @@ fn trans_match_inner<'a>(scope_cx: &'a Block<'a>,
for
arm_data
in
arm_datas
.iter
()
{
let
mut
bcx
=
arm_data
.bodycx
;
// insert bindings into the lllocals map
bcx
=
insert_lllocals
(
bcx
,
&
arm_data
.bindings_map
);
// insert bindings into the lllocals map and add cleanups
let
cs
=
fcx
.push_custom_cleanup_scope
();
bcx
=
insert_lllocals
(
bcx
,
&
arm_data
.bindings_map
,
Some
(
cleanup
::
CustomScope
(
cs
)));
bcx
=
expr
::
trans_into
(
bcx
,
&*
arm_data
.arm.body
,
dest
);
bcx
=
fcx
.pop_and_trans_custom_cleanup_scope
(
bcx
,
cs
);
arm_cxs
.push
(
bcx
);
}
...
...
src/librustc/middle/trans/cleanup.rs
浏览文件 @
1af86635
...
...
@@ -240,7 +240,8 @@ fn schedule_drop_mem(&self,
is_immediate
:
false
,
on_unwind
:
ty
::
type_needs_unwind_cleanup
(
self
.ccx
.tcx
(),
ty
),
val
:
val
,
ty
:
ty
ty
:
ty
,
zero
:
false
};
debug!
(
"schedule_drop_mem({:?}, val={}, ty={})"
,
...
...
@@ -251,6 +252,33 @@ fn schedule_drop_mem(&self,
self
.schedule_clean
(
cleanup_scope
,
drop
as
Box
<
Cleanup
>
);
}
fn
schedule_drop_and_zero_mem
(
&
self
,
cleanup_scope
:
ScopeId
,
val
:
ValueRef
,
ty
:
ty
::
t
)
{
/*!
* Schedules a (deep) drop and zero-ing of `val`, which is a pointer
* to an instance of `ty`
*/
if
!
ty
::
type_needs_drop
(
self
.ccx
.tcx
(),
ty
)
{
return
;
}
let
drop
=
box
DropValue
{
is_immediate
:
false
,
on_unwind
:
ty
::
type_needs_unwind_cleanup
(
self
.ccx
.tcx
(),
ty
),
val
:
val
,
ty
:
ty
,
zero
:
true
};
debug!
(
"schedule_drop_and_zero_mem({:?}, val={}, ty={}, zero={})"
,
cleanup_scope
,
self
.ccx.tn
.val_to_str
(
val
),
ty
.repr
(
self
.ccx
.tcx
()),
true
);
self
.schedule_clean
(
cleanup_scope
,
drop
as
Box
<
Cleanup
>
);
}
fn
schedule_drop_immediate
(
&
self
,
cleanup_scope
:
ScopeId
,
val
:
ValueRef
,
...
...
@@ -264,7 +292,8 @@ fn schedule_drop_immediate(&self,
is_immediate
:
true
,
on_unwind
:
ty
::
type_needs_unwind_cleanup
(
self
.ccx
.tcx
(),
ty
),
val
:
val
,
ty
:
ty
ty
:
ty
,
zero
:
false
};
debug!
(
"schedule_drop_immediate({:?}, val={}, ty={})"
,
...
...
@@ -824,6 +853,7 @@ pub struct DropValue {
on_unwind
:
bool
,
val
:
ValueRef
,
ty
:
ty
::
t
,
zero
:
bool
}
impl
Cleanup
for
DropValue
{
...
...
@@ -832,11 +862,15 @@ fn clean_on_unwind(&self) -> bool {
}
fn
trans
<
'a
>
(
&
self
,
bcx
:
&
'a
Block
<
'a
>
)
->
&
'a
Block
<
'a
>
{
if
self
.is_immediate
{
let
bcx
=
if
self
.is_immediate
{
glue
::
drop_ty_immediate
(
bcx
,
self
.val
,
self
.ty
)
}
else
{
glue
::
drop_ty
(
bcx
,
self
.val
,
self
.ty
)
};
if
self
.zero
{
base
::
zero_mem
(
bcx
,
self
.val
,
self
.ty
);
}
bcx
}
}
...
...
@@ -927,6 +961,10 @@ fn schedule_drop_mem(&self,
cleanup_scope
:
ScopeId
,
val
:
ValueRef
,
ty
:
ty
::
t
);
fn
schedule_drop_and_zero_mem
(
&
self
,
cleanup_scope
:
ScopeId
,
val
:
ValueRef
,
ty
:
ty
::
t
);
fn
schedule_drop_immediate
(
&
self
,
cleanup_scope
:
ScopeId
,
val
:
ValueRef
,
...
...
src/test/run-pass/order-drop-with-match.rs
0 → 100644
浏览文件 @
1af86635
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test to make sure the destructors run in the right order.
// Each destructor sets it's tag in the corresponding entry
// in ORDER matching up to when it ran.
// Correct order is: matched, inner, outer
static
mut
ORDER
:
[
uint
,
..
3
]
=
[
0
,
0
,
0
];
static
mut
INDEX
:
uint
=
0
;
struct
A
;
impl
Drop
for
A
{
fn
drop
(
&
mut
self
)
{
unsafe
{
ORDER
[
INDEX
]
=
1
;
INDEX
=
INDEX
+
1
;
}
}
}
struct
B
;
impl
Drop
for
B
{
fn
drop
(
&
mut
self
)
{
unsafe
{
ORDER
[
INDEX
]
=
2
;
INDEX
=
INDEX
+
1
;
}
}
}
struct
C
;
impl
Drop
for
C
{
fn
drop
(
&
mut
self
)
{
unsafe
{
ORDER
[
INDEX
]
=
3
;
INDEX
=
INDEX
+
1
;
}
}
}
fn
main
()
{
{
let
matched
=
A
;
let
_
outer
=
C
;
{
match
matched
{
_
s
=>
{}
}
let
_
inner
=
B
;
}
}
unsafe
{
assert_eq!
(
&
[
1
,
2
,
3
],
ORDER
.as_slice
());
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录