Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
3a16f57f
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,发现更多精彩内容 >>
提交
3a16f57f
编写于
3月 10, 2016
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
extend Terminator into a struct so it can have additional fields
上级
e752d4cd
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
177 addition
and
159 deletion
+177
-159
src/librustc/mir/repr.rs
src/librustc/mir/repr.rs
+22
-7
src/librustc/mir/visit.rs
src/librustc/mir/visit.rs
+20
-18
src/librustc_borrowck/borrowck/mir/dataflow.rs
src/librustc_borrowck/borrowck/mir/dataflow.rs
+10
-11
src/librustc_borrowck/borrowck/mir/gather_moves.rs
src/librustc_borrowck/borrowck/mir/gather_moves.rs
+38
-40
src/librustc_mir/build/cfg.rs
src/librustc_mir/build/cfg.rs
+4
-2
src/librustc_mir/build/expr/as_lvalue.rs
src/librustc_mir/build/expr/as_lvalue.rs
+1
-1
src/librustc_mir/build/expr/into.rs
src/librustc_mir/build/expr/into.rs
+11
-11
src/librustc_mir/build/matches/mod.rs
src/librustc_mir/build/matches/mod.rs
+4
-4
src/librustc_mir/build/matches/test.rs
src/librustc_mir/build/matches/test.rs
+4
-4
src/librustc_mir/build/mod.rs
src/librustc_mir/build/mod.rs
+2
-2
src/librustc_mir/build/scope.rs
src/librustc_mir/build/scope.rs
+12
-11
src/librustc_mir/graphviz.rs
src/librustc_mir/graphviz.rs
+2
-2
src/librustc_mir/transform/erase_regions.rs
src/librustc_mir/transform/erase_regions.rs
+9
-9
src/librustc_mir/transform/no_landing_pads.rs
src/librustc_mir/transform/no_landing_pads.rs
+9
-9
src/librustc_mir/transform/simplify_cfg.rs
src/librustc_mir/transform/simplify_cfg.rs
+10
-10
src/librustc_mir/transform/type_check.rs
src/librustc_mir/transform/type_check.rs
+9
-9
src/librustc_trans/trans/mir/block.rs
src/librustc_trans/trans/mir/block.rs
+10
-9
未找到文件。
src/librustc/mir/repr.rs
浏览文件 @
3a16f57f
...
...
@@ -228,8 +228,13 @@ pub struct BasicBlockData<'tcx> {
pub
is_cleanup
:
bool
,
}
#[derive(Clone,
Debug,
RustcEncodable,
RustcDecodable)]
pub
struct
Terminator
<
'tcx
>
{
pub
kind
:
TerminatorKind
<
'tcx
>
}
#[derive(Clone,
RustcEncodable,
RustcDecodable)]
pub
enum
Terminator
<
'tcx
>
{
pub
enum
Terminator
Kind
<
'tcx
>
{
/// block should have one successor in the graph; we jump there
Goto
{
target
:
BasicBlock
,
...
...
@@ -299,7 +304,17 @@ pub enum Terminator<'tcx> {
impl
<
'tcx
>
Terminator
<
'tcx
>
{
pub
fn
successors
(
&
self
)
->
Cow
<
[
BasicBlock
]
>
{
use
self
::
Terminator
::
*
;
self
.kind
.successors
()
}
pub
fn
successors_mut
(
&
mut
self
)
->
Vec
<&
mut
BasicBlock
>
{
self
.kind
.successors_mut
()
}
}
impl
<
'tcx
>
TerminatorKind
<
'tcx
>
{
pub
fn
successors
(
&
self
)
->
Cow
<
[
BasicBlock
]
>
{
use
self
::
TerminatorKind
::
*
;
match
*
self
{
Goto
{
target
:
ref
b
}
=>
slice
::
ref_slice
(
b
)
.into_cow
(),
If
{
targets
:
(
b1
,
b2
),
..
}
=>
vec!
[
b1
,
b2
]
.into_cow
(),
...
...
@@ -320,7 +335,7 @@ pub fn successors(&self) -> Cow<[BasicBlock]> {
// FIXME: no mootable cow. I’m honestly not sure what a “cow” between `&mut [BasicBlock]` and
// `Vec<&mut BasicBlock>` would look like in the first place.
pub
fn
successors_mut
(
&
mut
self
)
->
Vec
<&
mut
BasicBlock
>
{
use
self
::
Terminator
::
*
;
use
self
::
Terminator
Kind
::
*
;
match
*
self
{
Goto
{
target
:
ref
mut
b
}
=>
vec!
[
b
],
If
{
targets
:
(
ref
mut
b1
,
ref
mut
b2
),
..
}
=>
vec!
[
b1
,
b2
],
...
...
@@ -360,7 +375,7 @@ pub fn terminator_mut(&mut self) -> &mut Terminator<'tcx> {
}
}
impl
<
'tcx
>
Debug
for
Terminator
<
'tcx
>
{
impl
<
'tcx
>
Debug
for
Terminator
Kind
<
'tcx
>
{
fn
fmt
(
&
self
,
fmt
:
&
mut
Formatter
)
->
fmt
::
Result
{
self
.fmt_head
(
fmt
)
?
;
let
successors
=
self
.successors
();
...
...
@@ -387,12 +402,12 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
}
}
impl
<
'tcx
>
Terminator
<
'tcx
>
{
impl
<
'tcx
>
Terminator
Kind
<
'tcx
>
{
/// Write the "head" part of the terminator; that is, its name and the data it uses to pick the
/// successor basic block, if any. The only information not inlcuded is the list of possible
/// successors, which may be rendered differently between the text and the graphviz format.
pub
fn
fmt_head
<
W
:
Write
>
(
&
self
,
fmt
:
&
mut
W
)
->
fmt
::
Result
{
use
self
::
Terminator
::
*
;
use
self
::
Terminator
Kind
::
*
;
match
*
self
{
Goto
{
..
}
=>
write!
(
fmt
,
"goto"
),
If
{
cond
:
ref
lv
,
..
}
=>
write!
(
fmt
,
"if({:?})"
,
lv
),
...
...
@@ -419,7 +434,7 @@ pub fn fmt_head<W: Write>(&self, fmt: &mut W) -> fmt::Result {
/// Return the list of labels for the edges to the successor basic blocks.
pub
fn
fmt_successor_labels
(
&
self
)
->
Vec
<
Cow
<
'static
,
str
>>
{
use
self
::
Terminator
::
*
;
use
self
::
Terminator
Kind
::
*
;
match
*
self
{
Return
|
Resume
=>
vec!
[],
Goto
{
..
}
=>
vec!
[
""
.into
()],
...
...
src/librustc/mir/visit.rs
浏览文件 @
3a16f57f
...
...
@@ -138,52 +138,54 @@ fn super_assign(&mut self,
fn
super_terminator
(
&
mut
self
,
block
:
BasicBlock
,
terminator
:
&
$
(
$mutability
)
*
Terminator
<
'tcx
>
)
{
match
*
terminator
{
Terminator
::
Goto
{
target
}
=>
{
match
terminator
.kind
{
Terminator
Kind
::
Goto
{
target
}
=>
{
self
.visit_branch
(
block
,
target
);
}
Terminator
::
If
{
ref
$
(
$mutability
)
*
cond
,
ref
$
(
$mutability
)
*
targets
}
=>
{
Terminator
Kind
::
If
{
ref
$
(
$mutability
)
*
cond
,
ref
$
(
$mutability
)
*
targets
}
=>
{
self
.visit_operand
(
cond
);
for
&
target
in
targets
.as_slice
()
{
self
.visit_branch
(
block
,
target
);
}
}
Terminator
::
Switch
{
ref
$
(
$mutability
)
*
discr
,
adt_def
:
_
,
ref
targets
}
=>
{
Terminator
Kind
::
Switch
{
ref
$
(
$mutability
)
*
discr
,
adt_def
:
_
,
ref
targets
}
=>
{
self
.visit_lvalue
(
discr
,
LvalueContext
::
Inspect
);
for
&
target
in
targets
{
self
.visit_branch
(
block
,
target
);
}
}
Terminator
::
SwitchInt
{
ref
$
(
$mutability
)
*
discr
,
switch_ty
:
_
,
values
:
_
,
ref
targets
}
=>
{
Terminator
Kind
::
SwitchInt
{
ref
$
(
$mutability
)
*
discr
,
switch_ty
:
_
,
values
:
_
,
ref
targets
}
=>
{
self
.visit_lvalue
(
discr
,
LvalueContext
::
Inspect
);
for
&
target
in
targets
{
self
.visit_branch
(
block
,
target
);
}
}
Terminator
::
Resume
|
Terminator
::
Return
=>
{
Terminator
Kind
::
Resume
|
Terminator
Kind
::
Return
=>
{
}
Terminator
::
Drop
{
ref
$
(
$mutability
)
*
value
,
target
,
unwind
}
=>
{
TerminatorKind
::
Drop
{
ref
$
(
$mutability
)
*
value
,
target
,
unwind
}
=>
{
self
.visit_lvalue
(
value
,
LvalueContext
::
Drop
);
self
.visit_branch
(
block
,
target
);
unwind
.map
(|
t
|
self
.visit_branch
(
block
,
t
));
}
Terminator
::
Call
{
ref
$
(
$mutability
)
*
func
,
ref
$
(
$mutability
)
*
args
,
ref
$
(
$mutability
)
*
destination
,
cleanup
}
=>
{
Terminator
Kind
::
Call
{
ref
$
(
$mutability
)
*
func
,
ref
$
(
$mutability
)
*
args
,
ref
$
(
$mutability
)
*
destination
,
cleanup
}
=>
{
self
.visit_operand
(
func
);
for
arg
in
args
{
self
.visit_operand
(
arg
);
...
...
src/librustc_borrowck/borrowck/mir/dataflow.rs
浏览文件 @
3a16f57f
...
...
@@ -410,29 +410,28 @@ fn propagate_bits_into_graph_successors_of<OnReturn>(
bb
:
&
repr
::
BasicBlockData
,
on_return
:
OnReturn
)
where
OnReturn
:
Fn
(
&
D
,
&
mut
[
usize
],
&
repr
::
Lvalue
)
{
let
term
=
if
let
Some
(
ref
term
)
=
bb
.terminator
{
term
}
else
{
return
};
match
*
term
{
repr
::
Terminator
::
Return
|
repr
::
Terminator
::
Resume
=>
{}
repr
::
Terminator
::
Goto
{
ref
target
}
|
repr
::
Terminator
::
Drop
{
ref
target
,
value
:
_
,
unwind
:
None
}
=>
{
match
bb
.terminator
()
.kind
{
repr
::
TerminatorKind
::
Return
|
repr
::
TerminatorKind
::
Resume
=>
{}
repr
::
TerminatorKind
::
Goto
{
ref
target
}
|
repr
::
TerminatorKind
::
Drop
{
ref
target
,
value
:
_
,
unwind
:
None
}
=>
{
self
.propagate_bits_into_entry_set_for
(
in_out
,
changed
,
target
);
}
repr
::
Terminator
::
Drop
{
ref
target
,
value
:
_
,
unwind
:
Some
(
ref
unwind
)
}
=>
{
repr
::
Terminator
Kind
::
Drop
{
ref
target
,
value
:
_
,
unwind
:
Some
(
ref
unwind
)
}
=>
{
self
.propagate_bits_into_entry_set_for
(
in_out
,
changed
,
target
);
self
.propagate_bits_into_entry_set_for
(
in_out
,
changed
,
unwind
);
}
repr
::
Terminator
::
If
{
ref
targets
,
..
}
=>
{
repr
::
Terminator
Kind
::
If
{
ref
targets
,
..
}
=>
{
self
.propagate_bits_into_entry_set_for
(
in_out
,
changed
,
&
targets
.0
);
self
.propagate_bits_into_entry_set_for
(
in_out
,
changed
,
&
targets
.1
);
}
repr
::
Terminator
::
Switch
{
ref
targets
,
..
}
|
repr
::
Terminator
::
SwitchInt
{
ref
targets
,
..
}
=>
{
repr
::
Terminator
Kind
::
Switch
{
ref
targets
,
..
}
|
repr
::
Terminator
Kind
::
SwitchInt
{
ref
targets
,
..
}
=>
{
for
target
in
targets
{
self
.propagate_bits_into_entry_set_for
(
in_out
,
changed
,
target
);
}
}
repr
::
Terminator
::
Call
{
ref
cleanup
,
ref
destination
,
func
:
_
,
args
:
_
}
=>
{
repr
::
Terminator
Kind
::
Call
{
ref
cleanup
,
ref
destination
,
func
:
_
,
args
:
_
}
=>
{
if
let
Some
(
ref
unwind
)
=
*
cleanup
{
self
.propagate_bits_into_entry_set_for
(
in_out
,
changed
,
unwind
);
}
...
...
src/librustc_borrowck/borrowck/mir/gather_moves.rs
浏览文件 @
3a16f57f
...
...
@@ -11,7 +11,7 @@
use
rustc
::
middle
::
ty
;
use
rustc
::
mir
::
repr
::{
self
,
Mir
,
BasicBlock
,
Lvalue
,
Rvalue
};
use
rustc
::
mir
::
repr
::{
StatementKind
,
Terminator
};
use
rustc
::
mir
::
repr
::{
StatementKind
,
Terminator
Kind
};
use
rustc
::
util
::
nodemap
::
FnvHashMap
;
use
std
::
cell
::{
Cell
};
...
...
@@ -577,50 +577,48 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &ty::TyCtxt<'tcx>) -> MoveData<'tcx>
}
}
if
let
Some
(
ref
term
)
=
bb_data
.terminator
{
match
*
term
{
Terminator
::
Goto
{
target
:
_
}
|
Terminator
::
Resume
=>
{
}
match
bb_data
.terminator
()
.kind
{
TerminatorKind
::
Goto
{
target
:
_
}
|
TerminatorKind
::
Resume
=>
{
}
Terminator
::
Return
=>
{
let
source
=
Location
{
block
:
bb
,
index
:
bb_data
.statements
.len
()
};
let
lval
=
&
Lvalue
::
ReturnPointer
.deref
();
bb_ctxt
.on_move_out_lval
(
SK
::
Return
,
lval
,
source
);
}
TerminatorKind
::
Return
=>
{
let
source
=
Location
{
block
:
bb
,
index
:
bb_data
.statements
.len
()
};
let
lval
=
&
Lvalue
::
ReturnPointer
.deref
();
bb_ctxt
.on_move_out_lval
(
SK
::
Return
,
lval
,
source
);
}
Terminator
::
If
{
ref
cond
,
targets
:
_
}
=>
{
// The `cond` is always of (copyable) type `bool`,
// so there will never be anything to move.
let
_
=
cond
;
}
TerminatorKind
::
If
{
ref
cond
,
targets
:
_
}
=>
{
// The `cond` is always of (copyable) type `bool`,
// so there will never be anything to move.
let
_
=
cond
;
}
Terminator
::
SwitchInt
{
switch_ty
:
_
,
values
:
_
,
targets
:
_
,
ref
discr
}
|
Terminator
::
Switch
{
adt_def
:
_
,
targets
:
_
,
ref
discr
}
=>
{
// The `discr` is not consumed; that is instead
// encoded on specific match arms (and for
// SwitchInt`, it is always a copyable integer
// type anyway).
let
_
=
discr
;
}
TerminatorKind
::
SwitchInt
{
switch_ty
:
_
,
values
:
_
,
targets
:
_
,
ref
discr
}
|
TerminatorKind
::
Switch
{
adt_def
:
_
,
targets
:
_
,
ref
discr
}
=>
{
// The `discr` is not consumed; that is instead
// encoded on specific match arms (and for
// SwitchInt`, it is always a copyable integer
// type anyway).
let
_
=
discr
;
}
Terminator
::
Drop
{
value
:
ref
lval
,
target
:
_
,
unwind
:
_
}
=>
{
let
source
=
Location
{
block
:
bb
,
index
:
bb_data
.statements
.len
()
};
bb_ctxt
.on_move_out_lval
(
SK
::
Drop
,
lval
,
source
);
}
TerminatorKind
::
Drop
{
value
:
ref
lval
,
target
:
_
,
unwind
:
_
}
=>
{
let
source
=
Location
{
block
:
bb
,
index
:
bb_data
.statements
.len
()
};
bb_ctxt
.on_move_out_lval
(
SK
::
Drop
,
lval
,
source
);
}
Terminator
::
Call
{
ref
func
,
ref
args
,
ref
destination
,
cleanup
:
_
}
=>
{
let
source
=
Location
{
block
:
bb
,
index
:
bb_data
.statements
.len
()
};
bb_ctxt
.on_operand
(
SK
::
CallFn
,
func
,
source
);
for
arg
in
args
{
bb_ctxt
.on_operand
(
SK
::
CallArg
,
arg
,
source
);
}
if
let
Some
((
ref
destination
,
_
bb
))
=
*
destination
{
// Create MovePath for `destination`, then
// discard returned index.
bb_ctxt
.builder
.move_path_for
(
destination
);
}
TerminatorKind
::
Call
{
ref
func
,
ref
args
,
ref
destination
,
cleanup
:
_
}
=>
{
let
source
=
Location
{
block
:
bb
,
index
:
bb_data
.statements
.len
()
};
bb_ctxt
.on_operand
(
SK
::
CallFn
,
func
,
source
);
for
arg
in
args
{
bb_ctxt
.on_operand
(
SK
::
CallArg
,
arg
,
source
);
}
if
let
Some
((
ref
destination
,
_
bb
))
=
*
destination
{
// Create MovePath for `destination`, then
// discard returned index.
bb_ctxt
.builder
.move_path_for
(
destination
);
}
}
}
...
...
src/librustc_mir/build/cfg.rs
浏览文件 @
3a16f57f
...
...
@@ -83,9 +83,11 @@ pub fn push_assign_unit(&mut self,
pub
fn
terminate
(
&
mut
self
,
block
:
BasicBlock
,
terminator
:
Terminator
<
'tcx
>
)
{
kind
:
TerminatorKind
<
'tcx
>
)
{
debug_assert!
(
self
.block_data
(
block
)
.terminator
.is_none
(),
"terminate: block {:?} already has a terminator set"
,
block
);
self
.block_data_mut
(
block
)
.terminator
=
Some
(
terminator
);
self
.block_data_mut
(
block
)
.terminator
=
Some
(
Terminator
{
kind
:
kind
});
}
}
src/librustc_mir/build/expr/as_lvalue.rs
浏览文件 @
3a16f57f
...
...
@@ -68,7 +68,7 @@ fn expr_as_lvalue(&mut self,
let
(
success
,
failure
)
=
(
this
.cfg
.start_new_block
(),
this
.cfg
.start_new_block
());
this
.cfg
.terminate
(
block
,
Terminator
::
If
{
Terminator
Kind
::
If
{
cond
:
Operand
::
Consume
(
lt
),
targets
:
(
success
,
failure
),
});
...
...
src/librustc_mir/build/expr/into.rs
浏览文件 @
3a16f57f
...
...
@@ -53,7 +53,7 @@ pub fn into_expr(&mut self,
let
mut
then_block
=
this
.cfg
.start_new_block
();
let
mut
else_block
=
this
.cfg
.start_new_block
();
this
.cfg
.terminate
(
block
,
Terminator
::
If
{
this
.cfg
.terminate
(
block
,
Terminator
Kind
::
If
{
cond
:
operand
,
targets
:
(
then_block
,
else_block
)
});
...
...
@@ -70,8 +70,8 @@ pub fn into_expr(&mut self,
};
let
join_block
=
this
.cfg
.start_new_block
();
this
.cfg
.terminate
(
then_block
,
Terminator
::
Goto
{
target
:
join_block
});
this
.cfg
.terminate
(
else_block
,
Terminator
::
Goto
{
target
:
join_block
});
this
.cfg
.terminate
(
then_block
,
Terminator
Kind
::
Goto
{
target
:
join_block
});
this
.cfg
.terminate
(
else_block
,
Terminator
Kind
::
Goto
{
target
:
join_block
});
join_block
.unit
()
}
...
...
@@ -97,10 +97,10 @@ pub fn into_expr(&mut self,
LogicalOp
::
And
=>
(
else_block
,
false_block
),
LogicalOp
::
Or
=>
(
true_block
,
else_block
),
};
this
.cfg
.terminate
(
block
,
Terminator
::
If
{
cond
:
lhs
,
targets
:
blocks
});
this
.cfg
.terminate
(
block
,
Terminator
Kind
::
If
{
cond
:
lhs
,
targets
:
blocks
});
let
rhs
=
unpack!
(
else_block
=
this
.as_operand
(
else_block
,
rhs
));
this
.cfg
.terminate
(
else_block
,
Terminator
::
If
{
this
.cfg
.terminate
(
else_block
,
Terminator
Kind
::
If
{
cond
:
rhs
,
targets
:
(
true_block
,
false_block
)
});
...
...
@@ -121,8 +121,8 @@ pub fn into_expr(&mut self,
literal
:
this
.hir
.false_literal
(),
});
this
.cfg
.terminate
(
true_block
,
Terminator
::
Goto
{
target
:
join_block
});
this
.cfg
.terminate
(
false_block
,
Terminator
::
Goto
{
target
:
join_block
});
this
.cfg
.terminate
(
true_block
,
Terminator
Kind
::
Goto
{
target
:
join_block
});
this
.cfg
.terminate
(
false_block
,
Terminator
Kind
::
Goto
{
target
:
join_block
});
join_block
.unit
()
}
...
...
@@ -146,7 +146,7 @@ pub fn into_expr(&mut self,
let
exit_block
=
this
.cfg
.start_new_block
();
// start the loop
this
.cfg
.terminate
(
block
,
Terminator
::
Goto
{
target
:
loop_block
});
this
.cfg
.terminate
(
block
,
Terminator
Kind
::
Goto
{
target
:
loop_block
});
let
might_break
=
this
.in_loop_scope
(
loop_block
,
exit_block
,
move
|
this
|
{
// conduct the test, if necessary
...
...
@@ -159,7 +159,7 @@ pub fn into_expr(&mut self,
let
cond
=
unpack!
(
loop_block_end
=
this
.as_operand
(
loop_block
,
cond_expr
));
body_block
=
this
.cfg
.start_new_block
();
this
.cfg
.terminate
(
loop_block_end
,
Terminator
::
If
{
Terminator
Kind
::
If
{
cond
:
cond
,
targets
:
(
body_block
,
exit_block
)
});
...
...
@@ -175,7 +175,7 @@ pub fn into_expr(&mut self,
let
tmp
=
this
.get_unit_temp
();
// Execute the body, branching back to the test.
let
body_block_end
=
unpack!
(
this
.into
(
&
tmp
,
body_block
,
body
));
this
.cfg
.terminate
(
body_block_end
,
Terminator
::
Goto
{
target
:
loop_block
});
this
.cfg
.terminate
(
body_block_end
,
Terminator
Kind
::
Goto
{
target
:
loop_block
});
});
// If the loop may reach its exit_block, we assign an empty tuple to the
// destination to keep the MIR well-formed.
...
...
@@ -254,7 +254,7 @@ pub fn into_expr(&mut self,
let
success
=
this
.cfg
.start_new_block
();
let
cleanup
=
this
.diverge_cleanup
();
this
.cfg
.terminate
(
block
,
Terminator
::
Call
{
this
.cfg
.terminate
(
block
,
Terminator
Kind
::
Call
{
func
:
fun
,
args
:
args
,
cleanup
:
cleanup
,
...
...
src/librustc_mir/build/matches/mod.rs
浏览文件 @
3a16f57f
...
...
@@ -97,7 +97,7 @@ pub fn match_expr(&mut self,
for
(
arm_index
,
arm_body
)
in
arm_bodies
.into_iter
()
.enumerate
()
{
let
mut
arm_block
=
arm_blocks
.blocks
[
arm_index
];
unpack!
(
arm_block
=
self
.into
(
destination
,
arm_block
,
arm_body
));
self
.cfg
.terminate
(
arm_block
,
Terminator
::
Goto
{
target
:
end_block
});
self
.cfg
.terminate
(
arm_block
,
Terminator
Kind
::
Goto
{
target
:
end_block
});
}
end_block
.unit
()
...
...
@@ -383,7 +383,7 @@ fn join_otherwise_blocks(&mut self,
}
else
{
let
join_block
=
self
.cfg
.start_new_block
();
for
block
in
otherwise
{
self
.cfg
.terminate
(
block
,
Terminator
::
Goto
{
target
:
join_block
});
self
.cfg
.terminate
(
block
,
Terminator
Kind
::
Goto
{
target
:
join_block
});
}
join_block
}
...
...
@@ -555,11 +555,11 @@ fn bind_and_guard_matched_candidate<'pat>(&mut self,
// guard, this block is simply unreachable
let
cond
=
unpack!
(
block
=
self
.as_operand
(
block
,
guard
));
let
otherwise
=
self
.cfg
.start_new_block
();
self
.cfg
.terminate
(
block
,
Terminator
::
If
{
cond
:
cond
,
self
.cfg
.terminate
(
block
,
Terminator
Kind
::
If
{
cond
:
cond
,
targets
:
(
arm_block
,
otherwise
)});
Some
(
otherwise
)
}
else
{
self
.cfg
.terminate
(
block
,
Terminator
::
Goto
{
target
:
arm_block
});
self
.cfg
.terminate
(
block
,
Terminator
Kind
::
Goto
{
target
:
arm_block
});
None
}
}
...
...
src/librustc_mir/build/matches/test.rs
浏览文件 @
3a16f57f
...
...
@@ -153,7 +153,7 @@ pub fn perform_test(&mut self,
let
target_blocks
:
Vec
<
_
>
=
(
0
..
num_enum_variants
)
.map
(|
_
|
self
.cfg
.start_new_block
())
.collect
();
self
.cfg
.terminate
(
block
,
Terminator
::
Switch
{
self
.cfg
.terminate
(
block
,
Terminator
Kind
::
Switch
{
discr
:
lvalue
.clone
(),
adt_def
:
adt_def
,
targets
:
target_blocks
.clone
()
...
...
@@ -168,7 +168,7 @@ pub fn perform_test(&mut self,
.map
(|
_
|
self
.cfg
.start_new_block
())
.chain
(
Some
(
otherwise
))
.collect
();
self
.cfg
.terminate
(
block
,
Terminator
::
SwitchInt
{
self
.cfg
.terminate
(
block
,
Terminator
Kind
::
SwitchInt
{
discr
:
lvalue
.clone
(),
switch_ty
:
switch_ty
,
values
:
options
.clone
(),
...
...
@@ -286,7 +286,7 @@ pub fn perform_test(&mut self,
// branch based on result
let
target_blocks
:
Vec
<
_
>
=
vec!
[
self
.cfg
.start_new_block
(),
self
.cfg
.start_new_block
()];
self
.cfg
.terminate
(
block
,
Terminator
::
If
{
self
.cfg
.terminate
(
block
,
Terminator
Kind
::
If
{
cond
:
Operand
::
Consume
(
result
),
targets
:
(
target_blocks
[
0
],
target_blocks
[
1
])
});
...
...
@@ -313,7 +313,7 @@ fn compare(&mut self,
// branch based on result
let
target_block
=
self
.cfg
.start_new_block
();
self
.cfg
.terminate
(
block
,
Terminator
::
If
{
self
.cfg
.terminate
(
block
,
Terminator
Kind
::
If
{
cond
:
Operand
::
Consume
(
result
),
targets
:
(
target_block
,
fail_block
)
});
...
...
src/librustc_mir/build/mod.rs
浏览文件 @
3a16f57f
...
...
@@ -166,8 +166,8 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>,
argument_extent
,
ast_block
));
builder
.cfg
.terminate
(
block
,
Terminator
::
Goto
{
target
:
END_BLOCK
});
builder
.cfg
.terminate
(
END_BLOCK
,
Terminator
::
Return
);
builder
.cfg
.terminate
(
block
,
Terminator
Kind
::
Goto
{
target
:
END_BLOCK
});
builder
.cfg
.terminate
(
END_BLOCK
,
Terminator
Kind
::
Return
);
MirPlusPlus
{
mir
:
Mir
{
...
...
src/librustc_mir/build/scope.rs
浏览文件 @
3a16f57f
...
...
@@ -295,7 +295,7 @@ pub fn exit_scope(&mut self,
.postdoms
.push
(
self
.cfg
.current_location
(
block
));
}
self
.cfg
.terminate
(
block
,
Terminator
::
Goto
{
target
:
target
});
self
.cfg
.terminate
(
block
,
Terminator
Kind
::
Goto
{
target
:
target
});
}
// Finding scopes
...
...
@@ -432,7 +432,7 @@ pub fn diverge_cleanup(&mut self) -> Option<BasicBlock> {
pub
fn
build_drop
(
&
mut
self
,
block
:
BasicBlock
,
value
:
Lvalue
<
'tcx
>
)
->
BlockAnd
<
()
>
{
let
next_target
=
self
.cfg
.start_new_block
();
let
diverge_target
=
self
.diverge_cleanup
();
self
.cfg
.terminate
(
block
,
Terminator
::
Drop
{
self
.cfg
.terminate
(
block
,
Terminator
Kind
::
Drop
{
value
:
value
,
target
:
next_target
,
unwind
:
diverge_target
,
...
...
@@ -474,7 +474,7 @@ pub fn panic_bounds_check(&mut self,
self
.cfg
.push_assign
(
block
,
scope_id
,
span
,
&
tuple_ref
,
// tuple_ref = &tuple;
Rvalue
::
Ref
(
region
,
BorrowKind
::
Shared
,
tuple
));
let
cleanup
=
self
.diverge_cleanup
();
self
.cfg
.terminate
(
block
,
Terminator
::
Call
{
self
.cfg
.terminate
(
block
,
Terminator
Kind
::
Call
{
func
:
Operand
::
Constant
(
func
),
args
:
vec!
[
Operand
::
Consume
(
tuple_ref
),
index
,
len
],
destination
:
None
,
...
...
@@ -516,7 +516,7 @@ pub fn panic(&mut self, block: BasicBlock, msg: &'static str, span: Span) {
self
.cfg
.push_assign
(
block
,
scope_id
,
span
,
&
tuple_ref
,
// tuple_ref = &tuple;
Rvalue
::
Ref
(
region
,
BorrowKind
::
Shared
,
tuple
));
let
cleanup
=
self
.diverge_cleanup
();
self
.cfg
.terminate
(
block
,
Terminator
::
Call
{
self
.cfg
.terminate
(
block
,
Terminator
Kind
::
Call
{
func
:
Operand
::
Constant
(
func
),
args
:
vec!
[
Operand
::
Consume
(
tuple_ref
)],
cleanup
:
cleanup
,
...
...
@@ -575,7 +575,7 @@ fn build_scope_drops<'tcx>(cfg: &mut CFG<'tcx>,
earlier_scopes
.iter
()
.rev
()
.flat_map
(|
s
|
s
.cached_block
())
.next
()
});
let
next
=
cfg
.start_new_block
();
cfg
.terminate
(
block
,
Terminator
::
Drop
{
cfg
.terminate
(
block
,
Terminator
Kind
::
Drop
{
value
:
drop_data
.value
.clone
(),
target
:
next
,
unwind
:
on_diverge
...
...
@@ -600,7 +600,7 @@ fn build_diverge_scope<'tcx>(tcx: &TyCtxt<'tcx>,
for
drop_data
in
scope
.drops
.iter_mut
()
.rev
()
{
if
let
Some
(
cached_block
)
=
drop_data
.cached_block
{
if
let
Some
((
previous_block
,
previous_value
))
=
previous
{
cfg
.terminate
(
previous_block
,
Terminator
::
Drop
{
cfg
.terminate
(
previous_block
,
Terminator
Kind
::
Drop
{
value
:
previous_value
,
target
:
cached_block
,
unwind
:
None
...
...
@@ -613,7 +613,7 @@ fn build_diverge_scope<'tcx>(tcx: &TyCtxt<'tcx>,
let
block
=
cfg
.start_new_cleanup_block
();
drop_data
.cached_block
=
Some
(
block
);
if
let
Some
((
previous_block
,
previous_value
))
=
previous
{
cfg
.terminate
(
previous_block
,
Terminator
::
Drop
{
cfg
.terminate
(
previous_block
,
Terminator
Kind
::
Drop
{
value
:
previous_value
,
target
:
block
,
unwind
:
None
...
...
@@ -628,7 +628,7 @@ fn build_diverge_scope<'tcx>(tcx: &TyCtxt<'tcx>,
// Prepare the end target for this chain.
let
mut
target
=
target
.unwrap_or_else
(||{
let
b
=
cfg
.start_new_cleanup_block
();
cfg
.terminate
(
b
,
Terminator
::
Resume
);
cfg
.terminate
(
b
,
Terminator
Kind
::
Resume
);
b
});
...
...
@@ -646,7 +646,7 @@ fn build_diverge_scope<'tcx>(tcx: &TyCtxt<'tcx>,
if
let
Some
((
previous_block
,
previous_value
))
=
previous
{
// Finally, branch into that just-built `target` from the `previous_block`.
cfg
.terminate
(
previous_block
,
Terminator
::
Drop
{
cfg
.terminate
(
previous_block
,
Terminator
Kind
::
Drop
{
value
:
previous_value
,
target
:
target
,
unwind
:
None
...
...
@@ -662,14 +662,15 @@ fn build_diverge_scope<'tcx>(tcx: &TyCtxt<'tcx>,
fn
build_free
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
unit_temp
:
Lvalue
<
'tcx
>
,
data
:
&
FreeData
<
'tcx
>
,
target
:
BasicBlock
)
->
Terminator
<
'tcx
>
{
target
:
BasicBlock
)
->
TerminatorKind
<
'tcx
>
{
let
free_func
=
tcx
.lang_items
.require
(
lang_items
::
BoxFreeFnLangItem
)
.unwrap_or_else
(|
e
|
tcx
.sess
.fatal
(
&
e
));
let
substs
=
tcx
.mk_substs
(
Substs
::
new
(
VecPerParamSpace
::
new
(
vec!
[],
vec!
[],
vec!
[
data
.item_ty
]),
VecPerParamSpace
::
new
(
vec!
[],
vec!
[],
vec!
[])
));
Terminator
::
Call
{
Terminator
Kind
::
Call
{
func
:
Operand
::
Constant
(
Constant
{
span
:
data
.span
,
ty
:
tcx
.lookup_item_type
(
free_func
)
.ty
.subst
(
tcx
,
substs
),
...
...
src/librustc_mir/graphviz.rs
浏览文件 @
3a16f57f
...
...
@@ -83,7 +83,7 @@ pub fn write_node_label<W: Write, INIT, FINI>(block: BasicBlock,
// Terminator head at the bottom, not including the list of successor blocks. Those will be
// displayed as labels on the edges between blocks.
let
mut
terminator_head
=
String
::
new
();
data
.terminator
()
.fmt_head
(
&
mut
terminator_head
)
.unwrap
();
data
.terminator
()
.
kind
.
fmt_head
(
&
mut
terminator_head
)
.unwrap
();
write!
(
w
,
r#"<tr><td align="left">{}</td></tr>"#
,
dot
::
escape_html
(
&
terminator_head
))
?
;
fini
(
w
)
?
;
...
...
@@ -104,7 +104,7 @@ fn write_node<W: Write>(block: BasicBlock, mir: &Mir, w: &mut W) -> io::Result<(
/// Write graphviz DOT edges with labels between the given basic block and all of its successors.
fn
write_edges
<
W
:
Write
>
(
source
:
BasicBlock
,
mir
:
&
Mir
,
w
:
&
mut
W
)
->
io
::
Result
<
()
>
{
let
terminator
=
&
mir
.basic_block_data
(
source
)
.terminator
();
let
labels
=
terminator
.fmt_successor_labels
();
let
labels
=
terminator
.
kind
.
fmt_successor_labels
();
for
(
&
target
,
label
)
in
terminator
.successors
()
.iter
()
.zip
(
labels
)
{
writeln!
(
w
,
r#" {} -> {} [label="{}"];"#
,
node
(
source
),
node
(
target
),
label
)
?
;
...
...
src/librustc_mir/transform/erase_regions.rs
浏览文件 @
3a16f57f
...
...
@@ -58,17 +58,17 @@ fn visit_mir(&mut self, mir: &mut Mir<'tcx>) {
}
fn
visit_terminator
(
&
mut
self
,
bb
:
BasicBlock
,
terminator
:
&
mut
Terminator
<
'tcx
>
)
{
match
*
terminator
{
Terminator
::
Goto
{
..
}
|
Terminator
::
Resume
|
Terminator
::
Return
|
Terminator
::
If
{
..
}
|
Terminator
::
Switch
{
..
}
|
Terminator
::
Drop
{
..
}
|
Terminator
::
Call
{
..
}
=>
{
match
terminator
.kind
{
Terminator
Kind
::
Goto
{
..
}
|
Terminator
Kind
::
Resume
|
Terminator
Kind
::
Return
|
Terminator
Kind
::
If
{
..
}
|
Terminator
Kind
::
Switch
{
..
}
|
Terminator
Kind
::
Drop
{
..
}
|
Terminator
Kind
::
Call
{
..
}
=>
{
/* nothing to do */
},
Terminator
::
SwitchInt
{
ref
mut
switch_ty
,
..
}
=>
{
Terminator
Kind
::
SwitchInt
{
ref
mut
switch_ty
,
..
}
=>
{
*
switch_ty
=
self
.tcx
.erase_regions
(
switch_ty
);
},
}
...
...
src/librustc_mir/transform/no_landing_pads.rs
浏览文件 @
3a16f57f
...
...
@@ -21,19 +21,19 @@
impl
<
'tcx
>
MutVisitor
<
'tcx
>
for
NoLandingPads
{
fn
visit_terminator
(
&
mut
self
,
bb
:
BasicBlock
,
terminator
:
&
mut
Terminator
<
'tcx
>
)
{
match
*
terminator
{
Terminator
::
Goto
{
..
}
|
Terminator
::
Resume
|
Terminator
::
Return
|
Terminator
::
If
{
..
}
|
Terminator
::
Switch
{
..
}
|
Terminator
::
SwitchInt
{
..
}
=>
{
match
terminator
.kind
{
Terminator
Kind
::
Goto
{
..
}
|
Terminator
Kind
::
Resume
|
Terminator
Kind
::
Return
|
Terminator
Kind
::
If
{
..
}
|
Terminator
Kind
::
Switch
{
..
}
|
Terminator
Kind
::
SwitchInt
{
..
}
=>
{
/* nothing to do */
},
Terminator
::
Drop
{
ref
mut
unwind
,
..
}
=>
{
Terminator
Kind
::
Drop
{
ref
mut
unwind
,
..
}
=>
{
unwind
.take
();
},
Terminator
::
Call
{
ref
mut
cleanup
,
..
}
=>
{
Terminator
Kind
::
Call
{
ref
mut
cleanup
,
..
}
=>
{
cleanup
.take
();
},
}
...
...
src/librustc_mir/transform/simplify_cfg.rs
浏览文件 @
3a16f57f
...
...
@@ -30,8 +30,8 @@ fn final_target(mir: &Mir, mut target: BasicBlock) -> Option<BasicBlock> {
let
mut
seen
:
Vec
<
BasicBlock
>
=
Vec
::
with_capacity
(
8
);
while
mir
.basic_block_data
(
target
)
.statements
.is_empty
()
{
match
mir
.basic_block_data
(
target
)
.terminator
{
Some
(
Terminator
::
Goto
{
target
:
next
})
=>
{
match
mir
.basic_block_data
(
target
)
.terminator
()
.kind
{
TerminatorKind
::
Goto
{
target
:
next
}
=>
{
if
seen
.contains
(
&
next
)
{
return
None
;
}
...
...
@@ -71,27 +71,27 @@ fn simplify_branches(&self, mir: &mut Mir) -> bool {
for
bb
in
mir
.all_basic_blocks
()
{
let
basic_block
=
mir
.basic_block_data_mut
(
bb
);
let
mut
terminator
=
basic_block
.terminator_mut
();
*
terminator
=
match
*
terminator
{
Terminator
::
If
{
ref
targets
,
..
}
if
targets
.0
==
targets
.1
=>
{
terminator
.kind
=
match
terminator
.kind
{
Terminator
Kind
::
If
{
ref
targets
,
..
}
if
targets
.0
==
targets
.1
=>
{
changed
=
true
;
Terminator
::
Goto
{
target
:
targets
.0
}
Terminator
Kind
::
Goto
{
target
:
targets
.0
}
}
Terminator
::
If
{
ref
targets
,
cond
:
Operand
::
Constant
(
Constant
{
Terminator
Kind
::
If
{
ref
targets
,
cond
:
Operand
::
Constant
(
Constant
{
literal
:
Literal
::
Value
{
value
:
ConstVal
::
Bool
(
cond
)
},
..
})
}
=>
{
changed
=
true
;
if
cond
{
Terminator
::
Goto
{
target
:
targets
.0
}
Terminator
Kind
::
Goto
{
target
:
targets
.0
}
}
else
{
Terminator
::
Goto
{
target
:
targets
.1
}
Terminator
Kind
::
Goto
{
target
:
targets
.1
}
}
}
Terminator
::
SwitchInt
{
ref
targets
,
..
}
if
targets
.len
()
==
1
=>
{
Terminator
::
Goto
{
target
:
targets
[
0
]
}
Terminator
Kind
::
SwitchInt
{
ref
targets
,
..
}
if
targets
.len
()
==
1
=>
{
Terminator
Kind
::
Goto
{
target
:
targets
[
0
]
}
}
_
=>
continue
}
...
...
src/librustc_mir/transform/type_check.rs
浏览文件 @
3a16f57f
...
...
@@ -376,15 +376,15 @@ fn check_terminator(&self,
term
:
&
Terminator
<
'tcx
>
)
{
debug!
(
"check_terminator: {:?}"
,
term
);
let
tcx
=
self
.tcx
();
match
*
term
{
Terminator
::
Goto
{
..
}
|
Terminator
::
Resume
|
Terminator
::
Return
|
Terminator
::
Drop
{
..
}
=>
{
match
term
.kind
{
Terminator
Kind
::
Goto
{
..
}
|
Terminator
Kind
::
Resume
|
Terminator
Kind
::
Return
|
Terminator
Kind
::
Drop
{
..
}
=>
{
// no checks needed for these
}
Terminator
::
If
{
ref
cond
,
..
}
=>
{
Terminator
Kind
::
If
{
ref
cond
,
..
}
=>
{
let
cond_ty
=
mir
.operand_ty
(
tcx
,
cond
);
match
cond_ty
.sty
{
ty
::
TyBool
=>
{}
...
...
@@ -393,7 +393,7 @@ fn check_terminator(&self,
}
}
}
Terminator
::
SwitchInt
{
ref
discr
,
switch_ty
,
..
}
=>
{
Terminator
Kind
::
SwitchInt
{
ref
discr
,
switch_ty
,
..
}
=>
{
let
discr_ty
=
mir
.lvalue_ty
(
tcx
,
discr
)
.to_ty
(
tcx
);
if
let
Err
(
terr
)
=
self
.mk_subty
(
self
.last_span
,
discr_ty
,
switch_ty
)
{
span_mirbug!
(
self
,
term
,
"bad SwitchInt ({:?} on {:?}): {:?}"
,
...
...
@@ -406,7 +406,7 @@ fn check_terminator(&self,
}
// FIXME: check the values
}
Terminator
::
Switch
{
ref
discr
,
adt_def
,
ref
targets
}
=>
{
Terminator
Kind
::
Switch
{
ref
discr
,
adt_def
,
ref
targets
}
=>
{
let
discr_ty
=
mir
.lvalue_ty
(
tcx
,
discr
)
.to_ty
(
tcx
);
match
discr_ty
.sty
{
ty
::
TyEnum
(
def
,
_
)
...
...
@@ -418,7 +418,7 @@ fn check_terminator(&self,
}
}
}
Terminator
::
Call
{
ref
func
,
ref
args
,
ref
destination
,
..
}
=>
{
Terminator
Kind
::
Call
{
ref
func
,
ref
args
,
ref
destination
,
..
}
=>
{
let
func_ty
=
mir
.operand_ty
(
tcx
,
func
);
debug!
(
"check_terminator: call, func_ty={:?}"
,
func_ty
);
let
func_ty
=
match
func_ty
.sty
{
...
...
src/librustc_trans/trans/mir/block.rs
浏览文件 @
3a16f57f
...
...
@@ -56,8 +56,8 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
debug!
(
"trans_block: terminator: {:?}"
,
data
.terminator
());
match
*
data
.terminator
()
{
mir
::
Terminator
::
Resume
=>
{
match
data
.terminator
()
.kind
{
mir
::
Terminator
Kind
::
Resume
=>
{
if
let
Some
(
cleanup_pad
)
=
cleanup_pad
{
bcx
.cleanup_ret
(
cleanup_pad
,
None
);
}
else
{
...
...
@@ -70,18 +70,18 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
}
}
mir
::
Terminator
::
Goto
{
target
}
=>
{
mir
::
Terminator
Kind
::
Goto
{
target
}
=>
{
funclet_br
(
bcx
,
self
.llblock
(
target
));
}
mir
::
Terminator
::
If
{
ref
cond
,
targets
:
(
true_bb
,
false_bb
)
}
=>
{
mir
::
Terminator
Kind
::
If
{
ref
cond
,
targets
:
(
true_bb
,
false_bb
)
}
=>
{
let
cond
=
self
.trans_operand
(
&
bcx
,
cond
);
let
lltrue
=
self
.llblock
(
true_bb
);
let
llfalse
=
self
.llblock
(
false_bb
);
bcx
.cond_br
(
cond
.immediate
(),
lltrue
,
llfalse
);
}
mir
::
Terminator
::
Switch
{
ref
discr
,
ref
adt_def
,
ref
targets
}
=>
{
mir
::
Terminator
Kind
::
Switch
{
ref
discr
,
ref
adt_def
,
ref
targets
}
=>
{
let
discr_lvalue
=
self
.trans_lvalue
(
&
bcx
,
discr
);
let
ty
=
discr_lvalue
.ty
.to_ty
(
bcx
.tcx
());
let
repr
=
adt
::
represent_type
(
bcx
.ccx
(),
ty
);
...
...
@@ -103,7 +103,7 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
}
}
mir
::
Terminator
::
SwitchInt
{
ref
discr
,
switch_ty
,
ref
values
,
ref
targets
}
=>
{
mir
::
Terminator
Kind
::
SwitchInt
{
ref
discr
,
switch_ty
,
ref
values
,
ref
targets
}
=>
{
let
(
otherwise
,
targets
)
=
targets
.split_last
()
.unwrap
();
let
discr
=
bcx
.load
(
self
.trans_lvalue
(
&
bcx
,
discr
)
.llval
);
let
discr
=
bcx
.with_block
(|
bcx
|
base
::
to_immediate
(
bcx
,
discr
,
switch_ty
));
...
...
@@ -115,13 +115,13 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
}
}
mir
::
Terminator
::
Return
=>
{
mir
::
Terminator
Kind
::
Return
=>
{
bcx
.with_block
(|
bcx
|
{
self
.fcx
.build_return_block
(
bcx
,
DebugLoc
::
None
);
})
}
mir
::
Terminator
::
Drop
{
ref
value
,
target
,
unwind
}
=>
{
mir
::
Terminator
Kind
::
Drop
{
ref
value
,
target
,
unwind
}
=>
{
let
lvalue
=
self
.trans_lvalue
(
&
bcx
,
value
);
let
ty
=
lvalue
.ty
.to_ty
(
bcx
.tcx
());
// Double check for necessity to drop
...
...
@@ -152,7 +152,7 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
}
}
mir
::
Terminator
::
Call
{
ref
func
,
ref
args
,
ref
destination
,
ref
cleanup
}
=>
{
mir
::
Terminator
Kind
::
Call
{
ref
func
,
ref
args
,
ref
destination
,
ref
cleanup
}
=>
{
// Create the callee. This is a fn ptr or zero-sized and hence a kind of scalar.
let
callee
=
self
.trans_operand
(
&
bcx
,
func
);
...
...
@@ -569,3 +569,4 @@ pub fn llblock(&self, bb: mir::BasicBlock) -> BasicBlockRef {
self
.blocks
[
bb
.index
()]
.llbb
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录