Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
0af3775d
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,发现更多精彩内容 >>
提交
0af3775d
编写于
2月 07, 2017
作者:
A
Ariel Ben-Yehuda
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
translate tuple-variant constructors using MIR
上级
a559452b
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
215 addition
and
138 deletion
+215
-138
src/librustc/ty/mod.rs
src/librustc/ty/mod.rs
+10
-3
src/librustc_metadata/encoder.rs
src/librustc_metadata/encoder.rs
+2
-2
src/librustc_mir/lib.rs
src/librustc_mir/lib.rs
+2
-0
src/librustc_mir/mir_map.rs
src/librustc_mir/mir_map.rs
+63
-0
src/librustc_mir/shim.rs
src/librustc_mir/shim.rs
+109
-0
src/librustc_trans/base.rs
src/librustc_trans/base.rs
+4
-74
src/librustc_trans/callee.rs
src/librustc_trans/callee.rs
+0
-33
src/librustc_trans/collector.rs
src/librustc_trans/collector.rs
+5
-14
src/librustc_trans/common.rs
src/librustc_trans/common.rs
+8
-2
src/librustc_trans/mir/block.rs
src/librustc_trans/mir/block.rs
+1
-5
src/librustc_trans/trans_item.rs
src/librustc_trans/trans_item.rs
+11
-5
未找到文件。
src/librustc/ty/mod.rs
浏览文件 @
0af3775d
...
...
@@ -1264,10 +1264,17 @@ pub fn for_item(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: NodeId)
def_id
,
ROOT_CODE_EXTENT
)
}
_
=>
{
Some
(
hir_map
::
NodeStructCtor
(
..
))
|
Some
(
hir_map
::
NodeVariant
(
..
))
=>
{
let
def_id
=
tcx
.hir
.local_def_id
(
id
);
tcx
.construct_parameter_environment
(
tcx
.hir
.span
(
id
),
def_id
,
ROOT_CODE_EXTENT
)
}
it
=>
{
bug!
(
"ParameterEnvironment::from_item():
\
`{}`
is not an item
"
,
tcx
.hir
.node_to_string
(
id
))
`{}`
= {:?} is unsupported
"
,
tcx
.hir
.node_to_string
(
id
)
,
it
)
}
}
}
...
...
src/librustc_metadata/encoder.rs
浏览文件 @
0af3775d
...
...
@@ -293,7 +293,7 @@ fn encode_enum_variant_info(&mut self,
predicates
:
Some
(
self
.encode_predicates
(
def_id
)),
ast
:
None
,
mir
:
None
,
mir
:
self
.encode_mir
(
def_id
)
,
}
}
...
...
@@ -426,7 +426,7 @@ fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<
predicates
:
Some
(
self
.encode_predicates
(
def_id
)),
ast
:
None
,
mir
:
None
,
mir
:
self
.encode_mir
(
def_id
)
,
}
}
...
...
src/librustc_mir/lib.rs
浏览文件 @
0af3775d
...
...
@@ -22,6 +22,7 @@
#![feature(associated_consts)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(i128_type)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
...
...
@@ -50,6 +51,7 @@
pub
mod
def_use
;
pub
mod
graphviz
;
mod
hair
;
mod
shim
;
pub
mod
mir_map
;
pub
mod
pretty
;
pub
mod
transform
;
...
...
src/librustc_mir/mir_map.rs
浏览文件 @
0af3775d
...
...
@@ -22,6 +22,7 @@
use
rustc
::
mir
::
Mir
;
use
rustc
::
mir
::
transform
::
MirSource
;
use
rustc
::
mir
::
visit
::
MutVisitor
;
use
shim
;
use
pretty
;
use
hair
::
cx
::
Cx
;
...
...
@@ -30,6 +31,7 @@
use
rustc
::
ty
::
maps
::
Providers
;
use
rustc
::
ty
::
subst
::
Substs
;
use
rustc
::
hir
;
use
rustc
::
hir
::
intravisit
::{
self
,
Visitor
,
NestedVisitorMap
};
use
syntax
::
abi
::
Abi
;
use
syntax
::
ast
;
use
syntax_pos
::
Span
;
...
...
@@ -44,6 +46,31 @@ fn build_mir_for_crate_task<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, (): ()) {
tcx
.visit_all_bodies_in_krate
(|
body_owner_def_id
,
_
body_id
|
{
tcx
.item_mir
(
body_owner_def_id
);
});
// Tuple struct/variant constructors don't have a BodyId, so we need
// to build them separately.
struct
GatherCtors
<
'a
,
'tcx
:
'a
>
{
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
}
impl
<
'a
,
'tcx
>
Visitor
<
'tcx
>
for
GatherCtors
<
'a
,
'tcx
>
{
fn
visit_variant_data
(
&
mut
self
,
v
:
&
'tcx
hir
::
VariantData
,
_
:
ast
::
Name
,
_
:
&
'tcx
hir
::
Generics
,
_
:
ast
::
NodeId
,
_
:
Span
)
{
if
let
hir
::
VariantData
::
Tuple
(
_
,
node_id
)
=
*
v
{
self
.tcx
.item_mir
(
self
.tcx.hir
.local_def_id
(
node_id
));
}
intravisit
::
walk_struct_def
(
self
,
v
)
}
fn
nested_visit_map
<
'b
>
(
&
'b
mut
self
)
->
NestedVisitorMap
<
'b
,
'tcx
>
{
NestedVisitorMap
::
None
}
}
tcx
.visit_all_item_likes_in_krate
(
DepNode
::
Mir
,
&
mut
GatherCtors
{
tcx
:
tcx
}
.as_deep_visitor
());
}
}
...
...
@@ -95,6 +122,10 @@ fn build_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
_
=>
hir
::
BodyId
{
node_id
:
expr
.id
}
}
}
hir
::
map
::
NodeVariant
(
variant
)
=>
return
create_constructor_shim
(
tcx
,
id
,
&
variant
.node.data
),
hir
::
map
::
NodeStructCtor
(
ctor
)
=>
return
create_constructor_shim
(
tcx
,
id
,
ctor
),
_
=>
unsupported
()
};
...
...
@@ -180,6 +211,38 @@ fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>) {
}
}
fn
create_constructor_shim
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
ctor_id
:
ast
::
NodeId
,
v
:
&
'tcx
hir
::
VariantData
)
->
&
'tcx
RefCell
<
Mir
<
'tcx
>>
{
let
span
=
tcx
.hir
.span
(
ctor_id
);
if
let
hir
::
VariantData
::
Tuple
(
ref
fields
,
ctor_id
)
=
*
v
{
let
pe
=
ty
::
ParameterEnvironment
::
for_item
(
tcx
,
ctor_id
);
tcx
.infer_ctxt
(
pe
,
Reveal
::
UserFacing
)
.enter
(|
infcx
|
{
let
(
mut
mir
,
src
)
=
shim
::
build_adt_ctor
(
&
infcx
,
ctor_id
,
fields
,
span
);
// Convert the Mir to global types.
let
tcx
=
infcx
.tcx
.global_tcx
();
let
mut
globalizer
=
GlobalizeMir
{
tcx
:
tcx
,
span
:
mir
.span
};
globalizer
.visit_mir
(
&
mut
mir
);
let
mir
=
unsafe
{
mem
::
transmute
::
<
Mir
,
Mir
<
'tcx
>>
(
mir
)
};
pretty
::
dump_mir
(
tcx
,
"mir_map"
,
&
0
,
src
,
&
mir
);
tcx
.alloc_mir
(
mir
)
})
}
else
{
span_bug!
(
span
,
"attempting to create MIR for non-tuple variant {:?}"
,
v
);
}
}
///////////////////////////////////////////////////////////////////////////
// BuildMir -- walks a crate, looking for fn items and methods to build MIR from
...
...
src/librustc_mir/shim.rs
0 → 100644
浏览文件 @
0af3775d
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
rustc
::
hir
;
use
rustc
::
infer
;
use
rustc
::
mir
::
*
;
use
rustc
::
mir
::
transform
::
MirSource
;
use
rustc
::
ty
;
use
rustc_data_structures
::
indexed_vec
::{
IndexVec
,
Idx
};
use
syntax
::
ast
;
use
syntax_pos
::
Span
;
use
std
::
iter
;
fn
local_decls_for_sig
<
'tcx
>
(
sig
:
&
ty
::
FnSig
<
'tcx
>
)
->
IndexVec
<
Local
,
LocalDecl
<
'tcx
>>
{
iter
::
once
(
LocalDecl
{
mutability
:
Mutability
::
Mut
,
ty
:
sig
.output
(),
name
:
None
,
source_info
:
None
})
.chain
(
sig
.inputs
()
.iter
()
.map
(|
ity
|
LocalDecl
{
mutability
:
Mutability
::
Not
,
ty
:
*
ity
,
name
:
None
,
source_info
:
None
,
}))
.collect
()
}
pub
fn
build_adt_ctor
<
'a
,
'gcx
,
'tcx
>
(
infcx
:
&
infer
::
InferCtxt
<
'a
,
'gcx
,
'tcx
>
,
ctor_id
:
ast
::
NodeId
,
fields
:
&
[
hir
::
StructField
],
span
:
Span
)
->
(
Mir
<
'tcx
>
,
MirSource
)
{
let
tcx
=
infcx
.tcx
;
let
def_id
=
tcx
.hir
.local_def_id
(
ctor_id
);
let
sig
=
match
tcx
.item_type
(
def_id
)
.sty
{
ty
::
TyFnDef
(
_
,
_
,
fty
)
=>
tcx
.no_late_bound_regions
(
&
fty
)
.expect
(
"LBR in ADT constructor signature"
),
_
=>
bug!
(
"unexpected type for ctor {:?}"
,
def_id
)
};
let
sig
=
tcx
.erase_regions
(
&
sig
);
let
(
adt_def
,
substs
)
=
match
sig
.output
()
.sty
{
ty
::
TyAdt
(
adt_def
,
substs
)
=>
(
adt_def
,
substs
),
_
=>
bug!
(
"unexpected type for ADT ctor {:?}"
,
sig
.output
())
};
debug!
(
"build_ctor: def_id={:?} sig={:?} fields={:?}"
,
def_id
,
sig
,
fields
);
let
local_decls
=
local_decls_for_sig
(
&
sig
);
let
source_info
=
SourceInfo
{
span
:
span
,
scope
:
ARGUMENT_VISIBILITY_SCOPE
};
let
variant_no
=
if
adt_def
.is_enum
()
{
adt_def
.variant_index_with_id
(
def_id
)
}
else
{
0
};
// return = ADT(arg0, arg1, ...); return
let
start_block
=
BasicBlockData
{
statements
:
vec!
[
Statement
{
source_info
:
source_info
,
kind
:
StatementKind
::
Assign
(
Lvalue
::
Local
(
RETURN_POINTER
),
Rvalue
::
Aggregate
(
AggregateKind
::
Adt
(
adt_def
,
variant_no
,
substs
,
None
),
(
1
..
sig
.inputs
()
.len
()
+
1
)
.map
(|
i
|
{
Operand
::
Consume
(
Lvalue
::
Local
(
Local
::
new
(
i
)))
})
.collect
()
)
)
}],
terminator
:
Some
(
Terminator
{
source_info
:
source_info
,
kind
:
TerminatorKind
::
Return
,
}),
is_cleanup
:
false
};
let
mir
=
Mir
::
new
(
IndexVec
::
from_elem_n
(
start_block
,
1
),
IndexVec
::
from_elem_n
(
VisibilityScopeData
{
span
:
span
,
parent_scope
:
None
},
1
),
IndexVec
::
new
(),
sig
.output
(),
local_decls
,
sig
.inputs
()
.len
(),
vec!
[],
span
);
(
mir
,
MirSource
::
Fn
(
ctor_id
))
}
src/librustc_trans/base.rs
浏览文件 @
0af3775d
...
...
@@ -34,10 +34,8 @@
use
back
::
symbol_export
::{
self
,
ExportedSymbols
};
use
llvm
::{
Linkage
,
ValueRef
,
Vector
,
get_param
};
use
llvm
;
use
rustc
::
hir
::
def_id
::
{
DefId
,
LOCAL_CRATE
}
;
use
rustc
::
hir
::
def_id
::
LOCAL_CRATE
;
use
middle
::
lang_items
::
StartFnLangItem
;
use
rustc
::
ty
::
subst
::
Substs
;
use
rustc
::
mir
::
tcx
::
LvalueTy
;
use
rustc
::
traits
;
use
rustc
::
ty
::{
self
,
Ty
,
TyCtxt
};
use
rustc
::
ty
::
adjustment
::
CustomCoerceUnsized
;
...
...
@@ -47,9 +45,8 @@
use
session
::
config
::{
self
,
NoDebugInfo
};
use
rustc_incremental
::
IncrementalHashesMap
;
use
session
::{
self
,
DataTypeKind
,
Session
};
use
abi
::{
self
,
FnType
}
;
use
abi
;
use
mir
::
lvalue
::
LvalueRef
;
use
adt
;
use
attributes
;
use
builder
::
Builder
;
use
callee
::{
Callee
};
...
...
@@ -65,7 +62,7 @@
use
debuginfo
;
use
declare
;
use
machine
;
use
machine
::
{
llalign_of_min
,
llsize_of
}
;
use
machine
::
llsize_of
;
use
meth
;
use
mir
;
use
monomorphize
::{
self
,
Instance
};
...
...
@@ -76,7 +73,6 @@
use
type_
::
Type
;
use
type_of
;
use
value
::
Value
;
use
Disr
;
use
util
::
nodemap
::{
NodeSet
,
FxHashMap
,
FxHashSet
};
use
libc
::
c_uint
;
...
...
@@ -615,72 +611,6 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance
mir
::
trans_mir
(
ccx
,
lldecl
,
&
mir
,
instance
,
sig
);
}
pub
fn
trans_ctor_shim
<
'a
,
'tcx
>
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
def_id
:
DefId
,
substs
:
&
'tcx
Substs
<
'tcx
>
,
disr
:
Disr
,
llfn
:
ValueRef
)
{
attributes
::
inline
(
llfn
,
attributes
::
InlineAttr
::
Hint
);
attributes
::
set_frame_pointer_elimination
(
ccx
,
llfn
);
let
ctor_ty
=
common
::
def_ty
(
ccx
.shared
(),
def_id
,
substs
);
let
sig
=
ccx
.tcx
()
.erase_late_bound_regions_and_normalize
(
&
ctor_ty
.fn_sig
());
let
fn_ty
=
FnType
::
new
(
ccx
,
sig
,
&
[]);
let
bcx
=
Builder
::
new_block
(
ccx
,
llfn
,
"entry-block"
);
if
!
fn_ty
.ret
.is_ignore
()
{
// But if there are no nested returns, we skip the indirection
// and have a single retslot
let
dest
=
if
fn_ty
.ret
.is_indirect
()
{
get_param
(
llfn
,
0
)
}
else
{
// We create an alloca to hold a pointer of type `ret.original_ty`
// which will hold the pointer to the right alloca which has the
// final ret value
bcx
.alloca
(
fn_ty
.ret
.memory_ty
(
ccx
),
"sret_slot"
)
};
// Can return unsized value
let
mut
dest_val
=
LvalueRef
::
new_sized_ty
(
dest
,
sig
.output
(),
Alignment
::
AbiAligned
);
dest_val
.ty
=
LvalueTy
::
Downcast
{
adt_def
:
sig
.output
()
.ty_adt_def
()
.unwrap
(),
substs
:
substs
,
variant_index
:
disr
.0
as
usize
,
};
let
mut
llarg_idx
=
fn_ty
.ret
.is_indirect
()
as
usize
;
let
mut
arg_idx
=
0
;
for
(
i
,
arg_ty
)
in
sig
.inputs
()
.iter
()
.enumerate
()
{
let
(
lldestptr
,
_
)
=
dest_val
.trans_field_ptr
(
&
bcx
,
i
);
let
arg
=
&
fn_ty
.args
[
arg_idx
];
arg_idx
+=
1
;
if
common
::
type_is_fat_ptr
(
bcx
.ccx
,
arg_ty
)
{
let
meta
=
&
fn_ty
.args
[
arg_idx
];
arg_idx
+=
1
;
arg
.store_fn_arg
(
&
bcx
,
&
mut
llarg_idx
,
get_dataptr
(
&
bcx
,
lldestptr
));
meta
.store_fn_arg
(
&
bcx
,
&
mut
llarg_idx
,
get_meta
(
&
bcx
,
lldestptr
));
}
else
{
arg
.store_fn_arg
(
&
bcx
,
&
mut
llarg_idx
,
lldestptr
);
}
}
adt
::
trans_set_discr
(
&
bcx
,
sig
.output
(),
dest
,
disr
);
if
fn_ty
.ret
.is_indirect
()
{
bcx
.ret_void
();
return
;
}
if
let
Some
(
cast_ty
)
=
fn_ty
.ret.cast
{
bcx
.ret
(
bcx
.load
(
bcx
.pointercast
(
dest
,
cast_ty
.ptr_to
()),
Some
(
llalign_of_min
(
ccx
,
fn_ty
.ret.ty
))
));
}
else
{
bcx
.ret
(
bcx
.load
(
dest
,
None
))
}
}
else
{
bcx
.ret_void
();
}
}
pub
fn
llvm_linkage_by_name
(
name
:
&
str
)
->
Option
<
Linkage
>
{
// Use the names from src/llvm/docs/LangRef.rst here. Most types are only
// applicable to variable declarations and may not really make sense for
...
...
@@ -721,7 +651,7 @@ pub fn set_link_section(ccx: &CrateContext,
}
/// Create the `main` function which will initialise the rust runtime and call
/// users
’
main function.
/// users main function.
pub
fn
maybe_create_entry_wrapper
(
ccx
:
&
CrateContext
)
{
let
(
main_def_id
,
span
)
=
match
*
ccx
.sess
()
.entry_fn
.borrow
()
{
Some
((
id
,
span
))
=>
{
...
...
src/librustc_trans/callee.rs
浏览文件 @
0af3775d
...
...
@@ -22,7 +22,6 @@
use
rustc
::
traits
;
use
abi
::{
Abi
,
FnType
};
use
attributes
;
use
base
;
use
builder
::
Builder
;
use
common
::{
self
,
CrateContext
};
use
cleanup
::
CleanupScope
;
...
...
@@ -35,7 +34,6 @@
use
monomorphize
::
Instance
;
use
trans_item
::
TransItem
;
use
type_of
;
use
Disr
;
use
rustc
::
ty
::{
self
,
Ty
,
TypeFoldable
};
use
rustc
::
hir
;
use
std
::
iter
;
...
...
@@ -46,9 +44,6 @@
#[derive(Debug)]
pub
enum
CalleeData
{
/// Constructor for enum variant/tuple-like-struct.
NamedTupleConstructor
(
Disr
),
/// Function pointer.
Fn
(
ValueRef
),
...
...
@@ -92,16 +87,6 @@ pub fn def<'a>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId, substs: &'tcx Substs
}
}
// FIXME(eddyb) Detect ADT constructors more efficiently.
if
let
Some
(
adt_def
)
=
fn_ty
.fn_ret
()
.skip_binder
()
.ty_adt_def
()
{
if
let
Some
(
i
)
=
adt_def
.variants
.iter
()
.position
(|
v
|
def_id
==
v
.did
)
{
return
Callee
{
data
:
NamedTupleConstructor
(
Disr
::
for_variant
(
tcx
,
adt_def
,
i
)),
ty
:
fn_ty
};
}
}
let
(
llfn
,
ty
)
=
get_fn
(
ccx
,
def_id
,
substs
);
Callee
::
ptr
(
llfn
,
ty
)
}
...
...
@@ -185,24 +170,6 @@ pub fn reify<'a>(self, ccx: &CrateContext<'a, 'tcx>) -> ValueRef {
match
self
.data
{
Fn
(
llfn
)
=>
llfn
,
Virtual
(
_
)
=>
meth
::
trans_object_shim
(
ccx
,
self
),
NamedTupleConstructor
(
disr
)
=>
match
self
.ty.sty
{
ty
::
TyFnDef
(
def_id
,
substs
,
_
)
=>
{
let
instance
=
Instance
::
new
(
def_id
,
substs
);
if
let
Some
(
&
llfn
)
=
ccx
.instances
()
.borrow
()
.get
(
&
instance
)
{
return
llfn
;
}
let
sym
=
ccx
.symbol_map
()
.get_or_compute
(
ccx
.shared
(),
TransItem
::
Fn
(
instance
));
assert
!
(
!
ccx
.codegen_unit
()
.contains_item
(
&
TransItem
::
Fn
(
instance
)));
let
lldecl
=
declare
::
define_internal_fn
(
ccx
,
&
sym
,
self
.ty
);
base
::
trans_ctor_shim
(
ccx
,
def_id
,
substs
,
disr
,
lldecl
);
ccx
.instances
()
.borrow_mut
()
.insert
(
instance
,
lldecl
);
lldecl
}
_
=>
bug!
(
"expected fn item type, found {}"
,
self
.ty
)
},
Intrinsic
=>
bug!
(
"intrinsic {} getting reified"
,
self
.ty
)
}
}
...
...
src/librustc_trans/collector.rs
浏览文件 @
0af3775d
...
...
@@ -630,14 +630,15 @@ fn can_result_in_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
->
bool
{
match
tcx
.item_type
(
def_id
)
.sty
{
ty
::
TyFnDef
(
def_id
,
_
,
_
)
=>
{
// Some constructors also have type TyFnDef but they are
// always instantiated inline and don't result in a
// translation item. Same for FFI functions.
// foreign items are linked from another library, not
// translated locally.
if
let
Some
(
hir_map
::
NodeForeignItem
(
_
))
=
tcx
.hir
.get_if_local
(
def_id
)
{
return
false
;
}
}
ty
::
TyClosure
(
..
)
=>
{}
ty
::
TyClosure
(
..
)
=>
{
// TODO: trans items for closures
}
_
=>
return
false
}
...
...
@@ -697,16 +698,6 @@ fn is_drop_in_place_intrinsic<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
fn
should_trans_locally
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
def_id
:
DefId
)
->
bool
{
if
let
ty
::
TyFnDef
(
_
,
_
,
sig
)
=
tcx
.item_type
(
def_id
)
.sty
{
if
let
Some
(
adt_def
)
=
sig
.output
()
.skip_binder
()
.ty_adt_def
()
{
if
adt_def
.variants
.iter
()
.any
(|
v
|
def_id
==
v
.did
)
{
// HACK: ADT constructors are translated in-place and
// do not have a trans-item.
return
false
;
}
}
}
if
def_id
.is_local
()
{
true
}
else
{
...
...
src/librustc_trans/common.rs
浏览文件 @
0af3775d
...
...
@@ -37,6 +37,7 @@
use
std
::
iter
;
use
syntax
::
ast
;
use
syntax
::
attr
;
use
syntax
::
symbol
::
InternedString
;
use
syntax_pos
::
Span
;
...
...
@@ -601,8 +602,13 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
}
pub
fn
is_closure
(
tcx
:
TyCtxt
,
def_id
:
DefId
)
->
bool
{
tcx
.def_key
(
def_id
)
.disambiguated_data.data
==
DefPathData
::
ClosureExpr
pub
fn
requests_inline
(
tcx
:
TyCtxt
,
def_id
:
DefId
)
->
bool
{
match
tcx
.def_key
(
def_id
)
.disambiguated_data.data
{
DefPathData
::
StructCtor
|
DefPathData
::
EnumVariant
(
..
)
|
DefPathData
::
ClosureExpr
=>
true
,
_
=>
attr
::
requests_inline
(
&
tcx
.get_attrs
(
def_id
)[
..
]),
}
}
/// Given a DefId and some Substs, produces the monomorphic item type.
...
...
src/librustc_trans/mir/block.rs
浏览文件 @
0af3775d
...
...
@@ -16,7 +16,7 @@
use
rustc
::
mir
;
use
abi
::{
Abi
,
FnType
,
ArgType
};
use
base
::{
self
,
Lifetime
};
use
callee
::{
Callee
,
CalleeData
,
Fn
,
Intrinsic
,
NamedTupleConstructor
,
Virtual
};
use
callee
::{
Callee
,
CalleeData
,
Fn
,
Intrinsic
,
Virtual
};
use
builder
::
Builder
;
use
common
::{
self
,
Funclet
};
use
common
::{
C_bool
,
C_str_slice
,
C_struct
,
C_u32
,
C_undef
};
...
...
@@ -491,10 +491,6 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock,
}
let
fn_ptr
=
match
callee
.data
{
NamedTupleConstructor
(
_
)
=>
{
// FIXME translate this like mir::Rvalue::Aggregate.
callee
.reify
(
bcx
.ccx
)
}
Intrinsic
=>
{
use
intrinsic
::
trans_intrinsic_call
;
...
...
src/librustc_trans/trans_item.rs
浏览文件 @
0af3775d
...
...
@@ -26,6 +26,7 @@
use
rustc
::
dep_graph
::
DepNode
;
use
rustc
::
hir
;
use
rustc
::
hir
::
def_id
::
DefId
;
use
rustc
::
hir
::
map
::
definitions
::
DefPathData
;
use
rustc
::
ty
::{
self
,
Ty
,
TyCtxt
,
TypeFoldable
};
use
rustc
::
ty
::
subst
::
Substs
;
use
rustc_const_eval
::
fatal_const_eval_err
;
...
...
@@ -178,9 +179,14 @@ fn predefine_fn(ccx: &CrateContext<'a, 'tcx>,
llvm
::
SetUniqueComdat
(
ccx
.llmod
(),
lldecl
);
}
if
let
ty
::
TyClosure
(
..
)
=
mono_ty
.sty
{
// set an inline hint for all closures
attributes
::
inline
(
lldecl
,
attributes
::
InlineAttr
::
Hint
);
debug!
(
"predefine_fn: mono_ty = {:?} instance = {:?}"
,
mono_ty
,
instance
);
match
ccx
.tcx
()
.def_key
(
instance
.def
)
.disambiguated_data.data
{
DefPathData
::
StructCtor
|
DefPathData
::
EnumVariant
(
..
)
|
DefPathData
::
ClosureExpr
=>
{
attributes
::
inline
(
lldecl
,
attributes
::
InlineAttr
::
Hint
);
}
_
=>
{}
}
attributes
::
from_fn_attrs
(
ccx
,
&
attrs
,
lldecl
);
...
...
@@ -252,8 +258,8 @@ pub fn instantiation_mode(&self,
match
*
self
{
TransItem
::
Fn
(
ref
instance
)
=>
{
if
self
.explicit_linkage
(
tcx
)
.is_none
()
&&
(
common
::
is_closure
(
tcx
,
instance
.def
)
||
attr
::
requests_inline
(
&
tcx
.get_attrs
(
instance
.def
)[
..
]))
{
common
::
requests_inline
(
tcx
,
instance
.def
)
{
InstantiationMode
::
LocalCopy
}
else
{
InstantiationMode
::
GloballyShared
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录