Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
0676c3bf
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,发现更多精彩内容 >>
提交
0676c3bf
编写于
12月 09, 2014
作者:
J
Jorge Aparicio
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
librustc_trans: use unboxed closures
上级
0d4d8b9b
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
140 addition
and
107 deletion
+140
-107
src/librustc_trans/back/write.rs
src/librustc_trans/back/write.rs
+6
-2
src/librustc_trans/save/mod.rs
src/librustc_trans/save/mod.rs
+3
-1
src/librustc_trans/trans/_match.rs
src/librustc_trans/trans/_match.rs
+9
-8
src/librustc_trans/trans/adt.rs
src/librustc_trans/trans/adt.rs
+7
-4
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/base.rs
+20
-13
src/librustc_trans/trans/cabi_x86_64.rs
src/librustc_trans/trans/cabi_x86_64.rs
+7
-5
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/callee.rs
+9
-9
src/librustc_trans/trans/cleanup.rs
src/librustc_trans/trans/cleanup.rs
+2
-2
src/librustc_trans/trans/datum.rs
src/librustc_trans/trans/datum.rs
+19
-16
src/librustc_trans/trans/debuginfo.rs
src/librustc_trans/trans/debuginfo.rs
+7
-7
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/expr.rs
+51
-40
未找到文件。
src/librustc_trans/back/write.rs
浏览文件 @
0676c3bf
...
...
@@ -488,8 +488,12 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
// pass manager passed to the closure should be ensured to not
// escape the closure itself, and the manager should only be
// used once.
unsafe
fn
with_codegen
(
tm
:
TargetMachineRef
,
llmod
:
ModuleRef
,
no_builtins
:
bool
,
f
:
|
PassManagerRef
|)
{
unsafe
fn
with_codegen
<
F
>
(
tm
:
TargetMachineRef
,
llmod
:
ModuleRef
,
no_builtins
:
bool
,
f
:
F
)
where
F
:
FnOnce
(
PassManagerRef
),
{
let
cpm
=
llvm
::
LLVMCreatePassManager
();
llvm
::
LLVMRustAddAnalysisPasses
(
tm
,
cpm
,
llmod
);
llvm
::
LLVMRustAddLibraryInfo
(
cpm
,
llmod
,
no_builtins
);
...
...
src/librustc_trans/save/mod.rs
浏览文件 @
0676c3bf
...
...
@@ -79,7 +79,9 @@ struct DxrVisitor<'l, 'tcx: 'l> {
}
impl
<
'l
,
'tcx
>
DxrVisitor
<
'l
,
'tcx
>
{
fn
nest
(
&
mut
self
,
scope_id
:
NodeId
,
f
:
|
&
mut
DxrVisitor
<
'l
,
'tcx
>
|)
{
fn
nest
<
F
>
(
&
mut
self
,
scope_id
:
NodeId
,
f
:
F
)
where
F
:
FnOnce
(
&
mut
DxrVisitor
<
'l
,
'tcx
>
),
{
let
parent_scope
=
self
.cur_scope
;
self
.cur_scope
=
scope_id
;
f
(
self
);
...
...
src/librustc_trans/trans/_match.rs
浏览文件 @
0676c3bf
...
...
@@ -1578,14 +1578,15 @@ pub fn store_for_loop_binding<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
bind_irrefutable_pat
(
bcx
,
pat
,
llvalue
,
body_scope
)
}
fn
mk_binding_alloca
<
'blk
,
'tcx
,
A
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
p_id
:
ast
::
NodeId
,
ident
:
&
ast
::
Ident
,
cleanup_scope
:
cleanup
::
ScopeId
,
arg
:
A
,
populate
:
|
A
,
Block
<
'blk
,
'tcx
>
,
ValueRef
,
Ty
<
'tcx
>
|
->
Block
<
'blk
,
'tcx
>
)
->
Block
<
'blk
,
'tcx
>
{
fn
mk_binding_alloca
<
'blk
,
'tcx
,
A
,
F
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
p_id
:
ast
::
NodeId
,
ident
:
&
ast
::
Ident
,
cleanup_scope
:
cleanup
::
ScopeId
,
arg
:
A
,
populate
:
F
)
->
Block
<
'blk
,
'tcx
>
where
F
:
FnOnce
(
A
,
Block
<
'blk
,
'tcx
>
,
ValueRef
,
Ty
<
'tcx
>
)
->
Block
<
'blk
,
'tcx
>
,
{
let
var_ty
=
node_id_type
(
bcx
,
p_id
);
// Allocate memory on stack for the binding.
...
...
src/librustc_trans/trans/adt.rs
浏览文件 @
0676c3bf
...
...
@@ -858,10 +858,13 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v
GEPi
(
bcx
,
val
,
&
[
0
,
ix
])
}
pub
fn
fold_variants
<
'blk
,
'tcx
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
r
:
&
Repr
<
'tcx
>
,
value
:
ValueRef
,
f
:
|
Block
<
'blk
,
'tcx
>
,
&
Struct
<
'tcx
>
,
ValueRef
|
->
Block
<
'blk
,
'tcx
>
)
->
Block
<
'blk
,
'tcx
>
{
pub
fn
fold_variants
<
'blk
,
'tcx
,
F
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
r
:
&
Repr
<
'tcx
>
,
value
:
ValueRef
,
mut
f
:
F
)
->
Block
<
'blk
,
'tcx
>
where
F
:
FnMut
(
Block
<
'blk
,
'tcx
>
,
&
Struct
<
'tcx
>
,
ValueRef
)
->
Block
<
'blk
,
'tcx
>
,
{
let
fcx
=
bcx
.fcx
;
match
*
r
{
Univariant
(
ref
st
,
_
)
=>
{
...
...
src/librustc_trans/trans/base.rs
浏览文件 @
0676c3bf
...
...
@@ -107,9 +107,11 @@
RefCell
::
new
(
None
)
})
pub
fn
with_insn_ctxt
(
blk
:
|
&
[
&
'static
str
]|)
{
TASK_LOCAL_INSN_KEY
.with
(|
slot
|
{
slot
.borrow
()
.as_ref
()
.map
(|
s
|
blk
(
s
.as_slice
()));
pub
fn
with_insn_ctxt
<
F
>
(
blk
:
F
)
where
F
:
FnOnce
(
&
[
&
'static
str
]),
{
TASK_LOCAL_INSN_KEY
.with
(
move
|
slot
|
{
slot
.borrow
()
.as_ref
()
.map
(
move
|
s
|
blk
(
s
.as_slice
()));
})
}
...
...
@@ -841,12 +843,15 @@ pub fn cast_shift_const_rhs(op: ast::BinOp,
|
a
,
b
|
unsafe
{
llvm
::
LLVMConstZExt
(
a
,
b
.to_ref
())
})
}
pub
fn
cast_shift_rhs
(
op
:
ast
::
BinOp
,
lhs
:
ValueRef
,
rhs
:
ValueRef
,
trunc
:
|
ValueRef
,
Type
|
->
ValueRef
,
zext
:
|
ValueRef
,
Type
|
->
ValueRef
)
->
ValueRef
{
pub
fn
cast_shift_rhs
<
F
,
G
>
(
op
:
ast
::
BinOp
,
lhs
:
ValueRef
,
rhs
:
ValueRef
,
trunc
:
F
,
zext
:
G
)
->
ValueRef
where
F
:
FnOnce
(
ValueRef
,
Type
)
->
ValueRef
,
G
:
FnOnce
(
ValueRef
,
Type
)
->
ValueRef
,
{
// Shifts may have any size int on the rhs
unsafe
{
if
ast_util
::
is_shift_binop
(
op
)
{
...
...
@@ -1101,10 +1106,12 @@ pub fn raw_block<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>,
common
::
BlockS
::
new
(
llbb
,
is_lpad
,
None
,
fcx
)
}
pub
fn
with_cond
<
'blk
,
'tcx
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
val
:
ValueRef
,
f
:
|
Block
<
'blk
,
'tcx
>
|
->
Block
<
'blk
,
'tcx
>
)
->
Block
<
'blk
,
'tcx
>
{
pub
fn
with_cond
<
'blk
,
'tcx
,
F
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
val
:
ValueRef
,
f
:
F
)
->
Block
<
'blk
,
'tcx
>
where
F
:
FnOnce
(
Block
<
'blk
,
'tcx
>
)
->
Block
<
'blk
,
'tcx
>
,
{
let
_
icx
=
push_ctxt
(
"with_cond"
);
let
fcx
=
bcx
.fcx
;
let
next_cx
=
fcx
.new_temp_block
(
"next"
);
...
...
src/librustc_trans/trans/cabi_x86_64.rs
浏览文件 @
0676c3bf
...
...
@@ -342,11 +342,13 @@ pub fn compute_abi_info(ccx: &CrateContext,
atys
:
&
[
Type
],
rty
:
Type
,
ret_def
:
bool
)
->
FnType
{
fn
x86_64_ty
(
ccx
:
&
CrateContext
,
ty
:
Type
,
is_mem_cls
:
|
cls
:
&
[
RegClass
]|
->
bool
,
ind_attr
:
Attribute
)
->
ArgType
{
fn
x86_64_ty
<
F
>
(
ccx
:
&
CrateContext
,
ty
:
Type
,
is_mem_cls
:
F
,
ind_attr
:
Attribute
)
->
ArgType
where
F
:
FnOnce
(
&
[
RegClass
])
->
bool
,
{
if
!
ty
.is_reg_ty
()
{
let
cls
=
classify_ty
(
ty
);
if
is_mem_cls
(
cls
.as_slice
())
{
...
...
src/librustc_trans/trans/callee.rs
浏览文件 @
0676c3bf
...
...
@@ -781,15 +781,15 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
///
/// For non-lang items, `dest` is always Some, and hence the result is written into memory
/// somewhere. Nonetheless we return the actual return value of the function.
pub
fn
trans_call_inner
<
'a
,
'blk
,
'tcx
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
call_info
:
Option
<
NodeInfo
>
,
callee_ty
:
Ty
<
'tcx
>
,
get_callee
:
|
bcx
:
Block
<
'blk
,
'tcx
>
,
arg_cleanup_scope
:
cleanup
::
ScopeId
|
->
Callee
<
'blk
,
'tcx
>
,
args
:
CallArgs
<
'a
,
'tcx
>
,
dest
:
Option
<
expr
::
Dest
>
)
->
Result
<
'blk
,
'tcx
>
{
pub
fn
trans_call_inner
<
'a
,
'blk
,
'tcx
,
F
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
call_info
:
Option
<
NodeInfo
>
,
callee_ty
:
Ty
<
'tcx
>
,
get_callee
:
F
,
args
:
CallArgs
<
'a
,
'tcx
>
,
dest
:
Option
<
expr
::
Dest
>
)
->
Result
<
'blk
,
'tcx
>
where
F
:
FnOnce
(
Block
<
'blk
,
'tcx
>
,
cleanup
::
ScopeId
)
->
Callee
<
'blk
,
'tcx
>
,
{
// Introduce a temporary cleanup scope that will contain cleanups
// for the arguments while they are being evaluated. The purpose
// this cleanup is to ensure that, should a panic occur while
...
...
src/librustc_trans/trans/cleanup.rs
浏览文件 @
0676c3bf
...
...
@@ -527,7 +527,7 @@ fn pop_scope(&self) -> CleanupScope<'blk, 'tcx> {
self
.scopes
.borrow_mut
()
.pop
()
.unwrap
()
}
fn
top_scope
<
R
>
(
&
self
,
f
:
|
&
CleanupScope
<
'blk
,
'tcx
>
|
->
R
)
->
R
{
fn
top_scope
<
R
,
F
>
(
&
self
,
f
:
F
)
->
R
where
F
:
FnOnce
(
&
CleanupScope
<
'blk
,
'tcx
>
)
->
R
{
f
(
self
.scopes
.borrow
()
.last
()
.unwrap
())
}
...
...
@@ -1145,5 +1145,5 @@ fn trans_cleanups_to_exit_scope(&'blk self,
fn
scopes_len
(
&
self
)
->
uint
;
fn
push_scope
(
&
self
,
scope
:
CleanupScope
<
'blk
,
'tcx
>
);
fn
pop_scope
(
&
self
)
->
CleanupScope
<
'blk
,
'tcx
>
;
fn
top_scope
<
R
>
(
&
self
,
f
:
|
&
CleanupScope
<
'blk
,
'tcx
>
|
->
R
)
->
R
;
fn
top_scope
<
R
,
F
>
(
&
self
,
f
:
F
)
->
R
where
F
:
FnOnce
(
&
CleanupScope
<
'blk
,
'tcx
>
)
->
R
;
}
src/librustc_trans/trans/datum.rs
浏览文件 @
0676c3bf
...
...
@@ -113,15 +113,16 @@ pub fn immediate_rvalue_bcx<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
/// it. The memory will be dropped upon exit from `scope`. The callback `populate` should
/// initialize the memory. If `zero` is true, the space will be zeroed when it is allocated; this
/// is not necessary unless `bcx` does not dominate the end of `scope`.
pub
fn
lvalue_scratch_datum
<
'blk
,
'tcx
,
A
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
name
:
&
str
,
zero
:
bool
,
scope
:
cleanup
::
ScopeId
,
arg
:
A
,
populate
:
|
A
,
Block
<
'blk
,
'tcx
>
,
ValueRef
|
->
Block
<
'blk
,
'tcx
>
)
->
DatumBlock
<
'blk
,
'tcx
,
Lvalue
>
{
pub
fn
lvalue_scratch_datum
<
'blk
,
'tcx
,
A
,
F
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
name
:
&
str
,
zero
:
bool
,
scope
:
cleanup
::
ScopeId
,
arg
:
A
,
populate
:
F
)
->
DatumBlock
<
'blk
,
'tcx
,
Lvalue
>
where
F
:
FnOnce
(
A
,
Block
<
'blk
,
'tcx
>
,
ValueRef
)
->
Block
<
'blk
,
'tcx
>
,
{
let
scratch
=
if
zero
{
alloca_zeroed
(
bcx
,
ty
,
name
)
}
else
{
...
...
@@ -339,10 +340,10 @@ pub fn to_appropriate_datum<'blk>(self, bcx: Block<'blk, 'tcx>)
/// here since we can `match self.kind` rather than having to implement
/// generic methods in `KindOps`.)
impl
<
'tcx
>
Datum
<
'tcx
,
Expr
>
{
fn
match_kind
<
R
>
(
self
,
if_lvalue
:
|
Datum
<
'tcx
,
Lvalue
>
|
->
R
,
if_rvalue
:
|
Datum
<
'tcx
,
Rvalue
>
|
->
R
)
->
R
{
fn
match_kind
<
R
,
F
,
G
>
(
self
,
if_lvalue
:
F
,
if_rvalue
:
G
)
->
R
where
F
:
FnOnce
(
Datum
<
'tcx
,
Lvalue
>
)
->
R
,
G
:
FnOnce
(
Datum
<
'tcx
,
Rvalue
>
)
->
R
,
{
let
Datum
{
val
,
ty
,
kind
}
=
self
;
match
kind
{
LvalueExpr
=>
if_lvalue
(
Datum
::
new
(
val
,
ty
,
Lvalue
)),
...
...
@@ -455,9 +456,11 @@ pub fn to_llref(self) -> ValueRef {
// datum may also be unsized _without the size information_. It is the
// callers responsibility to package the result in some way to make a valid
// datum in that case (e.g., by making a fat pointer or opened pair).
pub
fn
get_element
<
'blk
>
(
&
self
,
bcx
:
Block
<
'blk
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
gep
:
|
ValueRef
|
->
ValueRef
)
->
Datum
<
'tcx
,
Lvalue
>
{
pub
fn
get_element
<
'blk
,
F
>
(
&
self
,
bcx
:
Block
<
'blk
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
gep
:
F
)
->
Datum
<
'tcx
,
Lvalue
>
where
F
:
FnOnce
(
ValueRef
)
->
ValueRef
,
{
let
val
=
match
self
.ty.sty
{
_
if
ty
::
type_is_sized
(
bcx
.tcx
(),
self
.ty
)
=>
gep
(
self
.val
),
ty
::
ty_open
(
_
)
=>
{
...
...
src/librustc_trans/trans/debuginfo.rs
浏览文件 @
0676c3bf
...
...
@@ -3212,13 +3212,13 @@ struct ScopeStackEntry {
});
// local helper functions for walking the AST.
fn
with_new_scope
(
cx
:
&
CrateContext
,
scope_span
:
Span
,
scope_stack
:
&
mut
Vec
<
ScopeStackEntry
>
,
scope_map
:
&
mut
NodeMap
<
DIScope
>
,
inner_walk
:
|
&
CrateContext
,
&
mut
Vec
<
ScopeStackEntry
>
,
&
mut
NodeMap
<
DIScope
>
|)
{
fn
with_new_scope
<
F
>
(
cx
:
&
CrateContext
,
scope_span
:
Span
,
scope_stack
:
&
mut
Vec
<
ScopeStackEntry
>
,
scope_map
:
&
mut
NodeMap
<
DIScope
>
,
inner_walk
:
F
)
where
F
:
FnOnce
(
&
CrateContext
,
&
mut
Vec
<
ScopeStackEntry
>
,
&
mut
NodeMap
<
DIScope
>
)
,
{
// Create a new lexical scope and push it onto the stack
let
loc
=
cx
.sess
()
.codemap
()
.lookup_char_pos
(
scope_span
.lo
);
let
file_metadata
=
file_metadata
(
cx
,
loc
.file.name
.as_slice
());
...
...
src/librustc_trans/trans/expr.rs
浏览文件 @
0676c3bf
...
...
@@ -295,6 +295,7 @@ fn ref_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// into a type to be destructed. If we want to end up with a Box pointer,
// then mk_ty should make a Box pointer (T -> Box<T>), if we want a
// borrowed reference then it should be T -> &T.
// FIXME(#19596) unbox `mk_ty`
fn
unsized_info
<
'blk
,
'tcx
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
kind
:
&
ty
::
UnsizeKind
<
'tcx
>
,
id
:
ast
::
NodeId
,
...
...
@@ -341,27 +342,30 @@ fn unsize_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
debug!
(
"dest_ty={}"
,
unsized_ty
.repr
(
bcx
.tcx
()));
// Closures for extracting and manipulating the data and payload parts of
// the fat pointer.
let
base
=
match
k
{
&
ty
::
UnsizeStruct
(
..
)
=>
|
bcx
,
val
|
PointerCast
(
bcx
,
val
,
type_of
::
type_of
(
bcx
.ccx
(),
unsized_ty
)
.ptr_to
()),
&
ty
::
UnsizeLength
(
..
)
=>
|
bcx
,
val
|
GEPi
(
bcx
,
val
,
&
[
0u
,
0u
]),
&
ty
::
UnsizeVtable
(
..
)
=>
|
_
bcx
,
val
|
PointerCast
(
bcx
,
val
,
Type
::
i8p
(
bcx
.ccx
()))
};
let
info
=
|
bcx
,
_
val
|
unsized_info
(
bcx
,
k
,
expr
.id
,
datum_ty
,
|
t
|
ty
::
mk_rptr
(
tcx
,
ty
::
ReStatic
,
ty
::
mt
{
ty
:
t
,
mutbl
:
ast
::
MutImmutable
}));
into_fat_ptr
(
bcx
,
expr
,
datum
,
dest_ty
,
base
,
info
)
let
info
=
|:
bcx
,
_
val
|
unsized_info
(
bcx
,
k
,
expr
.id
,
datum_ty
,
|
t
|
ty
::
mk_rptr
(
tcx
,
ty
::
ReStatic
,
ty
::
mt
{
ty
:
t
,
mutbl
:
ast
::
MutImmutable
}));
match
*
k
{
ty
::
UnsizeStruct
(
..
)
=>
into_fat_ptr
(
bcx
,
expr
,
datum
,
dest_ty
,
|
bcx
,
val
|
{
PointerCast
(
bcx
,
val
,
type_of
::
type_of
(
bcx
.ccx
(),
unsized_ty
)
.ptr_to
())
},
info
),
ty
::
UnsizeLength
(
..
)
=>
into_fat_ptr
(
bcx
,
expr
,
datum
,
dest_ty
,
|
bcx
,
val
|
{
GEPi
(
bcx
,
val
,
&
[
0u
,
0u
])
},
info
),
ty
::
UnsizeVtable
(
..
)
=>
into_fat_ptr
(
bcx
,
expr
,
datum
,
dest_ty
,
|
_
bcx
,
val
|
{
PointerCast
(
bcx
,
val
,
Type
::
i8p
(
bcx
.ccx
()))
},
info
),
}
}
fn
ref_fat_ptr
<
'blk
,
'tcx
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
...
...
@@ -370,18 +374,21 @@ fn ref_fat_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
->
DatumBlock
<
'blk
,
'tcx
,
Expr
>
{
let
tcx
=
bcx
.tcx
();
let
dest_ty
=
ty
::
close_type
(
tcx
,
datum
.ty
);
let
base
=
|
bcx
,
val
|
Load
(
bcx
,
get_dataptr
(
bcx
,
val
));
let
len
=
|
bcx
,
val
|
Load
(
bcx
,
get_len
(
bcx
,
val
));
let
base
=
|
:
bcx
,
val
|
Load
(
bcx
,
get_dataptr
(
bcx
,
val
));
let
len
=
|
:
bcx
,
val
|
Load
(
bcx
,
get_len
(
bcx
,
val
));
into_fat_ptr
(
bcx
,
expr
,
datum
,
dest_ty
,
base
,
len
)
}
fn
into_fat_ptr
<
'blk
,
'tcx
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
expr
:
&
ast
::
Expr
,
datum
:
Datum
<
'tcx
,
Expr
>
,
dest_ty
:
Ty
<
'tcx
>
,
base
:
|
Block
<
'blk
,
'tcx
>
,
ValueRef
|
->
ValueRef
,
info
:
|
Block
<
'blk
,
'tcx
>
,
ValueRef
|
->
ValueRef
)
->
DatumBlock
<
'blk
,
'tcx
,
Expr
>
{
fn
into_fat_ptr
<
'blk
,
'tcx
,
F
,
G
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
expr
:
&
ast
::
Expr
,
datum
:
Datum
<
'tcx
,
Expr
>
,
dest_ty
:
Ty
<
'tcx
>
,
base
:
F
,
info
:
G
)
->
DatumBlock
<
'blk
,
'tcx
,
Expr
>
where
F
:
FnOnce
(
Block
<
'blk
,
'tcx
>
,
ValueRef
)
->
ValueRef
,
G
:
FnOnce
(
Block
<
'blk
,
'tcx
>
,
ValueRef
)
->
ValueRef
,
{
let
mut
bcx
=
bcx
;
// Arrange cleanup
...
...
@@ -659,17 +666,19 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
}
fn
trans_field
<
'blk
,
'tcx
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
base
:
&
ast
::
Expr
,
get_idx
:
|
&
'blk
ty
::
ctxt
<
'tcx
>
,
&
[
ty
::
field
<
'tcx
>
]|
->
uint
)
->
DatumBlock
<
'blk
,
'tcx
,
Expr
>
{
fn
trans_field
<
'blk
,
'tcx
,
F
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
base
:
&
ast
::
Expr
,
get_idx
:
F
)
->
DatumBlock
<
'blk
,
'tcx
,
Expr
>
where
F
:
FnOnce
(
&
'blk
ty
::
ctxt
<
'tcx
>
,
&
[
ty
::
field
<
'tcx
>
])
->
uint
,
{
let
mut
bcx
=
bcx
;
let
_
icx
=
push_ctxt
(
"trans_rec_field"
);
let
base_datum
=
unpack_datum!
(
bcx
,
trans_to_lvalue
(
bcx
,
base
,
"field"
));
let
bare_ty
=
ty
::
unopen_type
(
base_datum
.ty
);
let
repr
=
adt
::
represent_type
(
bcx
.ccx
(),
bare_ty
);
with_field_tys
(
bcx
.tcx
(),
bare_ty
,
None
,
|
discr
,
field_tys
|
{
with_field_tys
(
bcx
.tcx
(),
bare_ty
,
None
,
move
|
discr
,
field_tys
|
{
let
ix
=
get_idx
(
bcx
.tcx
(),
field_tys
);
let
d
=
base_datum
.get_element
(
bcx
,
...
...
@@ -1254,11 +1263,13 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
/// Helper for enumerating the field types of structs, enums, or records. The optional node ID here
/// is the node ID of the path identifying the enum variant in use. If none, this cannot possibly
/// an enum variant (so, if it is and `node_id_opt` is none, this function panics).
pub
fn
with_field_tys
<
'tcx
,
R
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
node_id_opt
:
Option
<
ast
::
NodeId
>
,
op
:
|
ty
::
Disr
,
(
&
[
ty
::
field
<
'tcx
>
])|
->
R
)
->
R
{
pub
fn
with_field_tys
<
'tcx
,
R
,
F
>
(
tcx
:
&
ty
::
ctxt
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
node_id_opt
:
Option
<
ast
::
NodeId
>
,
op
:
F
)
->
R
where
F
:
FnOnce
(
ty
::
Disr
,
&
[
ty
::
field
<
'tcx
>
])
->
R
,
{
match
ty
.sty
{
ty
::
ty_struct
(
did
,
ref
substs
)
=>
{
op
(
0
,
struct_fields
(
tcx
,
did
,
substs
)
.as_slice
())
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录