Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
2edb6438
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
2edb6438
编写于
4月 29, 2015
作者:
A
Alex Crichton
浏览文件
操作
浏览文件
下载
差异文件
rollup merge of #24921: tamird/bitflags-associated-const
Conflicts: src/librustc/lib.rs
上级
cc04cd4b
8c58fe17
变更
24
隐藏空白更改
内联
并排
Showing
24 changed file
with
341 addition
and
295 deletion
+341
-295
src/librustc/lib.rs
src/librustc/lib.rs
+5
-4
src/librustc/middle/check_const.rs
src/librustc/middle/check_const.rs
+48
-46
src/librustc/middle/mem_categorization.rs
src/librustc/middle/mem_categorization.rs
+4
-4
src/librustc/middle/ty.rs
src/librustc/middle/ty.rs
+32
-30
src/librustc_bitflags/lib.rs
src/librustc_bitflags/lib.rs
+67
-65
src/librustc_llvm/lib.rs
src/librustc_llvm/lib.rs
+24
-23
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/build_reduced_graph.rs
+28
-15
src/librustc_resolve/lib.rs
src/librustc_resolve/lib.rs
+17
-8
src/librustc_resolve/resolve_imports.rs
src/librustc_resolve/resolve_imports.rs
+5
-3
src/librustc_trans/trans/attributes.rs
src/librustc_trans/trans/attributes.rs
+35
-26
src/librustc_trans/trans/cabi_aarch64.rs
src/librustc_trans/trans/cabi_aarch64.rs
+4
-5
src/librustc_trans/trans/cabi_arm.rs
src/librustc_trans/trans/cabi_arm.rs
+4
-5
src/librustc_trans/trans/cabi_mips.rs
src/librustc_trans/trans/cabi_mips.rs
+4
-5
src/librustc_trans/trans/cabi_powerpc.rs
src/librustc_trans/trans/cabi_powerpc.rs
+4
-5
src/librustc_trans/trans/cabi_x86.rs
src/librustc_trans/trans/cabi_x86.rs
+4
-4
src/librustc_trans/trans/cabi_x86_64.rs
src/librustc_trans/trans/cabi_x86_64.rs
+3
-4
src/librustc_trans/trans/cabi_x86_win64.rs
src/librustc_trans/trans/cabi_x86_win64.rs
+4
-4
src/librustc_trans/trans/consts.rs
src/librustc_trans/trans/consts.rs
+2
-2
src/librustc_trans/trans/declare.rs
src/librustc_trans/trans/declare.rs
+2
-2
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/expr.rs
+11
-5
src/librustc_trans/trans/foreign.rs
src/librustc_trans/trans/foreign.rs
+2
-2
src/libstd/lib.rs
src/libstd/lib.rs
+10
-10
src/libsyntax/lib.rs
src/libsyntax/lib.rs
+2
-1
src/libsyntax/parse/parser.rs
src/libsyntax/parse/parser.rs
+20
-17
未找到文件。
src/librustc/lib.rs
浏览文件 @
2edb6438
...
...
@@ -25,22 +25,23 @@
html_favicon_url
=
"http://www.rust-lang.org/favicon.ico"
,
html_root_url
=
"http://doc.rust-lang.org/nightly/"
)]
#![feature(associated_consts)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(fs_canonicalize)]
#![feature(hash)]
#![feature(into_cow)]
#![feature(libc)]
#![feature(path_ext)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(path_ext)]
#![feature(str_char)]
#![feature(into_cow)]
#![feature(fs_canonicalize)]
#![feature(slice_patterns)]
#![cfg_attr(test,
feature(test))]
#![allow(trivial_casts)]
...
...
src/librustc/middle/check_const.rs
浏览文件 @
2edb6438
...
...
@@ -46,33 +46,35 @@
#[derive(RustcEncodable,
RustcDecodable)]
flags
ConstQualif
:
u8
{
// Const rvalue which can be placed behind a reference.
const
PURE_CONST
=
0b00000
0
,
const
PURE_CONST
=
0
,
// Inner mutability (can not be placed behind a reference) or behind
// &mut in a non-global expression. Can be copied from static memory.
const
MUTABLE_MEM
=
0b000001
,
const
MUTABLE_MEM
=
1
<<
0
,
// Constant value with a type that implements Drop. Can be copied
// from static memory, similar to MUTABLE_MEM.
const
NEEDS_DROP
=
0b000010
,
const
NEEDS_DROP
=
1
<<
1
,
// Even if the value can be placed in static memory, copying it from
// there is more expensive than in-place instantiation, and/or it may
// be too large. This applies to [T; N] and everything containing it.
// N.B.: references need to clear this flag to not end up on the stack.
const
PREFER_IN_PLACE
=
0b000100
,
const
PREFER_IN_PLACE
=
1
<<
2
,
// May use more than 0 bytes of memory, doesn't impact the constness
// directly, but is not allowed to be borrowed mutably in a constant.
const
NON_ZERO_SIZED
=
0b001000
,
const
NON_ZERO_SIZED
=
1
<<
3
,
// Actually borrowed, has to always be in static memory. Does not
// propagate, and requires the expression to behave like a 'static
// lvalue. The set of expressions with this flag is the minimum
// that have to be promoted.
const
HAS_STATIC_BORROWS
=
0b010000
,
const
HAS_STATIC_BORROWS
=
1
<<
4
,
// Invalid const for miscellaneous reasons (e.g. not implemented).
const
NOT_CONST
=
0b100000
,
const
NOT_CONST
=
1
<<
5
,
// Borrowing the expression won't produce &'static T if any of these
// bits are set, though the value could be copied from static memory
// if `NOT_CONST` isn't set.
const
NON_STATIC_BORROWS
=
MUTABLE_MEM
.bits
|
NEEDS_DROP
.bits
|
NOT_CONST
.bits
const
NON_STATIC_BORROWS
=
ConstQualif
::
MUTABLE_MEM
.bits
|
ConstQualif
::
NEEDS_DROP
.bits
|
ConstQualif
::
NOT_CONST
.bits
}
}
...
...
@@ -102,7 +104,7 @@ fn with_mode<F, R>(&mut self, mode: Mode, f: F) -> R where
{
let
(
old_mode
,
old_qualif
)
=
(
self
.mode
,
self
.qualif
);
self
.mode
=
mode
;
self
.qualif
=
PURE_CONST
;
self
.qualif
=
ConstQualif
::
PURE_CONST
;
let
r
=
f
(
self
);
self
.mode
=
old_mode
;
self
.qualif
=
old_qualif
;
...
...
@@ -126,7 +128,7 @@ fn global_expr(&mut self, mode: Mode, expr: &ast::Expr) -> ConstQualif {
Entry
::
Occupied
(
entry
)
=>
return
*
entry
.get
(),
Entry
::
Vacant
(
entry
)
=>
{
// Prevent infinite recursion on re-entry.
entry
.insert
(
PURE_CONST
);
entry
.insert
(
ConstQualif
::
PURE_CONST
);
}
}
self
.with_mode
(
mode
,
|
this
|
{
...
...
@@ -271,7 +273,7 @@ fn visit_pat(&mut self, p: &ast::Pat) {
fn
visit_expr
(
&
mut
self
,
ex
:
&
ast
::
Expr
)
{
let
mut
outer
=
self
.qualif
;
self
.qualif
=
PURE_CONST
;
self
.qualif
=
ConstQualif
::
PURE_CONST
;
let
node_ty
=
ty
::
node_id_to_type
(
self
.tcx
,
ex
.id
);
check_expr
(
self
,
ex
,
node_ty
);
...
...
@@ -287,7 +289,7 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
self
.visit_expr
(
&**
callee
);
// The callee's size doesn't count in the call.
let
added
=
self
.qualif
-
inner
;
self
.qualif
=
inner
|
(
added
-
NON_ZERO_SIZED
);
self
.qualif
=
inner
|
(
added
-
ConstQualif
::
NON_ZERO_SIZED
);
}
ast
::
ExprRepeat
(
ref
element
,
_
)
=>
{
self
.visit_expr
(
&**
element
);
...
...
@@ -298,7 +300,7 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
};
// [element; 0] is always zero-sized.
if
count
==
0
{
self
.qualif
=
self
.qualif
-
(
NON_ZERO_SIZED
|
PREFER_IN_PLACE
);
self
.qualif
.remove
(
ConstQualif
::
NON_ZERO_SIZED
|
ConstQualif
::
PREFER_IN_PLACE
);
}
}
ast
::
ExprMatch
(
ref
discr
,
ref
arms
,
_
)
=>
{
...
...
@@ -325,7 +327,7 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
let
div_or_rem
=
op
.node
==
ast
::
BiDiv
||
op
.node
==
ast
::
BiRem
;
match
node_ty
.sty
{
ty
::
ty_uint
(
_
)
|
ty
::
ty_int
(
_
)
if
div_or_rem
=>
{
if
!
self
.qualif
.intersects
(
NOT_CONST
)
{
if
!
self
.qualif
.intersects
(
ConstQualif
::
NOT_CONST
)
{
match
const_eval
::
eval_const_expr_partial
(
self
.tcx
,
ex
,
None
)
{
Ok
(
_
)
=>
{}
Err
(
msg
)
=>
{
...
...
@@ -348,11 +350,11 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
// Constants cannot be borrowed if they contain interior mutability as
// it means that our "silent insertion of statics" could change
// initializer values (very bad).
// If the type doesn't have interior mutability, then `MUTABLE_MEM` has
// If the type doesn't have interior mutability, then `
ConstQualif::
MUTABLE_MEM` has
// propagated from another error, so erroring again would be just noise.
let
tc
=
ty
::
type_contents
(
self
.tcx
,
node_ty
);
if
self
.qualif
.intersects
(
MUTABLE_MEM
)
&&
tc
.interior_unsafe
()
{
outer
=
outer
|
NOT_CONST
;
if
self
.qualif
.intersects
(
ConstQualif
::
MUTABLE_MEM
)
&&
tc
.interior_unsafe
()
{
outer
=
outer
|
ConstQualif
::
NOT_CONST
;
if
self
.mode
!=
Mode
::
Var
{
self
.tcx.sess
.span_err
(
ex
.span
,
"cannot borrow a constant which contains
\
...
...
@@ -361,32 +363,32 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
}
// If the reference has to be 'static, avoid in-place initialization
// as that will end up pointing to the stack instead.
if
!
self
.qualif
.intersects
(
NON_STATIC_BORROWS
)
{
self
.qualif
=
self
.qualif
-
PREFER_IN_PLACE
;
self
.add_qualif
(
HAS_STATIC_BORROWS
);
if
!
self
.qualif
.intersects
(
ConstQualif
::
NON_STATIC_BORROWS
)
{
self
.qualif
=
self
.qualif
-
ConstQualif
::
PREFER_IN_PLACE
;
self
.add_qualif
(
ConstQualif
::
HAS_STATIC_BORROWS
);
}
}
Some
(
ast
::
MutMutable
)
=>
{
// `&mut expr` means expr could be mutated, unless it's zero-sized.
if
self
.qualif
.intersects
(
NON_ZERO_SIZED
)
{
if
self
.qualif
.intersects
(
ConstQualif
::
NON_ZERO_SIZED
)
{
if
self
.mode
==
Mode
::
Var
{
outer
=
outer
|
NOT_CONST
;
self
.add_qualif
(
MUTABLE_MEM
);
outer
=
outer
|
ConstQualif
::
NOT_CONST
;
self
.add_qualif
(
ConstQualif
::
MUTABLE_MEM
);
}
else
{
span_err!
(
self
.tcx.sess
,
ex
.span
,
E0017
,
"references in {}s may only refer
\
to immutable values"
,
self
.msg
())
}
}
if
!
self
.qualif
.intersects
(
NON_STATIC_BORROWS
)
{
self
.add_qualif
(
HAS_STATIC_BORROWS
);
if
!
self
.qualif
.intersects
(
ConstQualif
::
NON_STATIC_BORROWS
)
{
self
.add_qualif
(
ConstQualif
::
HAS_STATIC_BORROWS
);
}
}
None
=>
{}
}
self
.tcx.const_qualif_map
.borrow_mut
()
.insert
(
ex
.id
,
self
.qualif
);
// Don't propagate certain flags.
self
.qualif
=
outer
|
(
self
.qualif
-
HAS_STATIC_BORROWS
);
self
.qualif
=
outer
|
(
self
.qualif
-
ConstQualif
::
HAS_STATIC_BORROWS
);
}
}
...
...
@@ -401,7 +403,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
match
node_ty
.sty
{
ty
::
ty_struct
(
did
,
_
)
|
ty
::
ty_enum
(
did
,
_
)
if
ty
::
has_dtor
(
v
.tcx
,
did
)
=>
{
v
.add_qualif
(
NEEDS_DROP
);
v
.add_qualif
(
ConstQualif
::
NEEDS_DROP
);
if
v
.mode
!=
Mode
::
Var
{
v
.tcx.sess
.span_err
(
e
.span
,
&
format!
(
"{}s are not allowed to have destructors"
,
...
...
@@ -416,7 +418,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
ast
::
ExprUnary
(
..
)
|
ast
::
ExprBinary
(
..
)
|
ast
::
ExprIndex
(
..
)
if
v
.tcx.method_map
.borrow
()
.contains_key
(
&
method_call
)
=>
{
v
.add_qualif
(
NOT_CONST
);
v
.add_qualif
(
ConstQualif
::
NOT_CONST
);
if
v
.mode
!=
Mode
::
Var
{
span_err!
(
v
.tcx.sess
,
e
.span
,
E0011
,
"user-defined operators are not allowed in {}s"
,
v
.msg
());
...
...
@@ -424,7 +426,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
}
ast
::
ExprBox
(
..
)
|
ast
::
ExprUnary
(
ast
::
UnUniq
,
_
)
=>
{
v
.add_qualif
(
NOT_CONST
);
v
.add_qualif
(
ConstQualif
::
NOT_CONST
);
if
v
.mode
!=
Mode
::
Var
{
span_err!
(
v
.tcx.sess
,
e
.span
,
E0010
,
"allocations are not allowed in {}s"
,
v
.msg
());
...
...
@@ -434,7 +436,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
match
ty
::
node_id_to_type
(
v
.tcx
,
ptr
.id
)
.sty
{
ty
::
ty_ptr
(
_
)
=>
{
// This shouldn't be allowed in constants at all.
v
.add_qualif
(
NOT_CONST
);
v
.add_qualif
(
ConstQualif
::
NOT_CONST
);
}
_
=>
{}
}
...
...
@@ -447,7 +449,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
ty
::
type_is_unsafe_ptr
(
toty
)
||
(
ty
::
type_is_bare_fn
(
toty
)
&&
ty
::
type_is_bare_fn_item
(
fromty
));
if
!
is_legal_cast
{
v
.add_qualif
(
NOT_CONST
);
v
.add_qualif
(
ConstQualif
::
NOT_CONST
);
if
v
.mode
!=
Mode
::
Var
{
span_err!
(
v
.tcx.sess
,
e
.span
,
E0012
,
"can not cast to `{}` in {}s"
,
...
...
@@ -455,7 +457,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
}
}
if
ty
::
type_is_unsafe_ptr
(
fromty
)
&&
ty
::
type_is_numeric
(
toty
)
{
v
.add_qualif
(
NOT_CONST
);
v
.add_qualif
(
ConstQualif
::
NOT_CONST
);
if
v
.mode
!=
Mode
::
Var
{
span_err!
(
v
.tcx.sess
,
e
.span
,
E0018
,
"can not cast a pointer to an integer in {}s"
,
v
.msg
());
...
...
@@ -467,17 +469,17 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
match
def
{
Some
(
def
::
DefVariant
(
_
,
_
,
_
))
=>
{
// Count the discriminator or function pointer.
v
.add_qualif
(
NON_ZERO_SIZED
);
v
.add_qualif
(
ConstQualif
::
NON_ZERO_SIZED
);
}
Some
(
def
::
DefStruct
(
_
))
=>
{
if
let
ty
::
ty_bare_fn
(
..
)
=
node_ty
.sty
{
// Count the function pointer.
v
.add_qualif
(
NON_ZERO_SIZED
);
v
.add_qualif
(
ConstQualif
::
NON_ZERO_SIZED
);
}
}
Some
(
def
::
DefFn
(
..
))
|
Some
(
def
::
DefMethod
(
..
))
=>
{
// Count the function pointer.
v
.add_qualif
(
NON_ZERO_SIZED
);
v
.add_qualif
(
ConstQualif
::
NON_ZERO_SIZED
);
}
Some
(
def
::
DefStatic
(
..
))
=>
{
match
v
.mode
{
...
...
@@ -487,7 +489,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
"constants cannot refer to other statics,
\
insert an intermediate constant instead"
);
}
Mode
::
Var
=>
v
.add_qualif
(
NOT_CONST
)
Mode
::
Var
=>
v
.add_qualif
(
ConstQualif
::
NOT_CONST
)
}
}
Some
(
def
::
DefConst
(
did
))
|
...
...
@@ -503,7 +505,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
}
}
def
=>
{
v
.add_qualif
(
NOT_CONST
);
v
.add_qualif
(
ConstQualif
::
NOT_CONST
);
if
v
.mode
!=
Mode
::
Var
{
debug!
(
"(checking const) found bad def: {:?}"
,
def
);
span_err!
(
v
.tcx.sess
,
e
.span
,
E0014
,
...
...
@@ -530,10 +532,10 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
Some
(
def
::
DefStruct
(
..
))
=>
{}
Some
(
def
::
DefVariant
(
..
))
=>
{
// Count the discriminator.
v
.add_qualif
(
NON_ZERO_SIZED
);
v
.add_qualif
(
ConstQualif
::
NON_ZERO_SIZED
);
}
_
=>
{
v
.add_qualif
(
NOT_CONST
);
v
.add_qualif
(
ConstQualif
::
NOT_CONST
);
if
v
.mode
!=
Mode
::
Var
{
span_err!
(
v
.tcx.sess
,
e
.span
,
E0015
,
"function calls in {}s are limited to
\
...
...
@@ -545,7 +547,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
ast
::
ExprBlock
(
ref
block
)
=>
{
// Check all statements in the block
let
mut
block_span_err
=
|
span
|
{
v
.add_qualif
(
NOT_CONST
);
v
.add_qualif
(
ConstQualif
::
NOT_CONST
);
if
v
.mode
!=
Mode
::
Var
{
span_err!
(
v
.tcx.sess
,
span
,
E0016
,
"blocks in {}s are limited to items and
\
...
...
@@ -574,17 +576,17 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
ast
::
ExprStruct
(
..
)
=>
{
let
did
=
v
.tcx.def_map
.borrow
()
.get
(
&
e
.id
)
.map
(|
def
|
def
.def_id
());
if
did
==
v
.tcx.lang_items
.unsafe_cell_type
()
{
v
.add_qualif
(
MUTABLE_MEM
);
v
.add_qualif
(
ConstQualif
::
MUTABLE_MEM
);
}
}
ast
::
ExprLit
(
_
)
|
ast
::
ExprAddrOf
(
..
)
=>
{
v
.add_qualif
(
NON_ZERO_SIZED
);
v
.add_qualif
(
ConstQualif
::
NON_ZERO_SIZED
);
}
ast
::
ExprRepeat
(
..
)
=>
{
v
.add_qualif
(
PREFER_IN_PLACE
);
v
.add_qualif
(
ConstQualif
::
PREFER_IN_PLACE
);
}
ast
::
ExprClosure
(
..
)
=>
{
...
...
@@ -593,7 +595,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
if
ty
::
with_freevars
(
v
.tcx
,
e
.id
,
|
fv
|
!
fv
.is_empty
())
{
assert
!
(
v
.mode
==
Mode
::
Var
,
"global closures can't capture anything"
);
v
.add_qualif
(
NOT_CONST
);
v
.add_qualif
(
ConstQualif
::
NOT_CONST
);
}
}
...
...
@@ -631,7 +633,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
ast
::
ExprAssignOp
(
..
)
|
ast
::
ExprInlineAsm
(
_
)
|
ast
::
ExprMac
(
_
)
=>
{
v
.add_qualif
(
NOT_CONST
);
v
.add_qualif
(
ConstQualif
::
NOT_CONST
);
if
v
.mode
!=
Mode
::
Var
{
span_err!
(
v
.tcx.sess
,
e
.span
,
E0019
,
"{} contains unimplemented expression type"
,
v
.msg
());
...
...
@@ -644,7 +646,7 @@ pub fn check_crate(tcx: &ty::ctxt) {
visit
::
walk_crate
(
&
mut
CheckCrateVisitor
{
tcx
:
tcx
,
mode
:
Mode
::
Var
,
qualif
:
NOT_CONST
,
qualif
:
ConstQualif
::
NOT_CONST
,
rvalue_borrows
:
NodeMap
()
},
tcx
.map
.krate
());
...
...
src/librustc/middle/mem_categorization.rs
浏览文件 @
2edb6438
...
...
@@ -838,20 +838,20 @@ pub fn cat_rvalue_node(&self,
expr_ty
:
Ty
<
'tcx
>
)
->
cmt
<
'tcx
>
{
let
qualif
=
self
.tcx
()
.const_qualif_map
.borrow
()
.get
(
&
id
)
.cloned
()
.unwrap_or
(
check_const
::
NOT_CONST
);
.unwrap_or
(
check_const
::
ConstQualif
::
NOT_CONST
);
// Only promote `[T; 0]` before an RFC for rvalue promotions
// is accepted.
let
qualif
=
match
expr_ty
.sty
{
ty
::
ty_vec
(
_
,
Some
(
0
))
=>
qualif
,
_
=>
check_const
::
NOT_CONST
_
=>
check_const
::
ConstQualif
::
NOT_CONST
};
// Compute maximum lifetime of this rvalue. This is 'static if
// we can promote to a constant, otherwise equal to enclosing temp
// lifetime.
let
re
=
match
qualif
&
check_const
::
NON_STATIC_BORROWS
{
check_const
::
PURE_CONST
=>
ty
::
ReStatic
,
let
re
=
match
qualif
&
check_const
::
ConstQualif
::
NON_STATIC_BORROWS
{
check_const
::
ConstQualif
::
PURE_CONST
=>
ty
::
ReStatic
,
_
=>
self
.temporary_scope
(
id
),
};
let
ret
=
self
.cat_rvalue
(
id
,
span
,
re
,
expr_ty
);
...
...
src/librustc/middle/ty.rs
浏览文件 @
2edb6438
...
...
@@ -848,16 +848,18 @@ pub fn free_region_map(&self, id: NodeId) -> FreeRegionMap {
// recursing over the type itself.
bitflags!
{
flags
TypeFlags
:
u32
{
const
NO_TYPE_FLAGS
=
0b0
,
const
HAS_PARAMS
=
0b1
,
const
HAS_SELF
=
0b10
,
const
HAS_TY_INFER
=
0b100
,
const
HAS_RE_INFER
=
0b1000
,
const
HAS_RE_LATE_BOUND
=
0b10000
,
const
HAS_REGIONS
=
0b100000
,
const
HAS_TY_ERR
=
0b1000000
,
const
HAS_PROJECTION
=
0b10000000
,
const
NEEDS_SUBST
=
HAS_PARAMS
.bits
|
HAS_SELF
.bits
|
HAS_REGIONS
.bits
,
const
NO_TYPE_FLAGS
=
0
,
const
HAS_PARAMS
=
1
<<
0
,
const
HAS_SELF
=
1
<<
1
,
const
HAS_TY_INFER
=
1
<<
2
,
const
HAS_RE_INFER
=
1
<<
3
,
const
HAS_RE_LATE_BOUND
=
1
<<
4
,
const
HAS_REGIONS
=
1
<<
5
,
const
HAS_TY_ERR
=
1
<<
6
,
const
HAS_PROJECTION
=
1
<<
7
,
const
NEEDS_SUBST
=
TypeFlags
::
HAS_PARAMS
.bits
|
TypeFlags
::
HAS_SELF
.bits
|
TypeFlags
::
HAS_REGIONS
.bits
,
}
}
...
...
@@ -890,8 +892,8 @@ pub fn go(tcx: &ty::ctxt) {
ty
::
ty_err
=>
/* unimportant */
continue
,
$
(
ty
::
$variant
(
..
)
=>
&
mut
$variant
,)
*
};
let
region
=
t
.flags
.intersects
(
ty
::
HAS_RE_INFER
);
let
ty
=
t
.flags
.intersects
(
ty
::
HAS_TY_INFER
);
let
region
=
t
.flags
.intersects
(
ty
::
TypeFlags
::
HAS_RE_INFER
);
let
ty
=
t
.flags
.intersects
(
ty
::
TypeFlags
::
HAS_TY_INFER
);
variant
.total
+=
1
;
total
.total
+=
1
;
...
...
@@ -993,23 +995,23 @@ fn borrow<'a>(&'a self) -> &'a sty<'tcx> {
}
pub
fn
type_has_params
(
ty
:
Ty
)
->
bool
{
ty
.flags
.intersects
(
HAS_PARAMS
)
ty
.flags
.intersects
(
TypeFlags
::
HAS_PARAMS
)
}
pub
fn
type_has_self
(
ty
:
Ty
)
->
bool
{
ty
.flags
.intersects
(
HAS_SELF
)
ty
.flags
.intersects
(
TypeFlags
::
HAS_SELF
)
}
pub
fn
type_has_ty_infer
(
ty
:
Ty
)
->
bool
{
ty
.flags
.intersects
(
HAS_TY_INFER
)
ty
.flags
.intersects
(
TypeFlags
::
HAS_TY_INFER
)
}
pub
fn
type_needs_infer
(
ty
:
Ty
)
->
bool
{
ty
.flags
.intersects
(
HAS_TY_INFER
|
HAS_RE_INFER
)
ty
.flags
.intersects
(
TypeFlags
::
HAS_TY_INFER
|
TypeFlags
::
HAS_RE_INFER
)
}
pub
fn
type_has_projection
(
ty
:
Ty
)
->
bool
{
ty
.flags
.intersects
(
HAS_PROJECTION
)
ty
.flags
.intersects
(
TypeFlags
::
HAS_PROJECTION
)
}
pub
fn
type_has_late_bound_regions
(
ty
:
Ty
)
->
bool
{
ty
.flags
.intersects
(
HAS_RE_LATE_BOUND
)
ty
.flags
.intersects
(
TypeFlags
::
HAS_RE_LATE_BOUND
)
}
/// An "escaping region" is a bound region whose binder is not part of `t`.
...
...
@@ -2810,7 +2812,7 @@ struct FlagComputation {
impl
FlagComputation
{
fn
new
()
->
FlagComputation
{
FlagComputation
{
flags
:
NO_TYPE_FLAGS
,
depth
:
0
}
FlagComputation
{
flags
:
TypeFlags
::
NO_TYPE_FLAGS
,
depth
:
0
}
}
fn
for_sty
(
st
:
&
sty
)
->
FlagComputation
{
...
...
@@ -2855,20 +2857,20 @@ fn add_sty(&mut self, st: &sty) {
// You might think that we could just return ty_err for
// any type containing ty_err as a component, and get
// rid of the HAS_TY_ERR flag -- likewise for ty_bot (with
// rid of the
TypeFlags::
HAS_TY_ERR flag -- likewise for ty_bot (with
// the exception of function types that return bot).
// But doing so caused sporadic memory corruption, and
// neither I (tjc) nor nmatsakis could figure out why,
// so we're doing it this way.
&
ty_err
=>
{
self
.add_flags
(
HAS_TY_ERR
)
self
.add_flags
(
TypeFlags
::
HAS_TY_ERR
)
}
&
ty_param
(
ref
p
)
=>
{
if
p
.space
==
subst
::
SelfSpace
{
self
.add_flags
(
HAS_SELF
);
self
.add_flags
(
TypeFlags
::
HAS_SELF
);
}
else
{
self
.add_flags
(
HAS_PARAMS
);
self
.add_flags
(
TypeFlags
::
HAS_PARAMS
);
}
}
...
...
@@ -2877,7 +2879,7 @@ fn add_sty(&mut self, st: &sty) {
}
&
ty_infer
(
_
)
=>
{
self
.add_flags
(
HAS_TY_INFER
)
self
.add_flags
(
TypeFlags
::
HAS_TY_INFER
)
}
&
ty_enum
(
_
,
substs
)
|
&
ty_struct
(
_
,
substs
)
=>
{
...
...
@@ -2885,7 +2887,7 @@ fn add_sty(&mut self, st: &sty) {
}
&
ty_projection
(
ref
data
)
=>
{
self
.add_flags
(
HAS_PROJECTION
);
self
.add_flags
(
TypeFlags
::
HAS_PROJECTION
);
self
.add_projection_ty
(
data
);
}
...
...
@@ -2949,11 +2951,11 @@ fn add_fn_sig(&mut self, fn_sig: &PolyFnSig) {
}
fn
add_region
(
&
mut
self
,
r
:
Region
)
{
self
.add_flags
(
HAS_REGIONS
);
self
.add_flags
(
TypeFlags
::
HAS_REGIONS
);
match
r
{
ty
::
ReInfer
(
_
)
=>
{
self
.add_flags
(
HAS_RE_INFER
);
}
ty
::
ReInfer
(
_
)
=>
{
self
.add_flags
(
TypeFlags
::
HAS_RE_INFER
);
}
ty
::
ReLateBound
(
debruijn
,
_
)
=>
{
self
.add_flags
(
HAS_RE_LATE_BOUND
);
self
.add_flags
(
TypeFlags
::
HAS_RE_LATE_BOUND
);
self
.add_depth
(
debruijn
.depth
);
}
_
=>
{
}
...
...
@@ -3307,11 +3309,11 @@ pub fn type_is_nil(ty: Ty) -> bool {
}
pub
fn
type_is_error
(
ty
:
Ty
)
->
bool
{
ty
.flags
.intersects
(
HAS_TY_ERR
)
ty
.flags
.intersects
(
TypeFlags
::
HAS_TY_ERR
)
}
pub
fn
type_needs_subst
(
ty
:
Ty
)
->
bool
{
ty
.flags
.intersects
(
NEEDS_SUBST
)
ty
.flags
.intersects
(
TypeFlags
::
NEEDS_SUBST
)
}
pub
fn
trait_ref_contains_error
(
tref
:
&
ty
::
TraitRef
)
->
bool
{
...
...
src/librustc_bitflags/lib.rs
浏览文件 @
2edb6438
...
...
@@ -12,6 +12,7 @@
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0,
feature(custom_attribute))]
#![crate_name
=
"rustc_bitflags"
]
#![feature(associated_consts)]
#![feature(staged_api)]
#![staged_api]
#![crate_type
=
"rlib"
]
...
...
@@ -34,6 +35,7 @@
///
/// ```{.rust}
/// # #![feature(rustc_private)]
/// # #![feature(associated_consts)]
/// #[macro_use] extern crate rustc_bitflags;
///
/// bitflags! {
...
...
@@ -41,19 +43,19 @@
/// const FLAG_A = 0b00000001,
/// const FLAG_B = 0b00000010,
/// const FLAG_C = 0b00000100,
/// const FLAG_ABC = FLAG_A.bits
/// | FLAG_B.bits
/// | FLAG_C.bits,
/// const FLAG_ABC = F
lags::F
LAG_A.bits
/// | F
lags::F
LAG_B.bits
/// | F
lags::F
LAG_C.bits,
/// }
/// }
///
/// fn main() {
/// let e1 = F
LAG_A |
FLAG_C;
/// let e2 = F
LAG_B |
FLAG_C;
/// assert!((e1 | e2) == F
LAG_ABC);
// union
/// assert!((e1 & e2) == F
LAG_C);
// intersection
/// assert!((e1 - e2) == F
LAG_A);
// set difference
/// assert!(!e2 == F
LAG_A);
// set complement
/// let e1 = F
lags::FLAG_A | Flags::
FLAG_C;
/// let e2 = F
lags::FLAG_B | Flags::
FLAG_C;
/// assert!((e1 | e2) == F
lags::FLAG_ABC);
// union
/// assert!((e1 & e2) == F
lags::FLAG_C);
// intersection
/// assert!((e1 - e2) == F
lags::FLAG_A);
// set difference
/// assert!(!e2 == F
lags::FLAG_A);
// set complement
/// }
/// ```
///
...
...
@@ -86,7 +88,7 @@
/// }
///
/// fn main() {
/// let mut flags = F
LAG_A |
FLAG_B;
/// let mut flags = F
lags::FLAG_A | Flags::
FLAG_B;
/// flags.clear();
/// assert!(flags.is_empty());
/// assert_eq!(format!("{:?}", flags), "hi!");
...
...
@@ -144,9 +146,9 @@ pub struct $BitFlags {
bits
:
$T
,
}
$
(
$
(
#[
$
Flag_attr]
)
*
pub
const
$Flag
:
$BitFlags
=
$BitFlags
{
bits
:
$value
};)
+
impl
$BitFlags
{
$
(
$
(
#[
$
Flag_attr]
)
*
pub
const
$Flag
:
$BitFlags
=
$BitFlags
{
bits
:
$value
};)
+
/// Returns an empty set of flags.
#[inline]
pub
fn
empty
()
->
$BitFlags
{
...
...
@@ -314,9 +316,9 @@ mod tests {
#[doc
=
"* cmr bed"
]
#[doc
=
"* strcat table"
]
#[doc
=
"<strcat> wait what?"
]
const
FlagABC
=
FlagA
.bits
|
FlagB
.bits
|
FlagC
.bits
,
const
FlagABC
=
Flag
s
::
Flag
A
.bits
|
Flag
s
::
Flag
B
.bits
|
Flag
s
::
Flag
C
.bits
,
}
}
...
...
@@ -329,32 +331,32 @@ mod tests {
#[test]
fn
test_bits
(){
assert_eq!
(
Flags
::
empty
()
.bits
(),
0b00000000
);
assert_eq!
(
FlagA
.bits
(),
0b00000001
);
assert_eq!
(
FlagABC
.bits
(),
0b00000111
);
assert_eq!
(
Flag
s
::
Flag
A
.bits
(),
0b00000001
);
assert_eq!
(
Flag
s
::
Flag
ABC
.bits
(),
0b00000111
);
assert_eq!
(
AnotherSetOfFlags
::
empty
()
.bits
(),
0b00
);
assert_eq!
(
AnotherFlag
.bits
(),
!
0
);
assert_eq!
(
Another
SetOfFlags
::
Another
Flag
.bits
(),
!
0
);
}
#[test]
fn
test_from_bits
()
{
assert
!
(
Flags
::
from_bits
(
0
)
==
Some
(
Flags
::
empty
()));
assert
!
(
Flags
::
from_bits
(
0b1
)
==
Some
(
FlagA
));
assert
!
(
Flags
::
from_bits
(
0b10
)
==
Some
(
FlagB
));
assert
!
(
Flags
::
from_bits
(
0b11
)
==
Some
(
Flag
A
|
FlagB
));
assert
!
(
Flags
::
from_bits
(
0b1
)
==
Some
(
Flag
s
::
Flag
A
));
assert
!
(
Flags
::
from_bits
(
0b10
)
==
Some
(
Flag
s
::
Flag
B
));
assert
!
(
Flags
::
from_bits
(
0b11
)
==
Some
(
Flag
s
::
FlagA
|
Flags
::
FlagB
));
assert
!
(
Flags
::
from_bits
(
0b1000
)
==
None
);
assert
!
(
AnotherSetOfFlags
::
from_bits
(
!
0
)
==
Some
(
AnotherFlag
));
assert
!
(
AnotherSetOfFlags
::
from_bits
(
!
0
)
==
Some
(
Another
SetOfFlags
::
Another
Flag
));
}
#[test]
fn
test_from_bits_truncate
()
{
assert
!
(
Flags
::
from_bits_truncate
(
0
)
==
Flags
::
empty
());
assert
!
(
Flags
::
from_bits_truncate
(
0b1
)
==
FlagA
);
assert
!
(
Flags
::
from_bits_truncate
(
0b10
)
==
FlagB
);
assert
!
(
Flags
::
from_bits_truncate
(
0b11
)
==
(
Flag
A
|
FlagB
));
assert
!
(
Flags
::
from_bits_truncate
(
0b1
)
==
Flag
s
::
Flag
A
);
assert
!
(
Flags
::
from_bits_truncate
(
0b10
)
==
Flag
s
::
Flag
B
);
assert
!
(
Flags
::
from_bits_truncate
(
0b11
)
==
(
Flag
s
::
FlagA
|
Flags
::
FlagB
));
assert
!
(
Flags
::
from_bits_truncate
(
0b1000
)
==
Flags
::
empty
());
assert
!
(
Flags
::
from_bits_truncate
(
0b1001
)
==
FlagA
);
assert
!
(
Flags
::
from_bits_truncate
(
0b1001
)
==
Flag
s
::
Flag
A
);
assert
!
(
AnotherSetOfFlags
::
from_bits_truncate
(
0
)
==
AnotherSetOfFlags
::
empty
());
}
...
...
@@ -362,19 +364,19 @@ fn test_from_bits_truncate() {
#[test]
fn
test_is_empty
(){
assert
!
(
Flags
::
empty
()
.is_empty
());
assert
!
(
!
FlagA
.is_empty
());
assert
!
(
!
FlagABC
.is_empty
());
assert
!
(
!
Flag
s
::
Flag
A
.is_empty
());
assert
!
(
!
Flag
s
::
Flag
ABC
.is_empty
());
assert
!
(
!
AnotherFlag
.is_empty
());
assert
!
(
!
Another
SetOfFlags
::
Another
Flag
.is_empty
());
}
#[test]
fn
test_is_all
()
{
assert
!
(
Flags
::
all
()
.is_all
());
assert
!
(
!
FlagA
.is_all
());
assert
!
(
FlagABC
.is_all
());
assert
!
(
!
Flag
s
::
Flag
A
.is_all
());
assert
!
(
Flag
s
::
Flag
ABC
.is_all
());
assert
!
(
AnotherFlag
.is_all
());
assert
!
(
Another
SetOfFlags
::
Another
Flag
.is_all
());
}
#[test]
...
...
@@ -383,77 +385,77 @@ fn test_two_empties_do_not_intersect() {
let
e2
=
Flags
::
empty
();
assert
!
(
!
e1
.intersects
(
e2
));
assert
!
(
Another
Flag
.intersects
(
AnotherFlag
));
assert
!
(
Another
SetOfFlags
::
AnotherFlag
.intersects
(
AnotherSetOfFlags
::
AnotherFlag
));
}
#[test]
fn
test_empty_does_not_intersect_with_full
()
{
let
e1
=
Flags
::
empty
();
let
e2
=
FlagABC
;
let
e2
=
Flag
s
::
Flag
ABC
;
assert
!
(
!
e1
.intersects
(
e2
));
}
#[test]
fn
test_disjoint_intersects
()
{
let
e1
=
FlagA
;
let
e2
=
FlagB
;
let
e1
=
Flag
s
::
Flag
A
;
let
e2
=
Flag
s
::
Flag
B
;
assert
!
(
!
e1
.intersects
(
e2
));
}
#[test]
fn
test_overlapping_intersects
()
{
let
e1
=
FlagA
;
let
e2
=
Flag
A
|
FlagB
;
let
e1
=
Flag
s
::
Flag
A
;
let
e2
=
Flag
s
::
FlagA
|
Flags
::
FlagB
;
assert
!
(
e1
.intersects
(
e2
));
}
#[test]
fn
test_contains
()
{
let
e1
=
FlagA
;
let
e2
=
Flag
A
|
FlagB
;
let
e1
=
Flag
s
::
Flag
A
;
let
e2
=
Flag
s
::
FlagA
|
Flags
::
FlagB
;
assert
!
(
!
e1
.contains
(
e2
));
assert
!
(
e2
.contains
(
e1
));
assert
!
(
FlagABC
.contains
(
e2
));
assert
!
(
Flag
s
::
Flag
ABC
.contains
(
e2
));
assert
!
(
Another
Flag
.contains
(
AnotherFlag
));
assert
!
(
Another
SetOfFlags
::
AnotherFlag
.contains
(
AnotherSetOfFlags
::
AnotherFlag
));
}
#[test]
fn
test_insert
(){
let
mut
e1
=
FlagA
;
let
e2
=
Flag
A
|
FlagB
;
let
mut
e1
=
Flag
s
::
Flag
A
;
let
e2
=
Flag
s
::
FlagA
|
Flags
::
FlagB
;
e1
.insert
(
e2
);
assert
!
(
e1
==
e2
);
let
mut
e3
=
AnotherSetOfFlags
::
empty
();
e3
.insert
(
AnotherFlag
);
assert
!
(
e3
==
AnotherFlag
);
e3
.insert
(
Another
SetOfFlags
::
Another
Flag
);
assert
!
(
e3
==
Another
SetOfFlags
::
Another
Flag
);
}
#[test]
fn
test_remove
(){
let
mut
e1
=
Flag
A
|
FlagB
;
let
e2
=
Flag
A
|
FlagC
;
let
mut
e1
=
Flag
s
::
FlagA
|
Flags
::
FlagB
;
let
e2
=
Flag
s
::
FlagA
|
Flags
::
FlagC
;
e1
.remove
(
e2
);
assert
!
(
e1
==
FlagB
);
assert
!
(
e1
==
Flag
s
::
Flag
B
);
let
mut
e3
=
AnotherFlag
;
e3
.remove
(
AnotherFlag
);
let
mut
e3
=
Another
SetOfFlags
::
Another
Flag
;
e3
.remove
(
Another
SetOfFlags
::
Another
Flag
);
assert
!
(
e3
==
AnotherSetOfFlags
::
empty
());
}
#[test]
fn
test_operators
()
{
let
e1
=
Flag
A
|
FlagC
;
let
e2
=
Flag
B
|
FlagC
;
assert
!
((
e1
|
e2
)
==
FlagABC
);
// union
assert
!
((
e1
&
e2
)
==
FlagC
);
// intersection
assert
!
((
e1
-
e2
)
==
FlagA
);
// set difference
assert
!
(
!
e2
==
FlagA
);
// set complement
assert
!
(
e1
^
e2
==
Flag
A
|
FlagB
);
// toggle
let
e1
=
Flag
s
::
FlagA
|
Flags
::
FlagC
;
let
e2
=
Flag
s
::
FlagB
|
Flags
::
FlagC
;
assert
!
((
e1
|
e2
)
==
Flag
s
::
Flag
ABC
);
// union
assert
!
((
e1
&
e2
)
==
Flag
s
::
Flag
C
);
// intersection
assert
!
((
e1
-
e2
)
==
Flag
s
::
Flag
A
);
// set difference
assert
!
(
!
e2
==
Flag
s
::
Flag
A
);
// set complement
assert
!
(
e1
^
e2
==
Flag
s
::
FlagA
|
Flags
::
FlagB
);
// toggle
let
mut
e3
=
e1
;
e3
.toggle
(
e2
);
assert
!
(
e3
==
Flag
A
|
FlagB
);
assert
!
(
e3
==
Flag
s
::
FlagA
|
Flags
::
FlagB
);
let
mut
m4
=
AnotherSetOfFlags
::
empty
();
m4
.toggle
(
AnotherSetOfFlags
::
empty
());
...
...
@@ -466,11 +468,11 @@ fn test_lt() {
let
mut
b
=
Flags
::
empty
();
assert
!
(
!
(
a
<
b
)
&&
!
(
b
<
a
));
b
=
FlagB
;
b
=
Flag
s
::
Flag
B
;
assert
!
(
a
<
b
);
a
=
FlagC
;
a
=
Flag
s
::
Flag
C
;
assert
!
(
!
(
a
<
b
)
&&
b
<
a
);
b
=
Flag
C
|
FlagB
;
b
=
Flag
s
::
FlagC
|
Flags
::
FlagB
;
assert
!
(
a
<
b
);
}
...
...
@@ -480,10 +482,10 @@ fn test_ord() {
let
mut
b
=
Flags
::
empty
();
assert
!
(
a
<=
b
&&
a
>=
b
);
a
=
FlagA
;
a
=
Flag
s
::
Flag
A
;
assert
!
(
a
>
b
&&
a
>=
b
);
assert
!
(
b
<
a
&&
b
<=
a
);
b
=
FlagB
;
b
=
Flag
s
::
Flag
B
;
assert
!
(
b
>
a
&&
b
>=
a
);
assert
!
(
a
<
b
&&
a
<=
b
);
}
...
...
@@ -494,7 +496,7 @@ fn test_hash() {
let
mut
y
=
Flags
::
empty
();
assert
!
(
hash
::
hash
::
<
Flags
,
SipHasher
>
(
&
x
)
==
hash
::
hash
::
<
Flags
,
SipHasher
>
(
&
y
));
x
=
Flags
::
all
();
y
=
FlagABC
;
y
=
Flag
s
::
Flag
ABC
;
assert
!
(
hash
::
hash
::
<
Flags
,
SipHasher
>
(
&
x
)
==
hash
::
hash
::
<
Flags
,
SipHasher
>
(
&
y
));
}
}
src/librustc_llvm/lib.rs
浏览文件 @
2edb6438
...
...
@@ -25,6 +25,7 @@
html_favicon_url
=
"http://www.rust-lang.org/favicon.ico"
,
html_root_url
=
"http://doc.rust-lang.org/nightly/"
)]
#![feature(associated_consts)]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(libc)]
...
...
@@ -124,32 +125,32 @@ pub enum DiagnosticSeverity {
bitflags!
{
flags
Attribute
:
u32
{
const
ZExtAttribute
=
1
<<
0
,
const
SExtAttribute
=
1
<<
1
,
const
NoReturnAttribute
=
1
<<
2
,
const
InRegAttribute
=
1
<<
3
,
const
StructRetAttribute
=
1
<<
4
,
const
NoUnwindAttribute
=
1
<<
5
,
const
NoAliasAttribute
=
1
<<
6
,
const
ByValAttribute
=
1
<<
7
,
const
NestAttribute
=
1
<<
8
,
const
ReadNoneAttribute
=
1
<<
9
,
const
ReadOnlyAttribute
=
1
<<
10
,
const
NoInlineAttribute
=
1
<<
11
,
const
AlwaysInlineAttribute
=
1
<<
12
,
const
ZExtAttribute
=
1
<<
0
,
const
SExtAttribute
=
1
<<
1
,
const
NoReturnAttribute
=
1
<<
2
,
const
InRegAttribute
=
1
<<
3
,
const
StructRetAttribute
=
1
<<
4
,
const
NoUnwindAttribute
=
1
<<
5
,
const
NoAliasAttribute
=
1
<<
6
,
const
ByValAttribute
=
1
<<
7
,
const
NestAttribute
=
1
<<
8
,
const
ReadNoneAttribute
=
1
<<
9
,
const
ReadOnlyAttribute
=
1
<<
10
,
const
NoInlineAttribute
=
1
<<
11
,
const
AlwaysInlineAttribute
=
1
<<
12
,
const
OptimizeForSizeAttribute
=
1
<<
13
,
const
StackProtectAttribute
=
1
<<
14
,
const
StackProtectAttribute
=
1
<<
14
,
const
StackProtectReqAttribute
=
1
<<
15
,
const
AlignmentAttribute
=
3
1
<<
16
,
const
NoCaptureAttribute
=
1
<<
21
,
const
NoRedZoneAttribute
=
1
<<
22
,
const
AlignmentAttribute
=
1
<<
16
,
const
NoCaptureAttribute
=
1
<<
21
,
const
NoRedZoneAttribute
=
1
<<
22
,
const
NoImplicitFloatAttribute
=
1
<<
23
,
const
NakedAttribute
=
1
<<
24
,
const
InlineHintAttribute
=
1
<<
25
,
const
StackAttribute
=
7
<<
26
,
const
ReturnsTwiceAttribute
=
1
<<
29
,
const
UWTableAttribute
=
1
<<
30
,
const
NonLazyBindAttribute
=
1
<<
31
,
const
NakedAttribute
=
1
<<
24
,
const
InlineHintAttribute
=
1
<<
25
,
const
StackAttribute
=
7
<<
26
,
const
ReturnsTwiceAttribute
=
1
<<
29
,
const
UWTableAttribute
=
1
<<
30
,
const
NonLazyBindAttribute
=
1
<<
31
,
}
}
...
...
src/librustc_resolve/build_reduced_graph.rs
浏览文件 @
2edb6438
...
...
@@ -13,7 +13,7 @@
//! Here we build the "reduced graph": the graph of the module tree without
//! any imports resolved.
use
{
DefModifiers
,
PUBLIC
,
IMPORTABLE
}
;
use
DefModifiers
;
use
resolve_imports
::
ImportDirective
;
use
resolve_imports
::
ImportDirectiveSubclass
::{
self
,
SingleImport
,
GlobImport
};
use
resolve_imports
::
ImportResolution
;
...
...
@@ -262,7 +262,11 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) ->
let
name
=
item
.ident.name
;
let
sp
=
item
.span
;
let
is_public
=
item
.vis
==
ast
::
Public
;
let
modifiers
=
if
is_public
{
PUBLIC
}
else
{
DefModifiers
::
empty
()
}
|
IMPORTABLE
;
let
modifiers
=
if
is_public
{
DefModifiers
::
PUBLIC
}
else
{
DefModifiers
::
empty
()
}
|
DefModifiers
::
IMPORTABLE
;
match
item
.node
{
ItemUse
(
ref
view_path
)
=>
{
...
...
@@ -533,20 +537,20 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) ->
ast
::
ConstTraitItem
(
..
)
=>
{
let
def
=
DefAssociatedConst
(
local_def
(
trait_item
.id
),
FromTrait
(
local_def
(
item
.id
)));
// NB: not IMPORTABLE
name_bindings
.define_value
(
def
,
trait_item
.span
,
PUBLIC
);
// NB: not
DefModifiers::
IMPORTABLE
name_bindings
.define_value
(
def
,
trait_item
.span
,
DefModifiers
::
PUBLIC
);
}
ast
::
MethodTraitItem
(
..
)
=>
{
let
def
=
DefMethod
(
local_def
(
trait_item
.id
),
FromTrait
(
local_def
(
item
.id
)));
// NB: not IMPORTABLE
name_bindings
.define_value
(
def
,
trait_item
.span
,
PUBLIC
);
// NB: not
DefModifiers::
IMPORTABLE
name_bindings
.define_value
(
def
,
trait_item
.span
,
DefModifiers
::
PUBLIC
);
}
ast
::
TypeTraitItem
(
..
)
=>
{
let
def
=
DefAssociatedTy
(
local_def
(
item
.id
),
local_def
(
trait_item
.id
));
// NB: not IMPORTABLE
name_bindings
.define_type
(
def
,
trait_item
.span
,
PUBLIC
);
// NB: not
DefModifiers::
IMPORTABLE
name_bindings
.define_type
(
def
,
trait_item
.span
,
DefModifiers
::
PUBLIC
);
}
}
...
...
@@ -584,10 +588,10 @@ fn build_reduced_graph_for_variant(&mut self,
// used
child
.define_value
(
DefVariant
(
item_id
,
local_def
(
variant
.node.id
),
is_exported
),
variant
.span
,
PUBLIC
|
IMPORTABLE
);
variant
.span
,
DefModifiers
::
PUBLIC
|
DefModifiers
::
IMPORTABLE
);
child
.define_type
(
DefVariant
(
item_id
,
local_def
(
variant
.node.id
),
is_exported
),
variant
.span
,
PUBLIC
|
IMPORTABLE
);
variant
.span
,
DefModifiers
::
PUBLIC
|
DefModifiers
::
IMPORTABLE
);
}
/// Constructs the reduced graph for one foreign item.
...
...
@@ -596,7 +600,11 @@ fn build_reduced_graph_for_foreign_item(&mut self,
parent
:
&
Rc
<
Module
>
)
{
let
name
=
foreign_item
.ident.name
;
let
is_public
=
foreign_item
.vis
==
ast
::
Public
;
let
modifiers
=
if
is_public
{
PUBLIC
}
else
{
DefModifiers
::
empty
()
}
|
IMPORTABLE
;
let
modifiers
=
if
is_public
{
DefModifiers
::
PUBLIC
}
else
{
DefModifiers
::
empty
()
}
|
DefModifiers
::
IMPORTABLE
;
let
name_bindings
=
self
.add_child
(
name
,
parent
,
ForbidDuplicateValues
,
foreign_item
.span
);
...
...
@@ -644,7 +652,11 @@ fn handle_external_def(&mut self,
external crate) building external def {}, priv {:?}"
,
final_ident
,
vis
);
let
is_public
=
vis
==
ast
::
Public
;
let
modifiers
=
if
is_public
{
PUBLIC
}
else
{
DefModifiers
::
empty
()
}
|
IMPORTABLE
;
let
modifiers
=
if
is_public
{
DefModifiers
::
PUBLIC
}
else
{
DefModifiers
::
empty
()
}
|
DefModifiers
::
IMPORTABLE
;
let
is_exported
=
is_public
&&
match
new_parent
.def_id
.get
()
{
None
=>
true
,
Some
(
did
)
=>
self
.external_exports
.contains
(
&
did
)
...
...
@@ -695,7 +707,7 @@ fn handle_external_def(&mut self,
final_ident
);
// variants are always treated as importable to allow them to be
// glob used
let
modifiers
=
PUBLIC
|
IMPORTABLE
;
let
modifiers
=
DefModifiers
::
PUBLIC
|
DefModifiers
::
IMPORTABLE
;
if
is_struct
{
child_name_bindings
.define_type
(
def
,
DUMMY_SP
,
modifiers
);
// Not adding fields for variants as they are not accessed with a self receiver
...
...
@@ -715,11 +727,12 @@ fn handle_external_def(&mut self,
crate) building value (fn/static) {}"
,
final_ident
);
// impl methods have already been defined with the correct importability modifier
let
mut
modifiers
=
match
*
child_name_bindings
.value_def
.borrow
()
{
Some
(
ref
def
)
=>
(
modifiers
&
!
IMPORTABLE
)
|
(
def
.modifiers
&
IMPORTABLE
),
Some
(
ref
def
)
=>
(
modifiers
&
!
DefModifiers
::
IMPORTABLE
)
|
(
def
.modifiers
&
DefModifiers
::
IMPORTABLE
),
None
=>
modifiers
};
if
new_parent
.kind
.get
()
!=
NormalModuleKind
{
modifiers
=
modifiers
&
!
IMPORTABLE
;
modifiers
=
modifiers
&
!
DefModifiers
::
IMPORTABLE
;
}
child_name_bindings
.define_value
(
def
,
DUMMY_SP
,
modifiers
);
}
...
...
src/librustc_resolve/lib.rs
浏览文件 @
2edb6438
...
...
@@ -20,6 +20,7 @@
html_root_url
=
"http://doc.rust-lang.org/nightly/"
)]
#![feature(alloc)]
#![feature(associated_consts)]
#![feature(collections)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
...
...
@@ -477,8 +478,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
bitflags!
{
#[derive(Debug)]
flags
DefModifiers
:
u8
{
const
PUBLIC
=
0b0000_0001
,
const
IMPORTABLE
=
0b0000_0010
,
const
PUBLIC
=
1
<<
0
,
const
IMPORTABLE
=
1
<<
1
,
}
}
...
...
@@ -524,7 +525,11 @@ fn define_module(&self,
is_public
:
bool
,
sp
:
Span
)
{
// Merges the module with the existing type def or creates a new one.
let
modifiers
=
if
is_public
{
PUBLIC
}
else
{
DefModifiers
::
empty
()
}
|
IMPORTABLE
;
let
modifiers
=
if
is_public
{
DefModifiers
::
PUBLIC
}
else
{
DefModifiers
::
empty
()
}
|
DefModifiers
::
IMPORTABLE
;
let
module_
=
Rc
::
new
(
Module
::
new
(
parent_link
,
def_id
,
kind
,
...
...
@@ -559,7 +564,11 @@ fn set_module_kind(&self,
external
:
bool
,
is_public
:
bool
,
_
sp
:
Span
)
{
let
modifiers
=
if
is_public
{
PUBLIC
}
else
{
DefModifiers
::
empty
()
}
|
IMPORTABLE
;
let
modifiers
=
if
is_public
{
DefModifiers
::
PUBLIC
}
else
{
DefModifiers
::
empty
()
}
|
DefModifiers
::
IMPORTABLE
;
let
type_def
=
self
.type_def
.borrow
()
.clone
();
match
type_def
{
None
=>
{
...
...
@@ -659,7 +668,7 @@ fn defined_in_namespace(&self, namespace: Namespace) -> bool {
}
fn
defined_in_public_namespace
(
&
self
,
namespace
:
Namespace
)
->
bool
{
self
.defined_in_namespace_with
(
namespace
,
PUBLIC
)
self
.defined_in_namespace_with
(
namespace
,
DefModifiers
::
PUBLIC
)
}
fn
defined_in_namespace_with
(
&
self
,
namespace
:
Namespace
,
modifiers
:
DefModifiers
)
->
bool
{
...
...
@@ -730,11 +739,11 @@ fn is_public(&self, namespace: Namespace) -> bool {
match
namespace
{
TypeNS
=>
{
let
type_def
=
self
.type_def
.borrow
();
type_def
.as_ref
()
.unwrap
()
.modifiers
.contains
(
PUBLIC
)
type_def
.as_ref
()
.unwrap
()
.modifiers
.contains
(
DefModifiers
::
PUBLIC
)
}
ValueNS
=>
{
let
value_def
=
self
.value_def
.borrow
();
value_def
.as_ref
()
.unwrap
()
.modifiers
.contains
(
PUBLIC
)
value_def
.as_ref
()
.unwrap
()
.modifiers
.contains
(
DefModifiers
::
PUBLIC
)
}
}
}
...
...
@@ -921,7 +930,7 @@ fn get_trait_name(&self, did: DefId) -> Name {
fn
create_name_bindings_from_module
(
module
:
Rc
<
Module
>
)
->
NameBindings
{
NameBindings
{
type_def
:
RefCell
::
new
(
Some
(
TypeNsDef
{
modifiers
:
IMPORTABLE
,
modifiers
:
DefModifiers
::
IMPORTABLE
,
module_def
:
Some
(
module
),
type_def
:
None
,
type_span
:
None
...
...
src/librustc_resolve/resolve_imports.rs
浏览文件 @
2edb6438
...
...
@@ -10,7 +10,7 @@
use
self
::
ImportDirectiveSubclass
::
*
;
use
{
PUBLIC
,
IMPORTABLE
}
;
use
DefModifiers
;
use
Module
;
use
Namespace
::{
self
,
TypeNS
,
ValueNS
};
use
NameBindings
;
...
...
@@ -848,7 +848,9 @@ fn merge_import_resolution(&mut self,
// Merge the child item into the import resolution.
{
let
mut
merge_child_item
=
|
namespace
|
{
if
name_bindings
.defined_in_namespace_with
(
namespace
,
IMPORTABLE
|
PUBLIC
)
{
let
modifier
=
DefModifiers
::
IMPORTABLE
|
DefModifiers
::
PUBLIC
;
if
name_bindings
.defined_in_namespace_with
(
namespace
,
modifier
)
{
let
namespace_name
=
match
namespace
{
TypeNS
=>
"type"
,
ValueNS
=>
"value"
,
...
...
@@ -914,7 +916,7 @@ fn check_that_import_is_importable(&mut self,
import_span
:
Span
,
name
:
Name
,
namespace
:
Namespace
)
{
if
!
name_bindings
.defined_in_namespace_with
(
namespace
,
IMPORTABLE
)
{
if
!
name_bindings
.defined_in_namespace_with
(
namespace
,
DefModifiers
::
IMPORTABLE
)
{
let
msg
=
format!
(
"`{}` is not directly importable"
,
token
::
get_name
(
name
));
span_err!
(
self
.resolver.session
,
import_span
,
E0253
,
"{}"
,
&
msg
[
..
]);
...
...
src/librustc_trans/trans/attributes.rs
浏览文件 @
2edb6438
...
...
@@ -39,13 +39,13 @@ pub fn split_stack(val: ValueRef, set: bool) {
pub
fn
inline
(
val
:
ValueRef
,
inline
:
InlineAttr
)
{
use
self
::
InlineAttr
::
*
;
match
inline
{
Hint
=>
llvm
::
SetFunctionAttribute
(
val
,
llvm
::
InlineHintAttribute
),
Always
=>
llvm
::
SetFunctionAttribute
(
val
,
llvm
::
AlwaysInlineAttribute
),
Never
=>
llvm
::
SetFunctionAttribute
(
val
,
llvm
::
NoInlineAttribute
),
Hint
=>
llvm
::
SetFunctionAttribute
(
val
,
llvm
::
Attribute
::
InlineHintAttribute
),
Always
=>
llvm
::
SetFunctionAttribute
(
val
,
llvm
::
A
ttribute
::
A
lwaysInlineAttribute
),
Never
=>
llvm
::
SetFunctionAttribute
(
val
,
llvm
::
Attribute
::
NoInlineAttribute
),
None
=>
{
let
attr
=
llvm
::
InlineHintAttribute
|
llvm
::
AlwaysInlineAttribute
|
llvm
::
NoInlineAttribute
;
let
attr
=
llvm
::
Attribute
::
InlineHintAttribute
|
llvm
::
A
ttribute
::
A
lwaysInlineAttribute
|
llvm
::
Attribute
::
NoInlineAttribute
;
unsafe
{
llvm
::
LLVMRemoveFunctionAttr
(
val
,
attr
.bits
()
as
c_ulonglong
)
}
...
...
@@ -57,10 +57,13 @@ pub fn inline(val: ValueRef, inline: InlineAttr) {
#[inline]
pub
fn
emit_uwtable
(
val
:
ValueRef
,
emit
:
bool
)
{
if
emit
{
llvm
::
SetFunctionAttribute
(
val
,
llvm
::
UWTableAttribute
);
llvm
::
SetFunctionAttribute
(
val
,
llvm
::
Attribute
::
UWTableAttribute
);
}
else
{
unsafe
{
llvm
::
LLVMRemoveFunctionAttr
(
val
,
llvm
::
UWTableAttribute
.bits
()
as
c_ulonglong
);
llvm
::
LLVMRemoveFunctionAttr
(
val
,
llvm
::
Attribute
::
UWTableAttribute
.bits
()
as
c_ulonglong
,
);
}
}
}
...
...
@@ -71,10 +74,13 @@ pub fn emit_uwtable(val: ValueRef, emit: bool) {
pub
fn
unwind
(
val
:
ValueRef
,
can_unwind
:
bool
)
{
if
can_unwind
{
unsafe
{
llvm
::
LLVMRemoveFunctionAttr
(
val
,
llvm
::
NoUnwindAttribute
.bits
()
as
c_ulonglong
);
llvm
::
LLVMRemoveFunctionAttr
(
val
,
llvm
::
Attribute
::
NoUnwindAttribute
.bits
()
as
c_ulonglong
,
);
}
}
else
{
llvm
::
SetFunctionAttribute
(
val
,
llvm
::
NoUnwindAttribute
);
llvm
::
SetFunctionAttribute
(
val
,
llvm
::
Attribute
::
NoUnwindAttribute
);
}
}
...
...
@@ -83,10 +89,13 @@ pub fn unwind(val: ValueRef, can_unwind: bool) {
#[allow(dead_code)]
// possibly useful function
pub
fn
set_optimize_for_size
(
val
:
ValueRef
,
optimize
:
bool
)
{
if
optimize
{
llvm
::
SetFunctionAttribute
(
val
,
llvm
::
OptimizeForSizeAttribute
);
llvm
::
SetFunctionAttribute
(
val
,
llvm
::
Attribute
::
OptimizeForSizeAttribute
);
}
else
{
unsafe
{
llvm
::
LLVMRemoveFunctionAttr
(
val
,
llvm
::
OptimizeForSizeAttribute
.bits
()
as
c_ulonglong
);
llvm
::
LLVMRemoveFunctionAttr
(
val
,
llvm
::
Attribute
::
OptimizeForSizeAttribute
.bits
()
as
c_ulonglong
,
);
}
}
}
...
...
@@ -107,7 +116,7 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRe
llvm
::
ColdAttribute
as
u64
)
}
}
else
if
attr
.check_name
(
"allocator"
)
{
llvm
::
NoAliasAttribute
.apply_llfn
(
llvm
::
ReturnIndex
as
c_uint
,
llfn
);
llvm
::
Attribute
::
NoAliasAttribute
.apply_llfn
(
llvm
::
ReturnIndex
as
c_uint
,
llfn
);
}
}
}
...
...
@@ -176,9 +185,9 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
// The outptr can be noalias and nocapture because it's entirely
// invisible to the program. We also know it's nonnull as well
// as how many bytes we can dereference
attrs
.arg
(
1
,
llvm
::
StructRetAttribute
)
.arg
(
1
,
llvm
::
NoAliasAttribute
)
.arg
(
1
,
llvm
::
NoCaptureAttribute
)
attrs
.arg
(
1
,
llvm
::
Attribute
::
StructRetAttribute
)
.arg
(
1
,
llvm
::
Attribute
::
NoAliasAttribute
)
.arg
(
1
,
llvm
::
Attribute
::
NoCaptureAttribute
)
.arg
(
1
,
llvm
::
DereferenceableAttribute
(
llret_sz
));
// Add one more since there's an outptr
...
...
@@ -190,7 +199,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
// `~` pointer return values never alias because ownership
// is transferred
ty
::
ty_uniq
(
it
)
if
common
::
type_is_sized
(
ccx
.tcx
(),
it
)
=>
{
attrs
.ret
(
llvm
::
NoAliasAttribute
);
attrs
.ret
(
llvm
::
Attribute
::
NoAliasAttribute
);
}
_
=>
{}
}
...
...
@@ -207,7 +216,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
}
if
let
ty
::
ty_bool
=
ret_ty
.sty
{
attrs
.ret
(
llvm
::
ZExtAttribute
);
attrs
.ret
(
llvm
::
Attribute
::
ZExtAttribute
);
}
}
}
...
...
@@ -221,20 +230,20 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
// For non-immediate arguments the callee gets its own copy of
// the value on the stack, so there are no aliases. It's also
// program-invisible so can't possibly capture
attrs
.arg
(
idx
,
llvm
::
NoAliasAttribute
)
.arg
(
idx
,
llvm
::
NoCaptureAttribute
)
attrs
.arg
(
idx
,
llvm
::
Attribute
::
NoAliasAttribute
)
.arg
(
idx
,
llvm
::
Attribute
::
NoCaptureAttribute
)
.arg
(
idx
,
llvm
::
DereferenceableAttribute
(
llarg_sz
));
}
ty
::
ty_bool
=>
{
attrs
.arg
(
idx
,
llvm
::
ZExtAttribute
);
attrs
.arg
(
idx
,
llvm
::
Attribute
::
ZExtAttribute
);
}
// `~` pointer parameters never alias because ownership is transferred
ty
::
ty_uniq
(
inner
)
=>
{
let
llsz
=
machine
::
llsize_of_real
(
ccx
,
type_of
::
type_of
(
ccx
,
inner
));
attrs
.arg
(
idx
,
llvm
::
NoAliasAttribute
)
attrs
.arg
(
idx
,
llvm
::
Attribute
::
NoAliasAttribute
)
.arg
(
idx
,
llvm
::
DereferenceableAttribute
(
llsz
));
}
...
...
@@ -247,15 +256,15 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
!
ty
::
type_contents
(
ccx
.tcx
(),
mt
.ty
)
.interior_unsafe
()
=>
{
let
llsz
=
machine
::
llsize_of_real
(
ccx
,
type_of
::
type_of
(
ccx
,
mt
.ty
));
attrs
.arg
(
idx
,
llvm
::
NoAliasAttribute
)
attrs
.arg
(
idx
,
llvm
::
Attribute
::
NoAliasAttribute
)
.arg
(
idx
,
llvm
::
DereferenceableAttribute
(
llsz
));
if
mt
.mutbl
==
ast
::
MutImmutable
{
attrs
.arg
(
idx
,
llvm
::
ReadOnlyAttribute
);
attrs
.arg
(
idx
,
llvm
::
Attribute
::
ReadOnlyAttribute
);
}
if
let
ReLateBound
(
_
,
BrAnon
(
_
))
=
*
b
{
attrs
.arg
(
idx
,
llvm
::
NoCaptureAttribute
);
attrs
.arg
(
idx
,
llvm
::
Attribute
::
NoCaptureAttribute
);
}
}
...
...
@@ -263,7 +272,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
// reference to escape this function (returned or stored beyond the call by a closure).
ty
::
ty_rptr
(
&
ReLateBound
(
_
,
BrAnon
(
_
)),
mt
)
=>
{
let
llsz
=
machine
::
llsize_of_real
(
ccx
,
type_of
::
type_of
(
ccx
,
mt
.ty
));
attrs
.arg
(
idx
,
llvm
::
NoCaptureAttribute
)
attrs
.arg
(
idx
,
llvm
::
Attribute
::
NoCaptureAttribute
)
.arg
(
idx
,
llvm
::
DereferenceableAttribute
(
llsz
));
}
...
...
src/librustc_trans/trans/cabi_aarch64.rs
浏览文件 @
2edb6438
...
...
@@ -10,8 +10,7 @@
#![allow(non_upper_case_globals)]
use
llvm
::{
Integer
,
Pointer
,
Float
,
Double
,
Struct
,
Array
,
Vector
};
use
llvm
::{
StructRetAttribute
,
ZExtAttribute
};
use
llvm
::{
Integer
,
Pointer
,
Float
,
Double
,
Struct
,
Array
,
Vector
,
Attribute
};
use
trans
::
cabi
::{
FnType
,
ArgType
};
use
trans
::
context
::
CrateContext
;
use
trans
::
type_
::
Type
;
...
...
@@ -164,7 +163,7 @@ fn check_struct(ty: Type) -> Option<(Type, u64)> {
fn
classify_ret_ty
(
ccx
:
&
CrateContext
,
ty
:
Type
)
->
ArgType
{
if
is_reg_ty
(
ty
)
{
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
ZExtAttribute
)
}
else
{
None
};
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
Attribute
::
ZExtAttribute
)
}
else
{
None
};
return
ArgType
::
direct
(
ty
,
None
,
None
,
attr
);
}
if
let
Some
((
base_ty
,
members
))
=
is_homogenous_aggregate_ty
(
ty
)
{
...
...
@@ -186,12 +185,12 @@ fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
};
return
ArgType
::
direct
(
ty
,
Some
(
llty
),
None
,
None
);
}
ArgType
::
indirect
(
ty
,
Some
(
StructRetAttribute
))
ArgType
::
indirect
(
ty
,
Some
(
Attribute
::
StructRetAttribute
))
}
fn
classify_arg_ty
(
ccx
:
&
CrateContext
,
ty
:
Type
)
->
ArgType
{
if
is_reg_ty
(
ty
)
{
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
ZExtAttribute
)
}
else
{
None
};
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
Attribute
::
ZExtAttribute
)
}
else
{
None
};
return
ArgType
::
direct
(
ty
,
None
,
None
,
attr
);
}
if
let
Some
((
base_ty
,
members
))
=
is_homogenous_aggregate_ty
(
ty
)
{
...
...
src/librustc_trans/trans/cabi_arm.rs
浏览文件 @
2edb6438
...
...
@@ -10,8 +10,7 @@
#![allow(non_upper_case_globals)]
use
llvm
::{
Integer
,
Pointer
,
Float
,
Double
,
Struct
,
Array
,
Vector
};
use
llvm
::{
StructRetAttribute
,
ZExtAttribute
};
use
llvm
::{
Integer
,
Pointer
,
Float
,
Double
,
Struct
,
Array
,
Vector
,
Attribute
};
use
trans
::
cabi
::{
FnType
,
ArgType
};
use
trans
::
context
::
CrateContext
;
use
trans
::
type_
::
Type
;
...
...
@@ -132,7 +131,7 @@ fn ty_size(ty: Type, align_fn: TyAlignFn) -> usize {
fn
classify_ret_ty
(
ccx
:
&
CrateContext
,
ty
:
Type
,
align_fn
:
TyAlignFn
)
->
ArgType
{
if
is_reg_ty
(
ty
)
{
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
ZExtAttribute
)
}
else
{
None
};
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
Attribute
::
ZExtAttribute
)
}
else
{
None
};
return
ArgType
::
direct
(
ty
,
None
,
None
,
attr
);
}
let
size
=
ty_size
(
ty
,
align_fn
);
...
...
@@ -146,12 +145,12 @@ fn classify_ret_ty(ccx: &CrateContext, ty: Type, align_fn: TyAlignFn) -> ArgType
};
return
ArgType
::
direct
(
ty
,
Some
(
llty
),
None
,
None
);
}
ArgType
::
indirect
(
ty
,
Some
(
StructRetAttribute
))
ArgType
::
indirect
(
ty
,
Some
(
Attribute
::
StructRetAttribute
))
}
fn
classify_arg_ty
(
ccx
:
&
CrateContext
,
ty
:
Type
,
align_fn
:
TyAlignFn
)
->
ArgType
{
if
is_reg_ty
(
ty
)
{
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
ZExtAttribute
)
}
else
{
None
};
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
Attribute
::
ZExtAttribute
)
}
else
{
None
};
return
ArgType
::
direct
(
ty
,
None
,
None
,
attr
);
}
let
align
=
align_fn
(
ty
);
...
...
src/librustc_trans/trans/cabi_mips.rs
浏览文件 @
2edb6438
...
...
@@ -13,8 +13,7 @@
use
libc
::
c_uint
;
use
std
::
cmp
;
use
llvm
;
use
llvm
::{
Integer
,
Pointer
,
Float
,
Double
,
Struct
,
Array
,
Vector
};
use
llvm
::{
StructRetAttribute
,
ZExtAttribute
};
use
llvm
::{
Integer
,
Pointer
,
Float
,
Double
,
Struct
,
Array
,
Vector
,
Attribute
};
use
trans
::
cabi
::{
ArgType
,
FnType
};
use
trans
::
context
::
CrateContext
;
use
trans
::
type_
::
Type
;
...
...
@@ -89,10 +88,10 @@ fn ty_size(ty: Type) -> usize {
fn
classify_ret_ty
(
ccx
:
&
CrateContext
,
ty
:
Type
)
->
ArgType
{
if
is_reg_ty
(
ty
)
{
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
ZExtAttribute
)
}
else
{
None
};
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
Attribute
::
ZExtAttribute
)
}
else
{
None
};
ArgType
::
direct
(
ty
,
None
,
None
,
attr
)
}
else
{
ArgType
::
indirect
(
ty
,
Some
(
StructRetAttribute
))
ArgType
::
indirect
(
ty
,
Some
(
Attribute
::
StructRetAttribute
))
}
}
...
...
@@ -106,7 +105,7 @@ fn classify_arg_ty(ccx: &CrateContext, ty: Type, offset: &mut usize) -> ArgType
*
offset
+=
align_up_to
(
size
,
align
*
8
)
/
8
;
if
is_reg_ty
(
ty
)
{
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
ZExtAttribute
)
}
else
{
None
};
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
Attribute
::
ZExtAttribute
)
}
else
{
None
};
ArgType
::
direct
(
ty
,
None
,
None
,
attr
)
}
else
{
ArgType
::
direct
(
...
...
src/librustc_trans/trans/cabi_powerpc.rs
浏览文件 @
2edb6438
...
...
@@ -10,8 +10,7 @@
use
libc
::
c_uint
;
use
llvm
;
use
llvm
::{
Integer
,
Pointer
,
Float
,
Double
,
Struct
,
Array
};
use
llvm
::{
StructRetAttribute
,
ZExtAttribute
};
use
llvm
::{
Integer
,
Pointer
,
Float
,
Double
,
Struct
,
Array
,
Attribute
};
use
trans
::
cabi
::{
FnType
,
ArgType
};
use
trans
::
context
::
CrateContext
;
use
trans
::
type_
::
Type
;
...
...
@@ -85,10 +84,10 @@ fn ty_size(ty: Type) -> usize {
fn
classify_ret_ty
(
ccx
:
&
CrateContext
,
ty
:
Type
)
->
ArgType
{
if
is_reg_ty
(
ty
)
{
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
ZExtAttribute
)
}
else
{
None
};
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
Attribute
::
ZExtAttribute
)
}
else
{
None
};
ArgType
::
direct
(
ty
,
None
,
None
,
attr
)
}
else
{
ArgType
::
indirect
(
ty
,
Some
(
StructRetAttribute
))
ArgType
::
indirect
(
ty
,
Some
(
Attribute
::
StructRetAttribute
))
}
}
...
...
@@ -102,7 +101,7 @@ fn classify_arg_ty(ccx: &CrateContext, ty: Type, offset: &mut usize) -> ArgType
*
offset
+=
align_up_to
(
size
,
align
*
8
)
/
8
;
if
is_reg_ty
(
ty
)
{
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
ZExtAttribute
)
}
else
{
None
};
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
Attribute
::
ZExtAttribute
)
}
else
{
None
};
ArgType
::
direct
(
ty
,
None
,
None
,
attr
)
}
else
{
ArgType
::
direct
(
...
...
src/librustc_trans/trans/cabi_x86.rs
浏览文件 @
2edb6438
...
...
@@ -52,11 +52,11 @@ pub fn compute_abi_info(ccx: &CrateContext,
ret_ty
=
ArgType
::
direct
(
rty
,
Some
(
t
),
None
,
None
);
}
RetPointer
=>
{
ret_ty
=
ArgType
::
indirect
(
rty
,
Some
(
StructRetAttribute
));
ret_ty
=
ArgType
::
indirect
(
rty
,
Some
(
Attribute
::
StructRetAttribute
));
}
}
}
else
{
let
attr
=
if
rty
==
Type
::
i1
(
ccx
)
{
Some
(
ZExtAttribute
)
}
else
{
None
};
let
attr
=
if
rty
==
Type
::
i1
(
ccx
)
{
Some
(
Attribute
::
ZExtAttribute
)
}
else
{
None
};
ret_ty
=
ArgType
::
direct
(
rty
,
None
,
None
,
attr
);
}
...
...
@@ -67,11 +67,11 @@ pub fn compute_abi_info(ccx: &CrateContext,
if
size
==
0
{
ArgType
::
ignore
(
t
)
}
else
{
ArgType
::
indirect
(
t
,
Some
(
ByValAttribute
))
ArgType
::
indirect
(
t
,
Some
(
Attribute
::
ByValAttribute
))
}
}
_
=>
{
let
attr
=
if
t
==
Type
::
i1
(
ccx
)
{
Some
(
ZExtAttribute
)
}
else
{
None
};
let
attr
=
if
t
==
Type
::
i1
(
ccx
)
{
Some
(
Attribute
::
ZExtAttribute
)
}
else
{
None
};
ArgType
::
direct
(
t
,
None
,
None
,
attr
)
}
};
...
...
src/librustc_trans/trans/cabi_x86_64.rs
浏览文件 @
2edb6438
...
...
@@ -16,7 +16,6 @@
use
llvm
::{
Integer
,
Pointer
,
Float
,
Double
};
use
llvm
::{
Struct
,
Array
,
Attribute
,
Vector
};
use
llvm
::{
StructRetAttribute
,
ByValAttribute
,
ZExtAttribute
};
use
trans
::
cabi
::{
ArgType
,
FnType
};
use
trans
::
context
::
CrateContext
;
use
trans
::
type_
::
Type
;
...
...
@@ -407,19 +406,19 @@ fn x86_64_ty<F>(ccx: &CrateContext,
None
)
}
}
else
{
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
ZExtAttribute
)
}
else
{
None
};
let
attr
=
if
ty
==
Type
::
i1
(
ccx
)
{
Some
(
Attribute
::
ZExtAttribute
)
}
else
{
None
};
ArgType
::
direct
(
ty
,
None
,
None
,
attr
)
}
}
let
mut
arg_tys
=
Vec
::
new
();
for
t
in
atys
{
let
ty
=
x86_64_ty
(
ccx
,
*
t
,
|
cls
|
cls
.is_pass_byval
(),
ByValAttribute
);
let
ty
=
x86_64_ty
(
ccx
,
*
t
,
|
cls
|
cls
.is_pass_byval
(),
Attribute
::
ByValAttribute
);
arg_tys
.push
(
ty
);
}
let
ret_ty
=
if
ret_def
{
x86_64_ty
(
ccx
,
rty
,
|
cls
|
cls
.is_ret_bysret
(),
StructRetAttribute
)
x86_64_ty
(
ccx
,
rty
,
|
cls
|
cls
.is_ret_bysret
(),
Attribute
::
StructRetAttribute
)
}
else
{
ArgType
::
direct
(
Type
::
void
(
ccx
),
None
,
None
,
None
)
};
...
...
src/librustc_trans/trans/cabi_x86_win64.rs
浏览文件 @
2edb6438
...
...
@@ -31,10 +31,10 @@ pub fn compute_abi_info(ccx: &CrateContext,
2
=>
ArgType
::
direct
(
rty
,
Some
(
Type
::
i16
(
ccx
)),
None
,
None
),
4
=>
ArgType
::
direct
(
rty
,
Some
(
Type
::
i32
(
ccx
)),
None
,
None
),
8
=>
ArgType
::
direct
(
rty
,
Some
(
Type
::
i64
(
ccx
)),
None
,
None
),
_
=>
ArgType
::
indirect
(
rty
,
Some
(
StructRetAttribute
))
_
=>
ArgType
::
indirect
(
rty
,
Some
(
Attribute
::
StructRetAttribute
))
};
}
else
{
let
attr
=
if
rty
==
Type
::
i1
(
ccx
)
{
Some
(
ZExtAttribute
)
}
else
{
None
};
let
attr
=
if
rty
==
Type
::
i1
(
ccx
)
{
Some
(
Attribute
::
ZExtAttribute
)
}
else
{
None
};
ret_ty
=
ArgType
::
direct
(
rty
,
None
,
None
,
attr
);
}
...
...
@@ -46,11 +46,11 @@ pub fn compute_abi_info(ccx: &CrateContext,
2
=>
ArgType
::
direct
(
rty
,
Some
(
Type
::
i16
(
ccx
)),
None
,
None
),
4
=>
ArgType
::
direct
(
rty
,
Some
(
Type
::
i32
(
ccx
)),
None
,
None
),
8
=>
ArgType
::
direct
(
rty
,
Some
(
Type
::
i64
(
ccx
)),
None
,
None
),
_
=>
ArgType
::
indirect
(
t
,
Some
(
ByValAttribute
))
_
=>
ArgType
::
indirect
(
t
,
Some
(
Attribute
::
ByValAttribute
))
}
}
_
=>
{
let
attr
=
if
t
==
Type
::
i1
(
ccx
)
{
Some
(
ZExtAttribute
)
}
else
{
None
};
let
attr
=
if
t
==
Type
::
i1
(
ccx
)
{
Some
(
Attribute
::
ZExtAttribute
)
}
else
{
None
};
ArgType
::
direct
(
t
,
None
,
None
,
attr
)
}
};
...
...
src/librustc_trans/trans/consts.rs
浏览文件 @
2edb6438
...
...
@@ -186,7 +186,7 @@ fn get_const_val(ccx: &CrateContext,
ref_expr
:
&
ast
::
Expr
)
->
ValueRef
{
let
expr
=
get_const_expr
(
ccx
,
def_id
,
ref_expr
);
let
empty_substs
=
ccx
.tcx
()
.mk_substs
(
Substs
::
trans_empty
());
get_const_expr_as_global
(
ccx
,
expr
,
check_const
::
PURE_CONST
,
empty_substs
)
get_const_expr_as_global
(
ccx
,
expr
,
check_const
::
ConstQualif
::
PURE_CONST
,
empty_substs
)
}
pub
fn
get_const_expr_as_global
<
'a
,
'tcx
>
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
...
...
@@ -215,7 +215,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
Some
(
&
val
)
=>
return
val
,
None
=>
{}
}
let
val
=
if
qualif
.intersects
(
check_const
::
NON_STATIC_BORROWS
)
{
let
val
=
if
qualif
.intersects
(
check_const
::
ConstQualif
::
NON_STATIC_BORROWS
)
{
// Avoid autorefs as they would create global instead of stack
// references, even when only the latter are correct.
let
ty
=
monomorphize
::
apply_param_substs
(
ccx
.tcx
(),
param_substs
,
...
...
src/librustc_trans/trans/declare.rs
浏览文件 @
2edb6438
...
...
@@ -71,12 +71,12 @@ pub fn declare_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty:
llvm
::
SetUnnamedAddr
(
llfn
,
true
);
if
output
==
ty
::
FnDiverging
{
llvm
::
SetFunctionAttribute
(
llfn
,
llvm
::
NoReturnAttribute
);
llvm
::
SetFunctionAttribute
(
llfn
,
llvm
::
Attribute
::
NoReturnAttribute
);
}
if
ccx
.tcx
()
.sess.opts.cg.no_redzone
.unwrap_or
(
ccx
.tcx
()
.sess.target.target.options.disable_redzone
)
{
llvm
::
SetFunctionAttribute
(
llfn
,
llvm
::
NoRedZoneAttribute
)
llvm
::
SetFunctionAttribute
(
llfn
,
llvm
::
Attribute
::
NoRedZoneAttribute
)
}
if
ccx
.is_split_stack_supported
()
&&
!
ccx
.sess
()
.opts.cg.no_stack_check
{
...
...
src/librustc_trans/trans/expr.rs
浏览文件 @
2edb6438
...
...
@@ -126,8 +126,11 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
let
qualif
=
*
bcx
.tcx
()
.const_qualif_map
.borrow
()
.get
(
&
expr
.id
)
.unwrap
();
if
!
qualif
.intersects
(
check_const
::
NOT_CONST
|
check_const
::
NEEDS_DROP
)
{
if
!
qualif
.intersects
(
check_const
::
PREFER_IN_PLACE
)
{
if
!
qualif
.intersects
(
check_const
::
ConstQualif
::
NOT_CONST
|
check_const
::
ConstQualif
::
NEEDS_DROP
)
{
if
!
qualif
.intersects
(
check_const
::
ConstQualif
::
PREFER_IN_PLACE
)
{
if
let
SaveIn
(
lldest
)
=
dest
{
let
global
=
consts
::
get_const_expr_as_global
(
bcx
.ccx
(),
expr
,
qualif
,
bcx
.fcx.param_substs
);
...
...
@@ -209,12 +212,15 @@ pub fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let
mut
bcx
=
bcx
;
let
fcx
=
bcx
.fcx
;
let
qualif
=
*
bcx
.tcx
()
.const_qualif_map
.borrow
()
.get
(
&
expr
.id
)
.unwrap
();
let
adjusted_global
=
!
qualif
.intersects
(
check_const
::
NON_STATIC_BORROWS
);
let
global
=
if
!
qualif
.intersects
(
check_const
::
NOT_CONST
|
check_const
::
NEEDS_DROP
)
{
let
adjusted_global
=
!
qualif
.intersects
(
check_const
::
ConstQualif
::
NON_STATIC_BORROWS
);
let
global
=
if
!
qualif
.intersects
(
check_const
::
ConstQualif
::
NOT_CONST
|
check_const
::
ConstQualif
::
NEEDS_DROP
)
{
let
global
=
consts
::
get_const_expr_as_global
(
bcx
.ccx
(),
expr
,
qualif
,
bcx
.fcx.param_substs
);
if
qualif
.intersects
(
check_const
::
HAS_STATIC_BORROWS
)
{
if
qualif
.intersects
(
check_const
::
ConstQualif
::
HAS_STATIC_BORROWS
)
{
// Is borrowed as 'static, must return lvalue.
// Cast pointer to global, because constants have different types.
...
...
src/librustc_trans/trans/foreign.rs
浏览文件 @
2edb6438
...
...
@@ -349,8 +349,8 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// The outptr can be noalias and nocapture because it's entirely
// invisible to the program. We also know it's nonnull as well
// as how many bytes we can dereference
attrs
.arg
(
1
,
llvm
::
NoAliasAttribute
)
.arg
(
1
,
llvm
::
NoCaptureAttribute
)
attrs
.arg
(
1
,
llvm
::
Attribute
::
NoAliasAttribute
)
.arg
(
1
,
llvm
::
Attribute
::
NoCaptureAttribute
)
.arg
(
1
,
llvm
::
DereferenceableAttribute
(
llret_sz
));
};
...
...
src/libstd/lib.rs
浏览文件 @
2edb6438
...
...
@@ -107,26 +107,27 @@
#![doc(test(attr(allow(dead_code,
deprecated,
unused_variables,
unused_mut))))]
#![feature(alloc)]
#![feature(allow_internal_unstable)]
#![feature(associated_consts)]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(debug_builders)]
#![feature(into_cow)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(linkage,
thread_local,
asm)]
#![feature(macro_reexport)]
#![feature(optin_builtin_traits)]
#![feature(rand)]
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(str_char)]
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unsafe_no_drop_flag,
filling_drop)]
#![feature(macro_reexport)]
#![feature(unique)]
#![feature(allow_internal_unstable)]
#![feature(str_char)]
#![feature(into_cow)]
#![feature(std_misc)]
#![feature(slice_patterns)]
#![feature(debug_builders)]
#![feature(unsafe_no_drop_flag,
filling_drop)]
#![feature(zero_one)]
#![cfg_attr(test,
feature(float_from_str_radix))]
#![cfg_attr(test,
feature(test,
rustc_private,
std_misc))]
...
...
@@ -307,13 +308,12 @@ mod std {
pub
use
sync
;
// used for select!()
pub
use
error
;
// used for try!()
pub
use
fmt
;
// used for any formatting strings
pub
use
option
;
// used for
bitflags
!{}
pub
use
option
;
// used for
thread_local
!{}
pub
use
rt
;
// used for panic!()
pub
use
vec
;
// used for vec![]
pub
use
cell
;
// used for tls!
pub
use
thread
;
// used for thread_local!
pub
use
marker
;
// used for tls!
pub
use
ops
;
// used for bitflags!
// The test runner calls ::std::env::args() but really wants realstd
#[cfg(test)]
pub
use
realstd
::
env
as
env
;
...
...
src/libsyntax/lib.rs
浏览文件 @
2edb6438
...
...
@@ -25,13 +25,14 @@
html_favicon_url
=
"http://www.rust-lang.org/favicon.ico"
,
html_root_url
=
"http://doc.rust-lang.org/nightly/"
)]
#![feature(associated_consts)]
#![feature(collections)]
#![feature(core)]
#![feature(libc)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(unicode)]
#![feature(str_char)]
#![feature(unicode)]
extern
crate
arena
;
extern
crate
fmt_macros
;
...
...
src/libsyntax/parse/parser.rs
浏览文件 @
2edb6438
...
...
@@ -88,9 +88,9 @@
bitflags!
{
flags
Restrictions
:
u8
{
const
UNRESTRICTED
=
0
b0000
,
const
RESTRICTION_STMT_EXPR
=
0b0001
,
const
RESTRICTION_NO_STRUCT_LITERAL
=
0b0010
,
const
UNRESTRICTED
=
0
,
const
RESTRICTION_STMT_EXPR
=
1
<<
0
,
const
RESTRICTION_NO_STRUCT_LITERAL
=
1
<<
1
,
}
}
...
...
@@ -339,7 +339,7 @@ pub fn new(sess: &'a ParseSess,
buffer_start
:
0
,
buffer_end
:
0
,
tokens_consumed
:
0
,
restrictions
:
UNRESTRICTED
,
restrictions
:
Restrictions
::
UNRESTRICTED
,
quote_depth
:
0
,
obsolete_set
:
HashSet
::
new
(),
mod_path_stack
:
Vec
::
new
(),
...
...
@@ -2198,7 +2198,10 @@ pub fn parse_bottom_expr(&mut self) -> PResult<P<Expr>> {
if
self
.check
(
&
token
::
OpenDelim
(
token
::
Brace
))
{
// This is a struct literal, unless we're prohibited
// from parsing struct literals here.
if
!
self
.restrictions
.contains
(
RESTRICTION_NO_STRUCT_LITERAL
)
{
let
prohibited
=
self
.restrictions
.contains
(
Restrictions
::
RESTRICTION_NO_STRUCT_LITERAL
);
if
!
prohibited
{
// It's a struct literal.
try!
(
self
.bump
());
let
mut
fields
=
Vec
::
new
();
...
...
@@ -2759,7 +2762,7 @@ pub fn parse_assign_expr(&mut self) -> PResult<P<Expr>> {
}
pub
fn
parse_assign_expr_with
(
&
mut
self
,
lhs
:
P
<
Expr
>
)
->
PResult
<
P
<
Expr
>>
{
let
restrictions
=
self
.restrictions
&
RESTRICTION_NO_STRUCT_LITERAL
;
let
restrictions
=
self
.restrictions
&
R
estrictions
::
R
ESTRICTION_NO_STRUCT_LITERAL
;
let
op_span
=
self
.span
;
match
self
.token
{
token
::
Eq
=>
{
...
...
@@ -2814,7 +2817,7 @@ fn is_at_start_of_range_notation_rhs(&self) -> bool {
if
self
.token
.can_begin_expr
()
{
// parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
if
self
.token
==
token
::
OpenDelim
(
token
::
Brace
)
{
return
!
self
.restrictions
.contains
(
RESTRICTION_NO_STRUCT_LITERAL
);
return
!
self
.restrictions
.contains
(
R
estrictions
::
R
ESTRICTION_NO_STRUCT_LITERAL
);
}
true
}
else
{
...
...
@@ -2828,7 +2831,7 @@ pub fn parse_if_expr(&mut self) -> PResult<P<Expr>> {
return
self
.parse_if_let_expr
();
}
let
lo
=
self
.last_span.lo
;
let
cond
=
try!
(
self
.parse_expr_res
(
RESTRICTION_NO_STRUCT_LITERAL
));
let
cond
=
try!
(
self
.parse_expr_res
(
R
estrictions
::
R
ESTRICTION_NO_STRUCT_LITERAL
));
let
thn
=
try!
(
self
.parse_block
());
let
mut
els
:
Option
<
P
<
Expr
>>
=
None
;
let
mut
hi
=
thn
.span.hi
;
...
...
@@ -2846,7 +2849,7 @@ pub fn parse_if_let_expr(&mut self) -> PResult<P<Expr>> {
try!
(
self
.expect_keyword
(
keywords
::
Let
));
let
pat
=
try!
(
self
.parse_pat_nopanic
());
try!
(
self
.expect
(
&
token
::
Eq
));
let
expr
=
try!
(
self
.parse_expr_res
(
RESTRICTION_NO_STRUCT_LITERAL
));
let
expr
=
try!
(
self
.parse_expr_res
(
R
estrictions
::
R
ESTRICTION_NO_STRUCT_LITERAL
));
let
thn
=
try!
(
self
.parse_block
());
let
(
hi
,
els
)
=
if
try!
(
self
.eat_keyword
(
keywords
::
Else
)
){
let
expr
=
try!
(
self
.parse_else_expr
());
...
...
@@ -2905,7 +2908,7 @@ pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>) -> PResult<P<Exp
let
lo
=
self
.last_span.lo
;
let
pat
=
try!
(
self
.parse_pat_nopanic
());
try!
(
self
.expect_keyword
(
keywords
::
In
));
let
expr
=
try!
(
self
.parse_expr_res
(
RESTRICTION_NO_STRUCT_LITERAL
));
let
expr
=
try!
(
self
.parse_expr_res
(
R
estrictions
::
R
ESTRICTION_NO_STRUCT_LITERAL
));
let
loop_block
=
try!
(
self
.parse_block
());
let
hi
=
self
.last_span.hi
;
...
...
@@ -2918,7 +2921,7 @@ pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>) -> PResult<P<E
return
self
.parse_while_let_expr
(
opt_ident
);
}
let
lo
=
self
.last_span.lo
;
let
cond
=
try!
(
self
.parse_expr_res
(
RESTRICTION_NO_STRUCT_LITERAL
));
let
cond
=
try!
(
self
.parse_expr_res
(
R
estrictions
::
R
ESTRICTION_NO_STRUCT_LITERAL
));
let
body
=
try!
(
self
.parse_block
());
let
hi
=
body
.span.hi
;
return
Ok
(
self
.mk_expr
(
lo
,
hi
,
ExprWhile
(
cond
,
body
,
opt_ident
)));
...
...
@@ -2930,7 +2933,7 @@ pub fn parse_while_let_expr(&mut self, opt_ident: Option<ast::Ident>) -> PResult
try!
(
self
.expect_keyword
(
keywords
::
Let
));
let
pat
=
try!
(
self
.parse_pat_nopanic
());
try!
(
self
.expect
(
&
token
::
Eq
));
let
expr
=
try!
(
self
.parse_expr_res
(
RESTRICTION_NO_STRUCT_LITERAL
));
let
expr
=
try!
(
self
.parse_expr_res
(
R
estrictions
::
R
ESTRICTION_NO_STRUCT_LITERAL
));
let
body
=
try!
(
self
.parse_block
());
let
hi
=
body
.span.hi
;
return
Ok
(
self
.mk_expr
(
lo
,
hi
,
ExprWhileLet
(
pat
,
expr
,
body
,
opt_ident
)));
...
...
@@ -2945,7 +2948,7 @@ pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>) -> PResult<P<Ex
fn
parse_match_expr
(
&
mut
self
)
->
PResult
<
P
<
Expr
>>
{
let
lo
=
self
.last_span.lo
;
let
discriminant
=
try!
(
self
.parse_expr_res
(
RESTRICTION_NO_STRUCT_LITERAL
));
let
discriminant
=
try!
(
self
.parse_expr_res
(
R
estrictions
::
R
ESTRICTION_NO_STRUCT_LITERAL
));
try!
(
self
.commit_expr_expecting
(
&*
discriminant
,
token
::
OpenDelim
(
token
::
Brace
)));
let
mut
arms
:
Vec
<
Arm
>
=
Vec
::
new
();
while
self
.token
!=
token
::
CloseDelim
(
token
::
Brace
)
{
...
...
@@ -2966,7 +2969,7 @@ pub fn parse_arm_nopanic(&mut self) -> PResult<Arm> {
guard
=
Some
(
try!
(
self
.parse_expr_nopanic
()));
}
try!
(
self
.expect
(
&
token
::
FatArrow
));
let
expr
=
try!
(
self
.parse_expr_res
(
RESTRICTION_STMT_EXPR
));
let
expr
=
try!
(
self
.parse_expr_res
(
R
estrictions
::
R
ESTRICTION_STMT_EXPR
));
let
require_comma
=
!
classify
::
expr_is_simple_block
(
&*
expr
)
...
...
@@ -2988,7 +2991,7 @@ pub fn parse_arm_nopanic(&mut self) -> PResult<Arm> {
/// Parse an expression
pub
fn
parse_expr_nopanic
(
&
mut
self
)
->
PResult
<
P
<
Expr
>>
{
return
self
.parse_expr_res
(
UNRESTRICTED
);
return
self
.parse_expr_res
(
Restrictions
::
UNRESTRICTED
);
}
/// Parse an expression, subject to the given restrictions
...
...
@@ -3564,7 +3567,7 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
}
// Remainder are line-expr stmts.
let
e
=
try!
(
self
.parse_expr_res
(
RESTRICTION_STMT_EXPR
));
let
e
=
try!
(
self
.parse_expr_res
(
R
estrictions
::
R
ESTRICTION_STMT_EXPR
));
spanned
(
lo
,
e
.span.hi
,
StmtExpr
(
e
,
ast
::
DUMMY_NODE_ID
))
}
}
...
...
@@ -3573,7 +3576,7 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
/// Is this expression a successfully-parsed statement?
fn
expr_is_complete
(
&
mut
self
,
e
:
&
Expr
)
->
bool
{
self
.restrictions
.contains
(
RESTRICTION_STMT_EXPR
)
&&
self
.restrictions
.contains
(
R
estrictions
::
R
ESTRICTION_STMT_EXPR
)
&&
!
classify
::
expr_requires_semi_to_be_stmt
(
e
)
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录