Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
4f840a68
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,发现更多精彩内容 >>
提交
4f840a68
编写于
1月 30, 2018
作者:
W
Wesley Wiser
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add `inline` to `TransFnAttrs`
Part of #47320
上级
e8cd6cc2
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
149 addition
and
137 deletion
+149
-137
src/librustc/hir/mod.rs
src/librustc/hir/mod.rs
+11
-0
src/librustc/ich/impls_hir.rs
src/librustc/ich/impls_hir.rs
+11
-0
src/librustc/middle/reachable.rs
src/librustc/middle/reachable.rs
+12
-7
src/librustc/ty/instance.rs
src/librustc/ty/instance.rs
+2
-3
src/librustc_metadata/encoder.rs
src/librustc_metadata/encoder.rs
+2
-2
src/librustc_mir/monomorphize/item.rs
src/librustc_mir/monomorphize/item.rs
+1
-2
src/librustc_mir/transform/inline.rs
src/librustc_mir/transform/inline.rs
+1
-1
src/librustc_trans/attributes.rs
src/librustc_trans/attributes.rs
+3
-5
src/librustc_trans_utils/trans_crate.rs
src/librustc_trans_utils/trans_crate.rs
+1
-3
src/librustc_typeck/collect.rs
src/librustc_typeck/collect.rs
+35
-0
src/librustc_typeck/diagnostics.rs
src/librustc_typeck/diagnostics.rs
+69
-0
src/libsyntax/attr.rs
src/libsyntax/attr.rs
+1
-45
src/libsyntax/diagnostic_list.rs
src/libsyntax/diagnostic_list.rs
+0
-69
未找到文件。
src/librustc/hir/mod.rs
浏览文件 @
4f840a68
...
...
@@ -36,6 +36,7 @@
use
syntax
::
abi
::
Abi
;
use
syntax
::
ast
::{
self
,
Name
,
NodeId
,
DUMMY_NODE_ID
,
AsmDialect
};
use
syntax
::
ast
::{
Attribute
,
Lit
,
StrStyle
,
FloatTy
,
IntTy
,
UintTy
,
MetaItem
};
use
syntax
::
attr
::
InlineAttr
;
use
syntax
::
ext
::
hygiene
::
SyntaxContext
;
use
syntax
::
ptr
::
P
;
use
syntax
::
symbol
::{
Symbol
,
keywords
};
...
...
@@ -2214,6 +2215,7 @@ pub fn provide(providers: &mut Providers) {
#[derive(Clone,
RustcEncodable,
RustcDecodable,
Hash)]
pub
struct
TransFnAttrs
{
pub
flags
:
TransFnAttrFlags
,
pub
inline
:
InlineAttr
,
}
bitflags!
{
...
...
@@ -2231,6 +2233,15 @@ impl TransFnAttrs {
pub
fn
new
()
->
TransFnAttrs
{
TransFnAttrs
{
flags
:
TransFnAttrFlags
::
empty
(),
inline
:
InlineAttr
::
None
,
}
}
/// True if `#[inline]` or `#[inline(always)]` is present.
pub
fn
requests_inline
(
&
self
)
->
bool
{
match
self
.inline
{
InlineAttr
::
Hint
|
InlineAttr
::
Always
=>
true
,
InlineAttr
::
None
|
InlineAttr
::
Never
=>
false
,
}
}
}
...
...
src/librustc/ich/impls_hir.rs
浏览文件 @
4f840a68
...
...
@@ -19,6 +19,7 @@
StableHasher
,
StableHasherResult
};
use
std
::
mem
;
use
syntax
::
ast
;
use
syntax
::
attr
;
impl
<
'gcx
>
HashStable
<
StableHashingContext
<
'gcx
>>
for
DefId
{
#[inline]
...
...
@@ -1145,9 +1146,11 @@ fn hash_stable<W: StableHasherResult>(&self,
hasher
:
&
mut
StableHasher
<
W
>
)
{
let
hir
::
TransFnAttrs
{
flags
,
inline
,
}
=
*
self
;
flags
.hash_stable
(
hcx
,
hasher
);
inline
.hash_stable
(
hcx
,
hasher
);
}
}
...
...
@@ -1160,6 +1163,14 @@ fn hash_stable<W: StableHasherResult>(&self,
}
}
impl
<
'hir
>
HashStable
<
StableHashingContext
<
'hir
>>
for
attr
::
InlineAttr
{
fn
hash_stable
<
W
:
StableHasherResult
>
(
&
self
,
hcx
:
&
mut
StableHashingContext
<
'hir
>
,
hasher
:
&
mut
StableHasher
<
W
>
)
{
mem
::
discriminant
(
self
)
.hash_stable
(
hcx
,
hasher
);
}
}
impl_stable_hash_for!
(
struct
hir
::
Freevar
{
def
,
span
...
...
src/librustc/middle/reachable.rs
浏览文件 @
4f840a68
...
...
@@ -15,6 +15,7 @@
// makes all other generics or inline functions that it references
// reachable as well.
use
hir
::
TransFnAttrs
;
use
hir
::
map
as
hir_map
;
use
hir
::
def
::
Def
;
use
hir
::
def_id
::{
DefId
,
CrateNum
};
...
...
@@ -43,8 +44,8 @@ fn generics_require_inlining(generics: &hir::Generics) -> bool {
// Returns true if the given item must be inlined because it may be
// monomorphized or it was marked with `#[inline]`. This will only return
// true for functions.
fn
item_might_be_inlined
(
item
:
&
hir
::
Item
)
->
bool
{
if
attr
::
requests_inline
(
&
item
.attrs
)
{
fn
item_might_be_inlined
(
item
:
&
hir
::
Item
,
attrs
:
TransFnAttrs
)
->
bool
{
if
attr
s
.requests_inline
(
)
{
return
true
}
...
...
@@ -60,14 +61,15 @@ fn item_might_be_inlined(item: &hir::Item) -> bool {
fn
method_might_be_inlined
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
impl_item
:
&
hir
::
ImplItem
,
impl_src
:
DefId
)
->
bool
{
if
attr
::
requests_inline
(
&
impl_item
.attrs
)
||
let
trans_fn_attrs
=
tcx
.trans_fn_attrs
(
impl_item
.hir_id
.owner_def_id
());
if
trans_fn_attrs
.requests_inline
()
||
generics_require_inlining
(
&
impl_item
.generics
)
{
return
true
}
if
let
Some
(
impl_node_id
)
=
tcx
.hir
.as_local_node_id
(
impl_src
)
{
match
tcx
.hir
.find
(
impl_node_id
)
{
Some
(
hir_map
::
NodeItem
(
item
))
=>
item_might_be_inlined
(
&
item
),
item_might_be_inlined
(
&
item
,
trans_fn_attrs
),
Some
(
..
)
|
None
=>
span_bug!
(
impl_item
.span
,
"impl did is not an item"
)
}
...
...
@@ -160,7 +162,8 @@ fn def_id_represents_local_inlined_item(&self, def_id: DefId) -> bool {
match
self
.tcx.hir
.find
(
node_id
)
{
Some
(
hir_map
::
NodeItem
(
item
))
=>
{
match
item
.node
{
hir
::
ItemFn
(
..
)
=>
item_might_be_inlined
(
&
item
),
hir
::
ItemFn
(
..
)
=>
item_might_be_inlined
(
&
item
,
self
.tcx
.trans_fn_attrs
(
def_id
)),
_
=>
false
,
}
}
...
...
@@ -176,8 +179,9 @@ fn def_id_represents_local_inlined_item(&self, def_id: DefId) -> bool {
match
impl_item
.node
{
hir
::
ImplItemKind
::
Const
(
..
)
=>
true
,
hir
::
ImplItemKind
::
Method
(
..
)
=>
{
let
attrs
=
self
.tcx
.trans_fn_attrs
(
def_id
);
if
generics_require_inlining
(
&
impl_item
.generics
)
||
attr
::
requests_inline
(
&
impl_item
.attrs
)
{
attr
s
.requests_inline
(
)
{
true
}
else
{
let
impl_did
=
self
.tcx
...
...
@@ -246,7 +250,8 @@ fn propagate_node(&mut self, node: &hir_map::Node<'tcx>,
hir_map
::
NodeItem
(
item
)
=>
{
match
item
.node
{
hir
::
ItemFn
(
..
,
body
)
=>
{
if
item_might_be_inlined
(
&
item
)
{
let
def_id
=
self
.tcx.hir
.local_def_id
(
item
.id
);
if
item_might_be_inlined
(
&
item
,
self
.tcx
.trans_fn_attrs
(
def_id
))
{
self
.visit_nested_body
(
body
);
}
}
...
...
src/librustc/ty/instance.rs
浏览文件 @
4f840a68
...
...
@@ -96,7 +96,6 @@ pub fn requires_local<'a>(
&
self
,
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
)
->
bool
{
use
syntax
::
attr
::
requests_inline
;
if
self
.is_inline
(
tcx
)
{
return
true
}
...
...
@@ -106,8 +105,8 @@ pub fn requires_local<'a>(
// available to normal end-users.
return
true
}
requests_inline
(
&
self
.attrs
(
tcx
)[
..
])
||
tcx
.is_const_fn
(
self
.def_id
())
let
trans_fn_attrs
=
tcx
.trans_fn_attrs
(
self
.def_id
());
trans_fn_attrs
.requests_inline
()
||
tcx
.is_const_fn
(
self
.def_id
())
}
}
...
...
src/librustc_metadata/encoder.rs
浏览文件 @
4f840a68
...
...
@@ -832,7 +832,7 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
}
else
if
let
hir
::
ImplItemKind
::
Method
(
ref
sig
,
body
)
=
ast_item
.node
{
let
generics
=
self
.tcx
.generics_of
(
def_id
);
let
types
=
generics
.parent_types
as
usize
+
generics
.types
.len
();
let
needs_inline
=
types
>
0
||
attr
::
requests_inline
(
&
ast_item
.attrs
);
let
needs_inline
=
types
>
0
||
tcx
.trans_fn_attrs
(
def_id
)
.requests_inline
(
);
let
is_const_fn
=
sig
.constness
==
hir
::
Constness
::
Const
;
let
ast
=
if
is_const_fn
{
Some
(
body
)
}
else
{
None
};
let
always_encode_mir
=
self
.tcx.sess.opts.debugging_opts.always_encode_mir
;
...
...
@@ -1123,7 +1123,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
hir
::
ItemConst
(
..
)
=>
self
.encode_optimized_mir
(
def_id
),
hir
::
ItemFn
(
_
,
_
,
constness
,
_
,
ref
generics
,
_
)
=>
{
let
has_tps
=
generics
.ty_params
()
.next
()
.is_some
();
let
needs_inline
=
has_tps
||
attr
::
requests_inline
(
&
item
.attrs
);
let
needs_inline
=
has_tps
||
tcx
.trans_fn_attrs
(
def_id
)
.requests_inline
(
);
let
always_encode_mir
=
self
.tcx.sess.opts.debugging_opts.always_encode_mir
;
if
needs_inline
||
constness
==
hir
::
Constness
::
Const
||
always_encode_mir
{
self
.encode_optimized_mir
(
def_id
)
...
...
src/librustc_mir/monomorphize/item.rs
浏览文件 @
4f840a68
...
...
@@ -141,8 +141,7 @@ fn instantiation_mode(&self,
// creating one copy of this `#[inline]` function which may
// conflict with upstream crates as it could be an exported
// symbol.
let
attrs
=
instance
.def
.attrs
(
tcx
);
match
attr
::
find_inline_attr
(
Some
(
tcx
.sess
.diagnostic
()),
&
attrs
)
{
match
tcx
.trans_fn_attrs
(
instance
.def_id
())
.inline
{
InlineAttr
::
Always
=>
InstantiationMode
::
LocalCopy
,
_
=>
{
InstantiationMode
::
GloballyShared
{
may_conflict
:
true
}
...
...
src/librustc_mir/transform/inline.rs
浏览文件 @
4f840a68
...
...
@@ -207,7 +207,7 @@ fn should_inline(&self,
}
let
attrs
=
tcx
.get_attrs
(
callsite
.callee
);
let
hint
=
attr
::
find_inline_attr
(
None
,
&
attrs
[
..
])
;
let
hint
=
tcx
.trans_fn_attrs
(
callsite
.callee
)
.inline
;
let
hinted
=
match
hint
{
// Just treat inline(always) as a hint for now,
...
...
src/librustc_trans/attributes.rs
浏览文件 @
4f840a68
...
...
@@ -103,15 +103,13 @@ pub fn set_probestack(cx: &CodegenCx, llfn: ValueRef) {
/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
/// attributes.
pub
fn
from_fn_attrs
(
cx
:
&
CodegenCx
,
llfn
:
ValueRef
,
id
:
DefId
)
{
use
syntax
::
attr
::
*
;
let
attrs
=
cx
.tcx
.get_attrs
(
id
);
inline
(
llfn
,
find_inline_attr
(
Some
(
cx
.sess
()
.diagnostic
()),
&
attrs
)
);
let
trans_fn_attrs
=
cx
.tcx
.trans_fn_attrs
(
id
)
;
inline
(
llfn
,
trans_fn_attrs
.inline
);
set_frame_pointer_elimination
(
cx
,
llfn
);
set_probestack
(
cx
,
llfn
);
let
trans_fn_attrs
=
cx
.tcx
.trans_fn_attrs
(
id
);
if
trans_fn_attrs
.flags
.contains
(
TransFnAttrFlags
::
COLD
)
{
Attribute
::
Cold
.apply_llfn
(
Function
,
llfn
);
}
...
...
src/librustc_trans_utils/trans_crate.rs
浏览文件 @
4f840a68
...
...
@@ -236,9 +236,7 @@ fn trans_crate<'a, 'tcx>(
let
_
=
tcx
.export_name
(
def_id
);
let
_
=
tcx
.contains_extern_indicator
(
def_id
);
let
_
=
inst
.def
.is_inline
(
tcx
);
let
attrs
=
inst
.def
.attrs
(
tcx
);
let
_
=
::
syntax
::
attr
::
find_inline_attr
(
Some
(
tcx
.sess
.diagnostic
()),
&
attrs
);
let
_
=
tcx
.trans_fn_attrs
(
def_id
);
}
}
_
=>
{}
...
...
src/librustc_typeck/collect.rs
浏览文件 @
4f840a68
...
...
@@ -41,6 +41,8 @@
use
rustc_const_math
::
ConstInt
;
use
syntax
::{
abi
,
ast
};
use
syntax
::
ast
::
MetaItemKind
;
use
syntax
::
attr
::{
InlineAttr
,
list_contains_name
,
mark_used
};
use
syntax
::
codemap
::
Spanned
;
use
syntax
::
symbol
::{
Symbol
,
keywords
};
use
syntax_pos
::{
Span
,
DUMMY_SP
};
...
...
@@ -1742,6 +1744,39 @@ fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAt
}
else
if
attr
.check_name
(
"naked"
)
{
trans_fn_attrs
.flags
|
=
TransFnAttrFlags
::
NAKED
;
}
else
if
attr
.check_name
(
"inline"
)
{
trans_fn_attrs
.inline
=
attrs
.iter
()
.fold
(
InlineAttr
::
None
,
|
ia
,
attr
|
{
if
attr
.path
!=
"inline"
{
return
ia
;
}
let
meta
=
match
attr
.meta
()
{
Some
(
meta
)
=>
meta
.node
,
None
=>
return
ia
,
};
match
meta
{
MetaItemKind
::
Word
=>
{
mark_used
(
attr
);
InlineAttr
::
Hint
}
MetaItemKind
::
List
(
ref
items
)
=>
{
mark_used
(
attr
);
if
items
.len
()
!=
1
{
span_err!
(
tcx
.sess
.diagnostic
(),
attr
.span
,
E0534
,
"expected one argument"
);
InlineAttr
::
None
}
else
if
list_contains_name
(
&
items
[
..
],
"always"
)
{
InlineAttr
::
Always
}
else
if
list_contains_name
(
&
items
[
..
],
"never"
)
{
InlineAttr
::
Never
}
else
{
span_err!
(
tcx
.sess
.diagnostic
(),
items
[
0
]
.span
,
E0535
,
"invalid argument"
);
InlineAttr
::
None
}
}
_
=>
ia
,
}
});
}
}
...
...
src/librustc_typeck/diagnostics.rs
浏览文件 @
4f840a68
...
...
@@ -3705,6 +3705,75 @@ fn fly(&self) {} // And now that's ok!
```
"##
,
E0534
:
r##"
The `inline` attribute was malformed.
Erroneous code example:
```ignore (compile_fail not working here; see Issue #43707)
#[inline()] // error: expected one argument
pub fn something() {}
fn main() {}
```
The parenthesized `inline` attribute requires the parameter to be specified:
```
#[inline(always)]
fn something() {}
```
or:
```
#[inline(never)]
fn something() {}
```
Alternatively, a paren-less version of the attribute may be used to hint the
compiler about inlining opportunity:
```
#[inline]
fn something() {}
```
For more information about the inline attribute, read:
https://doc.rust-lang.org/reference.html#inline-attributes
"##
,
E0535
:
r##"
An unknown argument was given to the `inline` attribute.
Erroneous code example:
```ignore (compile_fail not working here; see Issue #43707)
#[inline(unknown)] // error: invalid argument
pub fn something() {}
fn main() {}
```
The `inline` attribute only supports two arguments:
* always
* never
All other arguments given to the `inline` attribute will return this error.
Example:
```
#[inline(never)] // ok!
pub fn something() {}
fn main() {}
```
For more information about the inline attribute, https:
read://doc.rust-lang.org/reference.html#inline-attributes
"##
,
E0559
:
r##"
An unknown field was specified into an enum's structure variant.
...
...
src/libsyntax/attr.rs
浏览文件 @
4f840a68
...
...
@@ -520,7 +520,7 @@ pub fn find_crate_name(attrs: &[Attribute]) -> Option<Symbol> {
first_attr_value_str_by_name
(
attrs
,
"crate_name"
)
}
#[derive(Copy,
Clone,
PartialEq
)]
#[derive(Copy,
Clone,
Hash,
PartialEq,
RustcEncodable,
RustcDecodable
)]
pub
enum
InlineAttr
{
None
,
Hint
,
...
...
@@ -528,43 +528,6 @@ pub enum InlineAttr {
Never
,
}
/// Determine what `#[inline]` attribute is present in `attrs`, if any.
pub
fn
find_inline_attr
(
diagnostic
:
Option
<&
Handler
>
,
attrs
:
&
[
Attribute
])
->
InlineAttr
{
attrs
.iter
()
.fold
(
InlineAttr
::
None
,
|
ia
,
attr
|
{
if
attr
.path
!=
"inline"
{
return
ia
;
}
let
meta
=
match
attr
.meta
()
{
Some
(
meta
)
=>
meta
.node
,
None
=>
return
ia
,
};
match
meta
{
MetaItemKind
::
Word
=>
{
mark_used
(
attr
);
InlineAttr
::
Hint
}
MetaItemKind
::
List
(
ref
items
)
=>
{
mark_used
(
attr
);
if
items
.len
()
!=
1
{
diagnostic
.map
(|
d
|{
span_err!
(
d
,
attr
.span
,
E0534
,
"expected one argument"
);
});
InlineAttr
::
None
}
else
if
list_contains_name
(
&
items
[
..
],
"always"
)
{
InlineAttr
::
Always
}
else
if
list_contains_name
(
&
items
[
..
],
"never"
)
{
InlineAttr
::
Never
}
else
{
diagnostic
.map
(|
d
|
{
span_err!
(
d
,
items
[
0
]
.span
,
E0535
,
"invalid argument"
);
});
InlineAttr
::
None
}
}
_
=>
ia
,
}
})
}
#[derive(Copy,
Clone,
PartialEq)]
pub
enum
UnwindAttr
{
Allowed
,
...
...
@@ -610,13 +573,6 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op
})
}
/// True if `#[inline]` or `#[inline(always)]` is present in `attrs`.
pub
fn
requests_inline
(
attrs
:
&
[
Attribute
])
->
bool
{
match
find_inline_attr
(
None
,
attrs
)
{
InlineAttr
::
Hint
|
InlineAttr
::
Always
=>
true
,
InlineAttr
::
None
|
InlineAttr
::
Never
=>
false
,
}
}
/// Tests if a cfg-pattern matches the cfg set
pub
fn
cfg_matches
(
cfg
:
&
ast
::
MetaItem
,
sess
:
&
ParseSess
,
features
:
Option
<&
Features
>
)
->
bool
{
...
...
src/libsyntax/diagnostic_list.rs
浏览文件 @
4f840a68
...
...
@@ -37,75 +37,6 @@ struct Bar<'a> {
[RFC 438]: https://github.com/rust-lang/rfcs/pull/438
"##
,
E0534
:
r##"
The `inline` attribute was malformed.
Erroneous code example:
```ignore (compile_fail not working here; see Issue #43707)
#[inline()] // error: expected one argument
pub fn something() {}
fn main() {}
```
The parenthesized `inline` attribute requires the parameter to be specified:
```
#[inline(always)]
fn something() {}
```
or:
```
#[inline(never)]
fn something() {}
```
Alternatively, a paren-less version of the attribute may be used to hint the
compiler about inlining opportunity:
```
#[inline]
fn something() {}
```
For more information about the inline attribute, read:
https://doc.rust-lang.org/reference.html#inline-attributes
"##
,
E0535
:
r##"
An unknown argument was given to the `inline` attribute.
Erroneous code example:
```ignore (compile_fail not working here; see Issue #43707)
#[inline(unknown)] // error: invalid argument
pub fn something() {}
fn main() {}
```
The `inline` attribute only supports two arguments:
* always
* never
All other arguments given to the `inline` attribute will return this error.
Example:
```
#[inline(never)] // ok!
pub fn something() {}
fn main() {}
```
For more information about the inline attribute, https:
read://doc.rust-lang.org/reference.html#inline-attributes
"##
,
E0536
:
r##"
The `not` cfg-predicate was malformed.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录