Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
3342da41
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,发现更多精彩内容 >>
提交
3342da41
编写于
2月 24, 2016
作者:
E
Eduard Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
trans: Don't treat closure types like function types in declare.
上级
da66431d
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
65 addition
and
100 deletion
+65
-100
src/librustc_trans/trans/attributes.rs
src/librustc_trans/trans/attributes.rs
+9
-33
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/base.rs
+0
-16
src/librustc_trans/trans/closure.rs
src/librustc_trans/trans/closure.rs
+43
-12
src/librustc_trans/trans/declare.rs
src/librustc_trans/trans/declare.rs
+11
-29
src/librustc_trans/trans/type_of.rs
src/librustc_trans/trans/type_of.rs
+2
-10
未找到文件。
src/librustc_trans/trans/attributes.rs
浏览文件 @
3342da41
...
...
@@ -13,13 +13,11 @@
use
llvm
::{
self
,
ValueRef
,
AttrHelper
};
use
middle
::
ty
;
use
middle
::
infer
;
use
middle
::
traits
::
ProjectionMode
;
use
session
::
config
::
NoDebugInfo
;
pub
use
syntax
::
attr
::
InlineAttr
;
use
syntax
::
ast
;
use
rustc_front
::
hir
;
use
trans
::
abi
::
Abi
;
use
trans
::
base
;
use
trans
::
common
;
use
trans
::
context
::
CrateContext
;
use
trans
::
machine
;
...
...
@@ -130,21 +128,12 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
->
llvm
::
AttrBuilder
{
use
middle
::
ty
::{
BrAnon
,
ReLateBound
};
let
function_type
;
let
(
fn_sig
,
abi
,
env_ty
)
=
match
fn_type
.sty
{
ty
::
TyFnDef
(
_
,
_
,
ref
f
)
|
ty
::
TyFnPtr
(
ref
f
)
=>
(
&
f
.sig
,
f
.abi
,
None
),
ty
::
TyClosure
(
closure_did
,
ref
substs
)
=>
{
let
infcx
=
infer
::
normalizing_infer_ctxt
(
ccx
.tcx
(),
&
ccx
.tcx
()
.tables
,
ProjectionMode
::
Any
);
function_type
=
infcx
.closure_type
(
closure_did
,
substs
);
let
self_type
=
base
::
self_type_for_closure
(
ccx
,
closure_did
,
fn_type
);
(
&
function_type
.sig
,
Abi
::
RustCall
,
Some
(
self_type
))
}
_
=>
ccx
.sess
()
.bug
(
"expected closure or function."
)
let
f
=
match
fn_type
.sty
{
ty
::
TyFnDef
(
_
,
_
,
f
)
|
ty
::
TyFnPtr
(
f
)
=>
f
,
_
=>
unreachable!
(
"expected fn type, found {:?}"
,
fn_type
)
};
let
fn_sig
=
ccx
.tcx
()
.erase_late_bound_regions
(
fn_
sig
);
let
fn_sig
=
ccx
.tcx
()
.erase_late_bound_regions
(
&
f
.
sig
);
let
fn_sig
=
infer
::
normalize_associated_type
(
ccx
.tcx
(),
&
fn_sig
);
let
mut
attrs
=
llvm
::
AttrBuilder
::
new
();
...
...
@@ -153,30 +142,17 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
// These have an odd calling convention, so we need to manually
// unpack the input ty's
let
input_tys
=
match
fn_type
.sty
{
ty
::
TyClosure
(
..
)
=>
{
assert
!
(
abi
==
Abi
::
RustCall
);
match
fn_sig
.inputs
[
0
]
.sty
{
ty
::
TyTuple
(
ref
inputs
)
=>
{
let
mut
full_inputs
=
vec!
[
env_ty
.expect
(
"Missing closure environment"
)];
full_inputs
.extend_from_slice
(
inputs
);
full_inputs
}
_
=>
ccx
.sess
()
.bug
(
"expected tuple'd inputs"
)
}
},
ty
::
TyFnDef
(
..
)
|
ty
::
TyFnPtr
(
_
)
if
abi
==
Abi
::
RustCall
=>
{
let
mut
inputs
=
vec!
[
fn_sig
.inputs
[
0
]];
ty
::
TyFnDef
(
..
)
|
ty
::
TyFnPtr
(
_
)
if
f
.abi
==
Abi
::
RustCall
=>
{
let
first
=
Some
(
fn_sig
.inputs
[
0
])
.into_iter
();
match
fn_sig
.inputs
[
1
]
.sty
{
ty
::
TyTuple
(
ref
t_in
)
=>
{
inputs
.extend_from_slice
(
&
t_in
[
..
]);
inputs
first
.chain
(
t_in
.iter
()
.cloned
())
}
_
=>
ccx
.sess
()
.bug
(
"expected tuple'd inputs"
)
}
}
_
=>
fn_sig
.inputs
.clone
(
)
_
=>
None
.into_iter
()
.chain
(
fn_sig
.inputs
.iter
()
.cloned
()
)
};
// Index 0 is the return value of the llvm func, so we start at 1
...
...
@@ -228,7 +204,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
}
}
for
&
t
in
input_tys
.iter
()
{
for
t
in
input_tys
{
match
t
.sty
{
_
if
type_of
::
arg_is_indirect
(
ccx
,
t
)
=>
{
let
llarg_sz
=
machine
::
llsize_of_real
(
ccx
,
type_of
::
type_of
(
ccx
,
t
));
...
...
src/librustc_trans/trans/base.rs
浏览文件 @
3342da41
...
...
@@ -192,22 +192,6 @@ fn drop(&mut self) {
}
}
pub
fn
self_type_for_closure
<
'a
,
'tcx
>
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
closure_id
:
DefId
,
fn_ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
let
closure_kind
=
ccx
.tcx
()
.closure_kind
(
closure_id
);
match
closure_kind
{
ty
::
ClosureKind
::
Fn
=>
{
ccx
.tcx
()
.mk_imm_ref
(
ccx
.tcx
()
.mk_region
(
ty
::
ReStatic
),
fn_ty
)
}
ty
::
ClosureKind
::
FnMut
=>
{
ccx
.tcx
()
.mk_mut_ref
(
ccx
.tcx
()
.mk_region
(
ty
::
ReStatic
),
fn_ty
)
}
ty
::
ClosureKind
::
FnOnce
=>
fn_ty
,
}
}
pub
fn
kind_for_closure
(
ccx
:
&
CrateContext
,
closure_id
:
DefId
)
->
ty
::
ClosureKind
{
*
ccx
.tcx
()
.tables
.borrow
()
.closure_kinds
.get
(
&
closure_id
)
.unwrap
()
}
...
...
src/librustc_trans/trans/closure.rs
浏览文件 @
3342da41
...
...
@@ -14,7 +14,7 @@
use
middle
::
def_id
::
DefId
;
use
middle
::
infer
;
use
middle
::
traits
::
ProjectionMode
;
use
trans
::
abi
::
Abi
::
RustCall
;
use
trans
::
abi
::
Abi
;
use
trans
::
adt
;
use
trans
::
attributes
;
use
trans
::
base
::
*
;
...
...
@@ -30,7 +30,7 @@
use
trans
::
type_of
::
*
;
use
trans
::
value
::
Value
;
use
trans
::
Disr
;
use
middle
::
ty
;
use
middle
::
ty
::{
self
,
Ty
,
TyCtxt
}
;
use
session
::
config
::
FullDebugInfo
;
use
syntax
::
ast
;
...
...
@@ -49,7 +49,7 @@ fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// Special case for small by-value selfs.
let
closure_ty
=
node_id_type
(
bcx
,
bcx
.fcx.id
);
let
self_type
=
self_type_for_closure
(
bcx
.c
cx
(),
closure_def_id
,
closure_ty
);
let
self_type
=
get_self_type
(
bcx
.t
cx
(),
closure_def_id
,
closure_ty
);
let
kind
=
kind_for_closure
(
bcx
.ccx
(),
closure_def_id
);
let
llenv
=
if
kind
==
ty
::
ClosureKind
::
FnOnce
&&
!
arg_is_indirect
(
bcx
.ccx
(),
self_type
)
{
...
...
@@ -131,6 +131,21 @@ pub fn load<'blk,'tcx>(self, bcx: Block<'blk, 'tcx>, arg_scope: ScopeId)
}
}
pub
fn
get_self_type
<
'tcx
>
(
tcx
:
&
TyCtxt
<
'tcx
>
,
closure_id
:
DefId
,
fn_ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
match
tcx
.closure_kind
(
closure_id
)
{
ty
::
ClosureKind
::
Fn
=>
{
tcx
.mk_imm_ref
(
tcx
.mk_region
(
ty
::
ReStatic
),
fn_ty
)
}
ty
::
ClosureKind
::
FnMut
=>
{
tcx
.mk_mut_ref
(
tcx
.mk_region
(
ty
::
ReStatic
),
fn_ty
)
}
ty
::
ClosureKind
::
FnOnce
=>
fn_ty
,
}
}
/// Returns the LLVM function declaration for a closure, creating it if
/// necessary. If the ID does not correspond to a closure ID, returns None.
pub
fn
get_or_create_closure_declaration
<
'a
,
'tcx
>
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
...
...
@@ -139,22 +154,38 @@ pub fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
->
ValueRef
{
// Normalize type so differences in regions and typedefs don't cause
// duplicate declarations
let
substs
=
ccx
.tcx
()
.erase_regions
(
substs
);
let
mono_id
=
Instance
{
let
tcx
=
ccx
.tcx
();
let
substs
=
tcx
.erase_regions
(
substs
);
let
instance
=
Instance
{
def
:
closure_id
,
params
:
&
substs
.func_substs.types
};
if
let
Some
(
&
llfn
)
=
ccx
.
closure_vals
()
.borrow
()
.get
(
&
mono_id
)
{
if
let
Some
(
&
llfn
)
=
ccx
.
instances
()
.borrow
()
.get
(
&
instance
)
{
debug!
(
"get_or_create_closure_declaration(): found closure {:?}: {:?}"
,
mono_id
,
Value
(
llfn
));
instance
,
Value
(
llfn
));
return
llfn
;
}
let
path
=
ccx
.tcx
()
.def_path
(
closure_id
);
let
path
=
tcx
.def_path
(
closure_id
);
let
symbol
=
mangle_internal_name_by_path_and_seq
(
path
,
"closure"
);
let
function_type
=
ccx
.tcx
()
.mk_closure_from_closure_substs
(
closure_id
,
Box
::
new
(
substs
));
// Compute the rust-call form of the closure call method.
let
infcx
=
infer
::
normalizing_infer_ctxt
(
tcx
,
&
tcx
.tables
,
ProjectionMode
::
Any
);
let
sig
=
&
infcx
.closure_type
(
closure_id
,
&
substs
)
.sig
;
let
sig
=
tcx
.erase_late_bound_regions
(
sig
);
let
sig
=
infer
::
normalize_associated_type
(
tcx
,
&
sig
);
let
closure_type
=
tcx
.mk_closure_from_closure_substs
(
closure_id
,
Box
::
new
(
substs
));
let
function_type
=
tcx
.mk_fn_ptr
(
ty
::
BareFnTy
{
unsafety
:
hir
::
Unsafety
::
Normal
,
abi
:
Abi
::
RustCall
,
sig
:
ty
::
Binder
(
ty
::
FnSig
{
inputs
:
Some
(
get_self_type
(
tcx
,
closure_id
,
closure_type
))
.into_iter
()
.chain
(
sig
.inputs
)
.collect
(),
output
:
sig
.output
,
variadic
:
false
})
});
let
llfn
=
declare
::
define_internal_fn
(
ccx
,
&
symbol
,
function_type
);
// set an inline hint for all closures
...
...
@@ -162,8 +193,8 @@ pub fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
debug!
(
"get_or_create_declaration_if_closure(): inserting new
\
closure {:?}: {:?}"
,
mono_id
,
Value
(
llfn
));
ccx
.
closure_vals
()
.borrow_mut
()
.insert
(
mono_id
,
llfn
);
instance
,
Value
(
llfn
));
ccx
.
instances
()
.borrow_mut
()
.insert
(
instance
,
llfn
);
llfn
}
...
...
@@ -347,7 +378,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
// Make a version of the closure type with the same arguments, but
// with argument #0 being by value.
assert_eq!
(
abi
,
RustCall
);
assert_eq!
(
abi
,
Abi
::
RustCall
);
sig
.0
.inputs
[
0
]
=
closure_ty
;
let
llonce_fn_ty
=
tcx
.mk_fn_ptr
(
ty
::
BareFnTy
{
unsafety
:
unsafety
,
...
...
src/librustc_trans/trans/declare.rs
浏览文件 @
3342da41
...
...
@@ -22,10 +22,8 @@
use
llvm
::{
self
,
ValueRef
};
use
middle
::
ty
;
use
middle
::
infer
;
use
middle
::
traits
::
ProjectionMode
;
use
trans
::
abi
::{
Abi
,
FnType
};
use
trans
::
attributes
;
use
trans
::
base
;
use
trans
::
context
::
CrateContext
;
use
trans
::
type_
::
Type
;
use
trans
::
type_of
;
...
...
@@ -94,37 +92,21 @@ pub fn declare_cfn(ccx: &CrateContext, name: &str, fn_type: Type) -> ValueRef {
/// update the declaration and return existing ValueRef instead.
pub
fn
declare_fn
<
'a
,
'tcx
>
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
name
:
&
str
,
fn_type
:
ty
::
Ty
<
'tcx
>
)
->
ValueRef
{
debug!
(
"declare_rust_fn(name={:?}, fn_type={:?})"
,
name
,
fn_type
);
let
function_type
;
// placeholder so that the memory ownership works out ok
let
(
sig
,
abi
,
env
)
=
match
fn_type
.sty
{
ty
::
TyFnDef
(
_
,
_
,
f
)
|
ty
::
TyFnPtr
(
f
)
=>
{
(
&
f
.sig
,
f
.abi
,
None
)
}
ty
::
TyClosure
(
closure_did
,
ref
substs
)
=>
{
let
infcx
=
infer
::
normalizing_infer_ctxt
(
ccx
.tcx
(),
&
ccx
.tcx
()
.tables
,
ProjectionMode
::
Any
);
function_type
=
infcx
.closure_type
(
closure_did
,
substs
);
let
self_type
=
base
::
self_type_for_closure
(
ccx
,
closure_did
,
fn_type
);
debug!
(
"declare_rust_fn function_type={:?} self_type={:?}"
,
function_type
,
self_type
);
(
&
function_type
.sig
,
Abi
::
RustCall
,
Some
(
self_type
))
}
_
=>
ccx
.sess
()
.bug
(
"expected closure or fn"
)
};
debug!
(
"declare_rust_fn(name={:?}, fn_type={:?})"
,
name
,
fn_type
);
let
f
=
match
fn_type
.sty
{
ty
::
TyFnDef
(
_
,
_
,
f
)
|
ty
::
TyFnPtr
(
f
)
=>
f
,
_
=>
unreachable!
(
"expected fn type for {:?}, found {:?}"
,
name
,
fn_type
)
};
let
sig
=
ccx
.tcx
()
.erase_late_bound_regions
(
sig
);
let
sig
=
ccx
.tcx
()
.erase_late_bound_regions
(
&
f
.
sig
);
let
sig
=
infer
::
normalize_associated_type
(
ccx
.tcx
(),
&
sig
);
debug!
(
"declare_rust_fn (after region erasure) sig={:?}"
,
sig
);
let
(
cconv
,
llfty
)
=
if
abi
==
Abi
::
Rust
||
abi
==
Abi
::
RustCall
{
(
llvm
::
CCallConv
,
type_of
::
type_of_rust_fn
(
ccx
,
env
,
&
sig
,
abi
))
let
(
cconv
,
llfty
)
=
if
f
.abi
==
Abi
::
Rust
||
f
.
abi
==
Abi
::
RustCall
{
(
llvm
::
CCallConv
,
type_of
::
type_of_rust_fn
(
ccx
,
&
sig
,
f
.
abi
))
}
else
{
let
fty
=
FnType
::
new
(
ccx
,
abi
,
&
sig
,
&
[]);
let
fty
=
FnType
::
new
(
ccx
,
f
.
abi
,
&
sig
,
&
[]);
(
fty
.cconv
,
fty
.to_llvm
(
ccx
))
};
...
...
@@ -137,10 +119,10 @@ pub fn declare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
llvm
::
SetFunctionAttribute
(
llfn
,
llvm
::
Attribute
::
NoReturn
);
}
if
abi
==
Abi
::
Rust
||
abi
==
Abi
::
RustCall
{
if
f
.abi
==
Abi
::
Rust
||
f
.
abi
==
Abi
::
RustCall
{
attributes
::
from_fn_type
(
ccx
,
fn_type
)
.apply_llfn
(
llfn
);
}
else
{
FnType
::
new
(
ccx
,
abi
,
&
sig
,
&
[])
.add_attributes
(
llfn
);
FnType
::
new
(
ccx
,
f
.
abi
,
&
sig
,
&
[])
.add_attributes
(
llfn
);
}
llfn
...
...
src/librustc_trans/trans/type_of.rs
浏览文件 @
3342da41
...
...
@@ -88,14 +88,11 @@ pub fn untuple_arguments<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
pub
fn
type_of_rust_fn
<
'a
,
'tcx
>
(
cx
:
&
CrateContext
<
'a
,
'tcx
>
,
maybe_env
:
Option
<
Ty
<
'tcx
>>
,
sig
:
&
ty
::
FnSig
<
'tcx
>
,
abi
:
Abi
)
->
Type
{
debug!
(
"type_of_rust_fn(sig={:?},abi={:?})"
,
sig
,
abi
);
debug!
(
"type_of_rust_fn(sig={:?}, abi={:?})"
,
sig
,
abi
);
assert
!
(
!
sig
.variadic
);
// rust fns are never variadic
...
...
@@ -129,11 +126,6 @@ pub fn type_of_rust_fn<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
ty
::
FnDiverging
=>
Type
::
void
(
cx
)
};
// Arg 1: Environment
if
let
Some
(
env_ty
)
=
maybe_env
{
atys
.push
(
type_of_explicit_arg
(
cx
,
env_ty
));
}
// ... then explicit args.
for
input
in
inputs
{
let
arg_ty
=
type_of_explicit_arg
(
cx
,
input
);
...
...
@@ -384,7 +376,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
let
sig
=
cx
.tcx
()
.erase_late_bound_regions
(
&
f
.sig
);
let
sig
=
infer
::
normalize_associated_type
(
cx
.tcx
(),
&
sig
);
if
f
.abi
==
Abi
::
Rust
||
f
.abi
==
Abi
::
RustCall
{
type_of_rust_fn
(
cx
,
None
,
&
sig
,
f
.abi
)
.ptr_to
()
type_of_rust_fn
(
cx
,
&
sig
,
f
.abi
)
.ptr_to
()
}
else
{
FnType
::
new
(
cx
,
f
.abi
,
&
sig
,
&
[])
.to_llvm
(
cx
)
.ptr_to
()
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录