Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
5e4867ee
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,发现更多精彩内容 >>
提交
5e4867ee
编写于
2月 25, 2015
作者:
F
Felix S. Klock II
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Use more precise `type_needs_drop` for deciding about emitting cleanup code.
Fix #22536
上级
2d0e6cae
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
69 addition
and
17 deletion
+69
-17
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/callee.rs
+1
-1
src/librustc_trans/trans/cleanup.rs
src/librustc_trans/trans/cleanup.rs
+4
-3
src/librustc_trans/trans/common.rs
src/librustc_trans/trans/common.rs
+42
-1
src/librustc_trans/trans/controlflow.rs
src/librustc_trans/trans/controlflow.rs
+1
-1
src/librustc_trans/trans/datum.rs
src/librustc_trans/trans/datum.rs
+2
-2
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/expr.rs
+3
-3
src/librustc_trans/trans/glue.rs
src/librustc_trans/trans/glue.rs
+12
-2
src/librustc_trans/trans/intrinsic.rs
src/librustc_trans/trans/intrinsic.rs
+2
-1
src/librustc_trans/trans/meth.rs
src/librustc_trans/trans/meth.rs
+1
-1
src/librustc_trans/trans/tvec.rs
src/librustc_trans/trans/tvec.rs
+1
-2
未找到文件。
src/librustc_trans/trans/callee.rs
浏览文件 @
5e4867ee
...
...
@@ -734,7 +734,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
};
if
!
is_rust_fn
||
type_of
::
return_uses_outptr
(
ccx
,
ret_ty
)
||
common
::
type_needs_drop
(
bcx
.tcx
(),
ret_ty
)
{
bcx
.fcx
.type_needs_drop
(
ret_ty
)
{
// Push the out-pointer if we use an out-pointer for this
// return type, otherwise push "undef".
if
common
::
type_is_zero_size
(
ccx
,
ret_ty
)
{
...
...
src/librustc_trans/trans/cleanup.rs
浏览文件 @
5e4867ee
...
...
@@ -386,7 +386,7 @@ fn schedule_drop_mem(&self,
cleanup_scope
:
ScopeId
,
val
:
ValueRef
,
ty
:
Ty
<
'tcx
>
)
{
if
!
common
::
type_needs_drop
(
self
.ccx
.tcx
(),
ty
)
{
return
;
}
if
!
self
.type_needs_drop
(
ty
)
{
return
;
}
let
drop
=
box
DropValue
{
is_immediate
:
false
,
must_unwind
:
common
::
type_needs_unwind_cleanup
(
self
.ccx
,
ty
),
...
...
@@ -408,7 +408,8 @@ fn schedule_drop_and_zero_mem(&self,
cleanup_scope
:
ScopeId
,
val
:
ValueRef
,
ty
:
Ty
<
'tcx
>
)
{
if
!
common
::
type_needs_drop
(
self
.ccx
.tcx
(),
ty
)
{
return
;
}
if
!
self
.type_needs_drop
(
ty
)
{
return
;
}
let
drop
=
box
DropValue
{
is_immediate
:
false
,
must_unwind
:
common
::
type_needs_unwind_cleanup
(
self
.ccx
,
ty
),
...
...
@@ -432,7 +433,7 @@ fn schedule_drop_immediate(&self,
val
:
ValueRef
,
ty
:
Ty
<
'tcx
>
)
{
if
!
common
::
type_needs_drop
(
self
.ccx
.tcx
(),
ty
)
{
return
;
}
if
!
self
.type_needs_drop
(
ty
)
{
return
;
}
let
drop
=
box
DropValue
{
is_immediate
:
true
,
must_unwind
:
common
::
type_needs_unwind_cleanup
(
self
.ccx
,
ty
),
...
...
src/librustc_trans/trans/common.rs
浏览文件 @
5e4867ee
...
...
@@ -213,8 +213,43 @@ fn type_needs_unwind_cleanup_<'tcx>(tcx: &ty::ctxt<'tcx>,
}
}
/// If `type_needs_drop` returns true, then `ty` is definitely
/// non-copy and *might* have a destructor attached; if it returns
/// false, then `ty` definitely has no destructor (i.e. no drop glue).
///
/// (Note that this implies that if `ty` has a destructor attached,
/// then `type_needs_drop` will definitely return `true` for `ty`.)
pub
fn
type_needs_drop
<
'tcx
>
(
cx
:
&
ty
::
ctxt
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
ty
::
type_contents
(
cx
,
ty
)
.needs_drop
(
cx
)
type_needs_drop_given_env
(
cx
,
ty
,
&
ty
::
empty_parameter_environment
(
cx
))
}
/// Core implementation of type_needs_drop, potentially making use of
/// and/or updating caches held in the `param_env`.
fn
type_needs_drop_given_env
<
'a
,
'tcx
>
(
cx
:
&
ty
::
ctxt
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
param_env
:
&
ty
::
ParameterEnvironment
<
'a
,
'tcx
>
)
->
bool
{
// Issue #22536: We first query type_moves_by_default. It sees a
// normalized version of the type, and therefore will definitely
// know whether the type implements Copy (and thus needs no
// cleanup/drop/zeroing) ...
let
implements_copy
=
!
ty
::
type_moves_by_default
(
&
param_env
,
DUMMY_SP
,
ty
);
if
implements_copy
{
return
false
;
}
// ... (issue #22536 continued) but as an optimization, still use
// prior logic of asking if the `needs_drop` bit is set; we need
// not zero non-Copy types if they have no destructor.
// FIXME(#22815): Note that calling `ty::type_contents` is a
// conservative heuristic; it may report that `needs_drop` is set
// when actual type does not actually have a destructor associated
// with it. But since `ty` absolutely did not have the `Copy`
// bound attached (see above), it is sound to treat it as having a
// destructor (e.g. zero its memory on move).
let
contents
=
ty
::
type_contents
(
cx
,
ty
);
debug!
(
"type_needs_drop ty={} contents={:?}"
,
ty
.repr
(
cx
),
contents
);
contents
.needs_drop
(
cx
)
}
fn
type_is_newtype_immediate
<
'a
,
'tcx
>
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
...
...
@@ -534,6 +569,12 @@ pub fn monomorphize<T>(&self, value: &T) -> T
self
.param_substs
,
value
)
}
/// This is the same as `common::type_needs_drop`, except that it
/// may use or update caches within this `FunctionContext`.
pub
fn
type_needs_drop
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
type_needs_drop_given_env
(
self
.ccx
.tcx
(),
ty
,
&
self
.param_env
)
}
}
// Basic block context. We create a block context for each basic block
...
...
src/librustc_trans/trans/controlflow.rs
浏览文件 @
5e4867ee
...
...
@@ -77,7 +77,7 @@ pub fn trans_stmt_semi<'blk, 'tcx>(cx: Block<'blk, 'tcx>, e: &ast::Expr)
->
Block
<
'blk
,
'tcx
>
{
let
_
icx
=
push_ctxt
(
"trans_stmt_semi"
);
let
ty
=
expr_ty
(
cx
,
e
);
if
type_needs_drop
(
cx
.tcx
(),
ty
)
{
if
cx
.fcx
.type_needs_drop
(
ty
)
{
expr
::
trans_to_lvalue
(
cx
,
e
,
"stmt"
)
.bcx
}
else
{
expr
::
trans_into
(
cx
,
e
,
expr
::
Ignore
)
...
...
src/librustc_trans/trans/datum.rs
浏览文件 @
5e4867ee
...
...
@@ -312,7 +312,7 @@ fn post_store<'blk, 'tcx>(&self,
ty
:
Ty
<
'tcx
>
)
->
Block
<
'blk
,
'tcx
>
{
let
_
icx
=
push_ctxt
(
"<Lvalue as KindOps>::post_store"
);
if
type_needs_drop
(
bcx
.tcx
(),
ty
)
{
if
bcx
.fcx
.type_needs_drop
(
ty
)
{
// cancel cleanup of affine values by zeroing out
let
()
=
zero_mem
(
bcx
,
val
,
ty
);
bcx
...
...
@@ -657,7 +657,7 @@ pub fn appropriate_rvalue_mode<'a>(&self, ccx: &CrateContext<'a, 'tcx>)
/// scalar-ish (like an int or a pointer) which (1) does not require drop glue and (2) is
/// naturally passed around by value, and not by reference.
pub
fn
to_llscalarish
<
'blk
>
(
self
,
bcx
:
Block
<
'blk
,
'tcx
>
)
->
ValueRef
{
assert
!
(
!
type_needs_drop
(
bcx
.tcx
(),
self
.ty
));
assert
!
(
!
bcx
.fcx
.type_needs_drop
(
self
.ty
));
assert
!
(
self
.appropriate_rvalue_mode
(
bcx
.ccx
())
==
ByValue
);
if
self
.kind
.is_by_ref
()
{
load_ty
(
bcx
,
self
.val
,
self
.ty
)
...
...
src/librustc_trans/trans/expr.rs
浏览文件 @
5e4867ee
...
...
@@ -974,7 +974,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let
src_datum
=
unpack_datum!
(
bcx
,
trans
(
bcx
,
&**
src
));
let
dst_datum
=
unpack_datum!
(
bcx
,
trans_to_lvalue
(
bcx
,
&**
dst
,
"assign"
));
if
type_needs_drop
(
bcx
.tcx
(),
dst_datum
.ty
)
{
if
bcx
.fcx
.type_needs_drop
(
dst_datum
.ty
)
{
// If there are destructors involved, make sure we
// are copying from an rvalue, since that cannot possible
// alias an lvalue. We are concerned about code like:
...
...
@@ -1498,7 +1498,7 @@ pub fn trans_adt<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
assert_eq!
(
discr
,
0
);
match
ty
::
expr_kind
(
bcx
.tcx
(),
&*
base
.expr
)
{
ty
::
RvalueDpsExpr
|
ty
::
RvalueDatumExpr
if
!
type_needs_drop
(
bcx
.tcx
(),
ty
)
=>
{
ty
::
RvalueDpsExpr
|
ty
::
RvalueDatumExpr
if
!
bcx
.fcx
.type_needs_drop
(
ty
)
=>
{
bcx
=
trans_into
(
bcx
,
&*
base
.expr
,
SaveIn
(
addr
));
},
ty
::
RvalueStmtExpr
=>
bcx
.tcx
()
.sess
.bug
(
"unexpected expr kind for struct base expr"
),
...
...
@@ -2116,7 +2116,7 @@ fn trans_assign_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// Evaluate LHS (destination), which should be an lvalue
let
dst_datum
=
unpack_datum!
(
bcx
,
trans_to_lvalue
(
bcx
,
dst
,
"assign_op"
));
assert
!
(
!
type_needs_drop
(
bcx
.tcx
(),
dst_datum
.ty
));
assert
!
(
!
bcx
.fcx
.type_needs_drop
(
dst_datum
.ty
));
let
dst_ty
=
dst_datum
.ty
;
let
dst
=
load_ty
(
bcx
,
dst_datum
.val
,
dst_datum
.ty
);
...
...
src/librustc_trans/trans/glue.rs
浏览文件 @
5e4867ee
...
...
@@ -99,6 +99,16 @@ pub fn get_drop_glue_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
if
!
type_is_sized
(
tcx
,
t
)
{
return
t
}
// FIXME (#22815): note that type_needs_drop conservatively
// approximates in some cases and may say a type expression
// requires drop glue when it actually does not.
//
// (In this case it is not clear whether any harm is done, i.e.
// erroneously returning `t` in some cases where we could have
// returned `tcx.types.i8` does not appear unsound. The impact on
// code quality is unknown at this time.)
if
!
type_needs_drop
(
tcx
,
t
)
{
return
tcx
.types.i8
;
}
...
...
@@ -125,7 +135,7 @@ pub fn drop_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// NB: v is an *alias* of type t here, not a direct value.
debug!
(
"drop_ty(t={})"
,
t
.repr
(
bcx
.tcx
()));
let
_
icx
=
push_ctxt
(
"drop_ty"
);
if
type_needs_drop
(
bcx
.tcx
(),
t
)
{
if
bcx
.fcx
.type_needs_drop
(
t
)
{
let
ccx
=
bcx
.ccx
();
let
glue
=
get_drop_glue
(
ccx
,
t
);
let
glue_type
=
get_drop_glue_type
(
ccx
,
t
);
...
...
@@ -480,7 +490,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
},
_
=>
{
assert
!
(
type_is_sized
(
bcx
.tcx
(),
t
));
if
type_needs_drop
(
bcx
.tcx
(),
t
)
&&
ty
::
type_is_structural
(
t
)
{
if
bcx
.fcx
.type_needs_drop
(
t
)
&&
ty
::
type_is_structural
(
t
)
{
iter_structural_ty
(
bcx
,
v0
,
t
,
...
...
src/librustc_trans/trans/intrinsic.rs
浏览文件 @
5e4867ee
...
...
@@ -378,7 +378,8 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
}
(
_
,
"needs_drop"
)
=>
{
let
tp_ty
=
*
substs
.types
.get
(
FnSpace
,
0
);
C_bool
(
ccx
,
type_needs_drop
(
ccx
.tcx
(),
tp_ty
))
C_bool
(
ccx
,
bcx
.fcx
.type_needs_drop
(
tp_ty
))
}
(
_
,
"owns_managed"
)
=>
{
let
tp_ty
=
*
substs
.types
.get
(
FnSpace
,
0
);
...
...
src/librustc_trans/trans/meth.rs
浏览文件 @
5e4867ee
...
...
@@ -454,7 +454,7 @@ fn trans_trait_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let
self_datum
=
unpack_datum!
(
bcx
,
expr
::
trans
(
bcx
,
self_expr
));
let
llval
=
if
type_needs_drop
(
bcx
.tcx
(),
self_datum
.ty
)
{
let
llval
=
if
bcx
.fcx
.type_needs_drop
(
self_datum
.ty
)
{
let
self_datum
=
unpack_datum!
(
bcx
,
self_datum
.to_rvalue_datum
(
bcx
,
"trait_callee"
));
...
...
src/librustc_trans/trans/tvec.rs
浏览文件 @
5e4867ee
...
...
@@ -53,11 +53,10 @@ pub fn make_drop_glue_unboxed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let
not_null
=
IsNotNull
(
bcx
,
vptr
);
with_cond
(
bcx
,
not_null
,
|
bcx
|
{
let
ccx
=
bcx
.ccx
();
let
tcx
=
bcx
.tcx
();
let
_
icx
=
push_ctxt
(
"tvec::make_drop_glue_unboxed"
);
let
dataptr
=
get_dataptr
(
bcx
,
vptr
);
let
bcx
=
if
type_needs_drop
(
tcx
,
unit_ty
)
{
let
bcx
=
if
bcx
.fcx
.type_needs_drop
(
unit_ty
)
{
let
len
=
get_len
(
bcx
,
vptr
);
iter_vec_raw
(
bcx
,
dataptr
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录