Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
a5997f2e
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,发现更多精彩内容 >>
提交
a5997f2e
编写于
8月 09, 2011
作者:
G
Graydon Hoare
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Actually perform handoff from caller to callee on move-mode args.
上级
5adaa6f9
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
53 addition
and
9 deletion
+53
-9
src/comp/middle/trans.rs
src/comp/middle/trans.rs
+41
-9
src/test/run-pass/move-arg-2.rs
src/test/run-pass/move-arg-2.rs
+12
-0
未找到文件。
src/comp/middle/trans.rs
浏览文件 @
a5997f2e
...
...
@@ -4656,7 +4656,10 @@ fn trans_bind_1(cx: &@block_ctxt, f: &@ast::expr, f_res: &lval_result,
ret
rslt
(
bcx
,
pair_v
);
}
fn
trans_arg_expr
(
cx
:
&@
block_ctxt
,
arg
:
&
ty
::
arg
,
lldestty0
:
TypeRef
,
fn
trans_arg_expr
(
cx
:
&@
block_ctxt
,
arg
:
&
ty
::
arg
,
lldestty0
:
TypeRef
,
to_zero
:
&
mutable
[{
v
:
ValueRef
,
t
:
ty
::
t
}],
to_revoke
:
&
mutable
[
ValueRef
],
e
:
&@
ast
::
expr
)
->
result
{
let
ccx
=
bcx_ccx
(
cx
);
let
e_ty
=
ty
::
expr_ty
(
ccx
.tcx
,
e
);
...
...
@@ -4711,6 +4714,15 @@ fn trans_arg_expr(cx: &@block_ctxt, arg: &ty::arg, lldestty0: TypeRef,
// we are now passing it as an arg, so need to load it.
val
=
bcx
.build
.Load
(
val
);
}
// Collect arg for later if it happens to be one we've moving out.
if
arg
.mode
==
ty
::
mo_move
{
if
lv
.is_mem
{
to_zero
+=
~
[{
v
:
lv
.res.val
,
t
:
arg
.ty
}];
}
else
{
to_revoke
+=
~
[
lv
.res.val
];
}
}
ret
rslt
(
bcx
,
val
);
}
...
...
@@ -4724,10 +4736,18 @@ fn trans_arg_expr(cx: &@block_ctxt, arg: &ty::arg, lldestty0: TypeRef,
fn
trans_args
(
cx
:
&@
block_ctxt
,
llenv
:
ValueRef
,
gen
:
&
option
::
t
[
generic_info
],
lliterbody
:
&
option
::
t
[
ValueRef
],
es
:
&
[
@
ast
::
expr
],
fn_ty
:
&
ty
::
t
)
->
{
bcx
:
@
block_ctxt
,
args
:
[
ValueRef
],
retslot
:
ValueRef
}
{
{
bcx
:
@
block_ctxt
,
args
:
[
ValueRef
],
retslot
:
ValueRef
,
to_zero
:
[{
v
:
ValueRef
,
t
:
ty
::
t
}],
to_revoke
:
[
ValueRef
]
}
{
let
args
:
[
ty
::
arg
]
=
ty
::
ty_fn_args
(
bcx_tcx
(
cx
),
fn_ty
);
let
llargs
:
[
ValueRef
]
=
~
[];
let
lltydescs
:
[
ValueRef
]
=
~
[];
let
to_zero
=
~
[];
let
to_revoke
=
~
[];
let
bcx
:
@
block_ctxt
=
cx
;
// Arg 0: Output pointer.
...
...
@@ -4736,9 +4756,9 @@ fn trans_args(cx: &@block_ctxt, llenv: ValueRef,
if
bcx
.build
.is_terminated
()
{
// This means an earlier arg was divergent.
// So this arg can't be evaluated.
ret
{
bcx
:
bcx
,
args
:
~
[],
retslot
:
C_nil
()};
ret
{
bcx
:
bcx
,
args
:
~
[],
retslot
:
C_nil
(),
to_zero
:
to_zero
,
to_revoke
:
to_revoke
};
}
let
retty
=
ty
::
ty_fn_ret
(
bcx_tcx
(
cx
),
fn_ty
);
let
llretslot_res
=
alloc_ty
(
bcx
,
retty
);
bcx
=
llretslot_res
.bcx
;
...
...
@@ -4787,12 +4807,14 @@ fn trans_args(cx: &@block_ctxt, llenv: ValueRef,
// So this arg can't be evaluated.
break
;
}
let
r
=
trans_arg_expr
(
bcx
,
args
.
(
i
),
arg_tys
.
(
i
),
e
);
let
r
=
trans_arg_expr
(
bcx
,
args
.
(
i
),
arg_tys
.
(
i
),
to_zero
,
to_revoke
,
e
);
bcx
=
r
.bcx
;
llargs
+=
~
[
r
.val
];
i
+=
1u
;
}
ret
{
bcx
:
bcx
,
args
:
llargs
,
retslot
:
llretslot
};
ret
{
bcx
:
bcx
,
args
:
llargs
,
retslot
:
llretslot
,
to_zero
:
to_zero
,
to_revoke
:
to_revoke
};
}
fn
trans_call
(
cx
:
&@
block_ctxt
,
f
:
&@
ast
::
expr
,
...
...
@@ -4875,6 +4897,14 @@ fn trans_call(cx: &@block_ctxt, f: &@ast::expr,
// we should ignore llretslot.
}
}
// Forget about anything we moved out.
for
{
v
,
t
}:
{
v
:
ValueRef
,
t
:
ty
::
t
}
in
args_res
.to_zero
{
zero_alloca
(
bcx
,
v
,
t
)
}
for
v
:
ValueRef
in
args_res
.to_revoke
{
revoke_clean
(
bcx
,
v
)
}
}
ret
rslt
(
bcx
,
retval
);
}
...
...
@@ -5493,7 +5523,9 @@ fn trans_put(cx: &@block_ctxt, e: &option::t[@ast::expr]) -> result {
let
e_ty
=
ty
::
expr_ty
(
bcx_tcx
(
cx
),
x
);
let
arg
=
{
mode
:
ty
::
mo_alias
(
false
),
ty
:
e_ty
};
let
arg_tys
=
type_of_explicit_args
(
bcx_ccx
(
cx
),
x
.span
,
~
[
arg
]);
let
r
=
trans_arg_expr
(
bcx
,
arg
,
arg_tys
.
(
0
),
x
);
let
z
=
~
[];
let
k
=
~
[];
let
r
=
trans_arg_expr
(
bcx
,
arg
,
arg_tys
.
(
0
),
z
,
k
,
x
);
bcx
=
r
.bcx
;
llargs
+=
~
[
r
.val
];
}
...
...
@@ -6035,13 +6067,13 @@ fn add_cleanups_for_args(bcx: &@block_ctxt, args: &[ast::arg],
arg_tys
:
&
[
ty
::
arg
])
{
let
arg_n
:
uint
=
0u
;
for
aarg
:
ast
::
arg
in
args
{
if
aarg
.mode
==
ast
::
val
{
if
aarg
.mode
==
ast
::
val
||
aarg
.mode
==
ast
::
move
{
let
argval
;
alt
bcx
.fcx.llargs
.find
(
aarg
.id
)
{
some
(
x
)
{
argval
=
x
;
}
_
{
bcx_ccx
(
bcx
)
.sess
.span_fatal
(
aarg
.ty.span
,
"unbound arg ID in
copy_args_to_alloca
s"
);
(
aarg
.ty.span
,
"unbound arg ID in
add_cleanups_for_arg
s"
);
}
}
add_clean
(
bcx
,
argval
,
arg_tys
.
(
arg_n
)
.ty
);
...
...
src/test/run-pass/move-arg-2.rs
0 → 100644
浏览文件 @
a5997f2e
fn
test
(
foo
:
-@
[
int
])
{
assert
(
foo
.
(
0
)
==
10
);
}
fn
main
()
{
let
x
=
@~
[
10
];
// Test forgetting a local by move-in
test
(
x
);
// Test forgetting a temporary by move-in.
test
(
@~
[
10
]);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录