Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
5b247b9b
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
未验证
提交
5b247b9b
编写于
1月 27, 2018
作者:
O
Oliver Schneider
提交者:
Oliver Schneider
3月 08, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Report errors in statics during collecting instead of translating
上级
df6b40e3
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
116 addition
and
69 deletion
+116
-69
src/librustc/ty/error.rs
src/librustc/ty/error.rs
+2
-6
src/librustc_mir/monomorphize/collector.rs
src/librustc_mir/monomorphize/collector.rs
+98
-59
src/librustc_trans/base.rs
src/librustc_trans/base.rs
+2
-0
src/test/compile-fail/huge-array.rs
src/test/compile-fail/huge-array.rs
+1
-1
src/test/ui/const-eval/index_out_of_bound.rs
src/test/ui/const-eval/index_out_of_bound.rs
+3
-1
src/test/ui/const-fn-error.stderr
src/test/ui/const-fn-error.stderr
+10
-2
未找到文件。
src/librustc/ty/error.rs
浏览文件 @
5b247b9b
...
...
@@ -9,10 +9,7 @@
// except according to those terms.
use
hir
::
def_id
::
DefId
;
use
middle
::
const_val
::
ConstVal
;
use
ty
::{
self
,
BoundRegion
,
Region
,
Ty
,
TyCtxt
};
use
mir
::
interpret
::{
Value
,
PrimVal
};
use
std
::
fmt
;
use
syntax
::
abi
;
use
syntax
::
ast
;
...
...
@@ -185,9 +182,8 @@ pub fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> String {
ty
::
TyAdt
(
def
,
_
)
=>
format!
(
"{} `{}`"
,
def
.descr
(),
tcx
.item_path_str
(
def
.did
)),
ty
::
TyForeign
(
def_id
)
=>
format!
(
"extern type `{}`"
,
tcx
.item_path_str
(
def_id
)),
ty
::
TyArray
(
_
,
n
)
=>
{
match
n
.val
{
ConstVal
::
Value
(
Value
::
ByVal
(
PrimVal
::
Bytes
(
n
)))
=>
format!
(
"array of {} elements"
,
n
),
match
n
.val
.to_raw_bits
()
{
Some
(
n
)
=>
format!
(
"array of {} elements"
,
n
),
_
=>
"array"
.to_string
(),
}
}
...
...
src/librustc_mir/monomorphize/collector.rs
浏览文件 @
5b247b9b
...
...
@@ -201,9 +201,10 @@
use
rustc
::
ty
::{
self
,
TypeFoldable
,
Ty
,
TyCtxt
};
use
rustc
::
ty
::
adjustment
::
CustomCoerceUnsized
;
use
rustc
::
session
::
config
;
use
rustc
::
mir
::{
self
,
Location
};
use
rustc
::
mir
::{
self
,
Location
,
Promoted
};
use
rustc
::
mir
::
visit
::
Visitor
as
MirVisitor
;
use
rustc
::
mir
::
mono
::
MonoItem
;
use
rustc
::
mir
::
interpret
::
GlobalId
;
use
monomorphize
::{
self
,
Instance
};
use
rustc
::
util
::
nodemap
::{
FxHashSet
,
FxHashMap
,
DefIdMap
};
...
...
@@ -378,7 +379,19 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
recursion_depth_reset
=
None
;
collect_neighbours
(
tcx
,
instance
,
true
,
&
mut
neighbors
);
let
cid
=
GlobalId
{
instance
,
promoted
:
None
,
};
let
param_env
=
ty
::
ParamEnv
::
empty
(
traits
::
Reveal
::
All
);
match
tcx
.const_eval
(
param_env
.and
(
cid
))
{
Ok
(
val
)
=>
collect_const
(
tcx
,
val
,
instance
.substs
,
&
mut
neighbors
),
Err
(
err
)
=>
{
let
span
=
tcx
.def_span
(
def_id
);
err
.report
(
tcx
,
span
,
"static"
);
}
}
}
MonoItem
::
Fn
(
instance
)
=>
{
// Sanity check whether this ended up being collected accidentally
...
...
@@ -390,7 +403,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
recursion_depths
));
check_type_length_limit
(
tcx
,
instance
);
collect_neighbours
(
tcx
,
instance
,
false
,
&
mut
neighbors
);
collect_neighbours
(
tcx
,
instance
,
&
mut
neighbors
);
}
MonoItem
::
GlobalAsm
(
..
)
=>
{
recursion_depth_reset
=
None
;
...
...
@@ -499,7 +512,6 @@ struct MirNeighborCollector<'a, 'tcx: 'a> {
mir
:
&
'a
mir
::
Mir
<
'tcx
>
,
output
:
&
'a
mut
Vec
<
MonoItem
<
'tcx
>>
,
param_substs
:
&
'tcx
Substs
<
'tcx
>
,
const_context
:
bool
,
}
impl
<
'a
,
'tcx
>
MirVisitor
<
'tcx
>
for
MirNeighborCollector
<
'a
,
'tcx
>
{
...
...
@@ -569,27 +581,7 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
fn
visit_const
(
&
mut
self
,
constant
:
&&
'tcx
ty
::
Const
<
'tcx
>
,
location
:
Location
)
{
debug!
(
"visiting const {:?} @ {:?}"
,
*
constant
,
location
);
match
constant
.val
{
ConstVal
::
Unevaluated
(
def_id
,
substs
)
=>
{
let
substs
=
self
.tcx
.trans_apply_param_substs
(
self
.param_substs
,
&
substs
);
let
instance
=
ty
::
Instance
::
resolve
(
self
.tcx
,
ty
::
ParamEnv
::
empty
(
traits
::
Reveal
::
All
),
def_id
,
substs
)
.unwrap
();
collect_neighbours
(
self
.tcx
,
instance
,
true
,
self
.output
);
},
ConstVal
::
Value
(
Value
::
ByValPair
(
PrimVal
::
Ptr
(
a
),
PrimVal
::
Ptr
(
b
)))
=>
{
collect_miri
(
self
.tcx
,
a
.alloc_id
,
self
.output
);
collect_miri
(
self
.tcx
,
b
.alloc_id
,
self
.output
);
}
ConstVal
::
Value
(
Value
::
ByValPair
(
_
,
PrimVal
::
Ptr
(
ptr
)))
|
ConstVal
::
Value
(
Value
::
ByValPair
(
PrimVal
::
Ptr
(
ptr
),
_
))
|
ConstVal
::
Value
(
Value
::
ByVal
(
PrimVal
::
Ptr
(
ptr
)))
|
ConstVal
::
Value
(
Value
::
ByRef
(
Pointer
{
primval
:
PrimVal
::
Ptr
(
ptr
)
},
_
))
=>
collect_miri
(
self
.tcx
,
ptr
.alloc_id
,
self
.output
),
_
=>
{},
}
collect_const
(
self
.tcx
,
constant
,
self
.param_substs
,
self
.output
);
self
.super_const
(
constant
);
}
...
...
@@ -605,30 +597,7 @@ fn visit_terminator_kind(&mut self,
mir
::
TerminatorKind
::
Call
{
ref
func
,
..
}
=>
{
let
callee_ty
=
func
.ty
(
self
.mir
,
tcx
);
let
callee_ty
=
tcx
.trans_apply_param_substs
(
self
.param_substs
,
&
callee_ty
);
let
constness
=
match
(
self
.const_context
,
&
callee_ty
.sty
)
{
(
true
,
&
ty
::
TyFnDef
(
def_id
,
substs
))
if
self
.tcx
.is_const_fn
(
def_id
)
=>
{
let
instance
=
ty
::
Instance
::
resolve
(
self
.tcx
,
ty
::
ParamEnv
::
empty
(
traits
::
Reveal
::
All
),
def_id
,
substs
)
.unwrap
();
Some
(
instance
)
}
_
=>
None
};
if
let
Some
(
const_fn_instance
)
=
constness
{
// If this is a const fn, called from a const context, we
// have to visit its body in order to find any fn reifications
// it might contain.
collect_neighbours
(
self
.tcx
,
const_fn_instance
,
true
,
self
.output
);
}
else
{
visit_fn_use
(
self
.tcx
,
callee_ty
,
true
,
&
mut
self
.output
);
}
visit_fn_use
(
self
.tcx
,
callee_ty
,
true
,
&
mut
self
.output
);
}
mir
::
TerminatorKind
::
Drop
{
ref
location
,
..
}
|
mir
::
TerminatorKind
::
DropAndReplace
{
ref
location
,
..
}
=>
{
...
...
@@ -1117,7 +1086,14 @@ fn collect_miri<'a, 'tcx>(
alloc_id
:
AllocId
,
output
:
&
mut
Vec
<
MonoItem
<
'tcx
>>
,
)
{
if
let
Some
(
alloc
)
=
tcx
.interpret_interner
.get_alloc
(
alloc_id
)
{
if
let
Some
(
did
)
=
tcx
.interpret_interner
.get_corresponding_static_def_id
(
alloc_id
)
{
let
instance
=
Instance
::
mono
(
tcx
,
did
);
if
should_monomorphize_locally
(
tcx
,
&
instance
)
{
trace!
(
"collecting static {:?}"
,
did
);
let
node_id
=
tcx
.hir
.as_local_node_id
(
did
)
.unwrap
();
output
.push
(
MonoItem
::
Static
(
node_id
));
}
}
else
if
let
Some
(
alloc
)
=
tcx
.interpret_interner
.get_alloc
(
alloc_id
)
{
trace!
(
"collecting {:?} with {:#?}"
,
alloc_id
,
alloc
);
for
&
inner
in
alloc
.relocations
.values
()
{
collect_miri
(
tcx
,
inner
,
output
);
...
...
@@ -1135,23 +1111,29 @@ fn collect_miri<'a, 'tcx>(
/// Scan the MIR in order to find function calls, closures, and drop-glue
fn
collect_neighbours
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
instance
:
Instance
<
'tcx
>
,
const_context
:
bool
,
output
:
&
mut
Vec
<
MonoItem
<
'tcx
>>
)
{
let
mir
=
tcx
.instance_mir
(
instance
.def
);
let
mut
visitor
=
MirNeighborCollector
{
MirNeighborCollector
{
tcx
,
mir
:
&
mir
,
output
,
param_substs
:
instance
.substs
,
const_context
,
};
visitor
.visit_mir
(
&
mir
);
for
promoted
in
&
mir
.promoted
{
visitor
.mir
=
promoted
;
visitor
.visit_mir
(
promoted
);
}
.visit_mir
(
&
mir
);
let
param_env
=
ty
::
ParamEnv
::
empty
(
traits
::
Reveal
::
All
);
for
(
i
,
promoted
)
in
mir
.promoted
.iter
()
.enumerate
()
{
use
rustc_data_structures
::
indexed_vec
::
Idx
;
let
cid
=
GlobalId
{
instance
,
promoted
:
Some
(
Promoted
::
new
(
i
)),
};
match
tcx
.const_eval
(
param_env
.and
(
cid
))
{
Ok
(
val
)
=>
collect_const
(
tcx
,
val
,
instance
.substs
,
output
),
Err
(
err
)
=>
{
err
.report
(
tcx
,
promoted
.span
,
"promoted"
);
}
}
}
}
...
...
@@ -1163,3 +1145,60 @@ fn def_id_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
printer
.push_def_path
(
def_id
,
&
mut
output
);
output
}
fn
collect_const
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
constant
:
&
ty
::
Const
<
'tcx
>
,
param_substs
:
&
'tcx
Substs
<
'tcx
>
,
output
:
&
mut
Vec
<
MonoItem
<
'tcx
>>
,
)
{
debug!
(
"visiting const {:?}"
,
*
constant
);
let
val
=
match
constant
.val
{
ConstVal
::
Unevaluated
(
def_id
,
substs
)
=>
{
let
param_env
=
ty
::
ParamEnv
::
empty
(
traits
::
Reveal
::
All
);
let
substs
=
tcx
.trans_apply_param_substs
(
param_substs
,
&
substs
);
let
instance
=
ty
::
Instance
::
resolve
(
tcx
,
param_env
,
def_id
,
substs
)
.unwrap
();
let
cid
=
GlobalId
{
instance
,
promoted
:
None
,
};
match
tcx
.const_eval
(
param_env
.and
(
cid
))
{
Ok
(
val
)
=>
val
.val
,
Err
(
err
)
=>
{
let
span
=
tcx
.def_span
(
def_id
);
err
.report
(
tcx
,
span
,
"constant"
);
return
;
}
}
},
_
=>
constant
.val
,
};
match
val
{
ConstVal
::
Unevaluated
(
..
)
=>
bug!
(
"const eval yielded unevaluated const"
),
ConstVal
::
Value
(
Value
::
ByValPair
(
PrimVal
::
Ptr
(
a
),
PrimVal
::
Ptr
(
b
)))
=>
{
collect_miri
(
tcx
,
a
.alloc_id
,
output
);
collect_miri
(
tcx
,
b
.alloc_id
,
output
);
}
ConstVal
::
Value
(
Value
::
ByValPair
(
_
,
PrimVal
::
Ptr
(
ptr
)))
|
ConstVal
::
Value
(
Value
::
ByValPair
(
PrimVal
::
Ptr
(
ptr
),
_
))
|
ConstVal
::
Value
(
Value
::
ByVal
(
PrimVal
::
Ptr
(
ptr
)))
=>
collect_miri
(
tcx
,
ptr
.alloc_id
,
output
),
ConstVal
::
Value
(
Value
::
ByRef
(
Pointer
{
primval
:
PrimVal
::
Ptr
(
ptr
)
},
_
))
=>
{
// by ref should only collect the inner allocation, not the value itself
let
alloc
=
tcx
.interpret_interner
.get_alloc
(
ptr
.alloc_id
)
.expect
(
"ByRef to extern static is not allowed"
);
for
&
inner
in
alloc
.relocations
.values
()
{
collect_miri
(
tcx
,
inner
,
output
);
}
}
_
=>
{},
}
}
src/librustc_trans/base.rs
浏览文件 @
5b247b9b
...
...
@@ -972,6 +972,8 @@ fn collect_and_partition_translation_items<'a, 'tcx>(
collector
::
collect_crate_mono_items
(
tcx
,
collection_mode
)
});
tcx
.sess
.abort_if_errors
();
::
rustc_mir
::
monomorphize
::
assert_symbols_are_distinct
(
tcx
,
items
.iter
());
let
strategy
=
if
tcx
.sess.opts.incremental
.is_some
()
{
...
...
src/test/compile-fail/huge-array.rs
浏览文件 @
5b247b9b
...
...
@@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:; 1518
599999
// error-pattern:; 1518
600000
fn
generic
<
T
:
Copy
>
(
t
:
T
)
{
let
s
:
[
T
;
1518600000
]
=
[
t
;
1518600000
];
...
...
src/test/ui/const-eval/index_out_of_bound.rs
浏览文件 @
5b247b9b
...
...
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
static
FOO
:
i32
=
[][
0
];
//~ ERROR E0080
static
FOO
:
i32
=
[][
0
];
//~^ ERROR E0080
//~| ERROR E0080
fn
main
()
{}
src/test/ui/const-fn-error.stderr
浏览文件 @
5b247b9b
...
...
@@ -20,15 +20,23 @@ error[E0016]: blocks in constant functions are limited to items and tail express
| ^
error[E0015]: calls in constant functions are limited to constant functions, struct and enum constructors
--> $DIR/const-fn-error.rs:1
7
:14
--> $DIR/const-fn-error.rs:1
8
:14
|
<<<<<<< HEAD
LL | for i in 0..x { //~ ERROR calls in constant functions
=======
18 | for i in 0..x {
>>>>>>> Report errors in statics during collecting instead of translating
| ^^^^
error[E0019]: constant function contains unimplemented expression type
--> $DIR/const-fn-error.rs:1
7
:14
--> $DIR/const-fn-error.rs:1
8
:14
|
<<<<<<< HEAD
LL | for i in 0..x { //~ ERROR calls in constant functions
=======
18 | for i in 0..x {
>>>>>>> Report errors in statics during collecting instead of translating
| ^^^^
error[E0080]: constant evaluation error
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录