Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
8a9b78f5
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,发现更多精彩内容 >>
提交
8a9b78f5
编写于
8月 05, 2017
作者:
E
Eduard-Mihai Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc: use ty::Const for the length of TyArray.
上级
3ce31eb9
变更
34
隐藏空白更改
内联
并排
Showing
34 changed file
with
215 addition
and
60 deletion
+215
-60
src/librustc/middle/const_val.rs
src/librustc/middle/const_val.rs
+11
-6
src/librustc/middle/mem_categorization.rs
src/librustc/middle/mem_categorization.rs
+1
-1
src/librustc/mir/tcx.rs
src/librustc/mir/tcx.rs
+3
-2
src/librustc/ty/context.rs
src/librustc/ty/context.rs
+10
-2
src/librustc/ty/error.rs
src/librustc/ty/error.rs
+10
-3
src/librustc/ty/flags.rs
src/librustc/ty/flags.rs
+37
-1
src/librustc/ty/inhabitedness/mod.rs
src/librustc/ty/inhabitedness/mod.rs
+1
-1
src/librustc/ty/layout.rs
src/librustc/ty/layout.rs
+2
-2
src/librustc/ty/relate.rs
src/librustc/ty/relate.rs
+7
-3
src/librustc/ty/structural_impls.rs
src/librustc/ty/structural_impls.rs
+2
-2
src/librustc/ty/sty.rs
src/librustc/ty/sty.rs
+1
-3
src/librustc/ty/util.rs
src/librustc/ty/util.rs
+3
-1
src/librustc/ty/walk.rs
src/librustc/ty/walk.rs
+37
-6
src/librustc/ty/wf.rs
src/librustc/ty/wf.rs
+11
-2
src/librustc/util/ppaux.rs
src/librustc/util/ppaux.rs
+14
-1
src/librustc_const_eval/_match.rs
src/librustc_const_eval/_match.rs
+7
-4
src/librustc_const_eval/eval.rs
src/librustc_const_eval/eval.rs
+8
-3
src/librustc_const_eval/pattern.rs
src/librustc_const_eval/pattern.rs
+2
-1
src/librustc_mir/shim.rs
src/librustc_mir/shim.rs
+4
-1
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/qualify_consts.rs
+2
-1
src/librustc_mir/transform/type_check.rs
src/librustc_mir/transform/type_check.rs
+1
-1
src/librustc_trans/base.rs
src/librustc_trans/base.rs
+3
-1
src/librustc_trans/debuginfo/metadata.rs
src/librustc_trans/debuginfo/metadata.rs
+2
-1
src/librustc_trans/debuginfo/type_names.rs
src/librustc_trans/debuginfo/type_names.rs
+1
-1
src/librustc_trans/mir/constant.rs
src/librustc_trans/mir/constant.rs
+3
-1
src/librustc_trans/mir/lvalue.rs
src/librustc_trans/mir/lvalue.rs
+3
-1
src/librustc_trans/mir/rvalue.rs
src/librustc_trans/mir/rvalue.rs
+2
-1
src/librustc_trans/trans_item.rs
src/librustc_trans/trans_item.rs
+2
-1
src/librustc_trans/type_of.rs
src/librustc_trans/type_of.rs
+2
-1
src/librustc_typeck/astconv.rs
src/librustc_typeck/astconv.rs
+1
-1
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/_match.rs
+1
-1
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+4
-1
src/librustdoc/clean/mod.rs
src/librustdoc/clean/mod.rs
+16
-2
src/librustdoc/lib.rs
src/librustdoc/lib.rs
+1
-0
未找到文件。
src/librustc/middle/const_val.rs
浏览文件 @
8a9b78f5
...
...
@@ -247,18 +247,23 @@ pub fn report(&self,
}
/// Returns the value of the length-valued expression
pub
fn
eval_length
(
tcx
:
TyCtxt
,
count
:
hir
::
BodyId
,
reason
:
&
str
)
->
Result
<
ConstUsize
,
ErrorReported
>
pub
fn
eval_length
<
'a
,
'gcx
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'gcx
,
'tcx
>
,
count
:
hir
::
BodyId
,
reason
:
&
str
)
->
Result
<&
'gcx
ty
::
Const
<
'gcx
>
,
ErrorReported
>
{
let
count_expr
=
&
tcx
.hir
.body
(
count
)
.value
;
let
count_def_id
=
tcx
.hir
.body_owner_def_id
(
count
);
let
param_env
=
ty
::
ParamEnv
::
empty
(
Reveal
::
UserFacing
);
let
substs
=
Substs
::
identity_for_item
(
tcx
.global_tcx
(),
count_def_id
);
match
tcx
.at
(
count_expr
.span
)
.const_eval
(
param_env
.and
((
count_def_id
,
substs
)))
{
Ok
(
&
ty
::
Const
{
val
:
Integral
(
Usize
(
count
)),
..
})
=>
Ok
(
count
),
Ok
(
_
)
|
Err
(
ConstEvalErr
{
kind
:
ErrKind
::
TypeckError
,
..
})
=>
Err
(
ErrorReported
),
Ok
(
count
)
=>
{
// Elsewhere in the compiler this is enforced even in the presence
// of erroneous code (type mismatch error has already been emitted).
assert_eq!
(
count
.ty
,
tcx
.types.usize
);
Ok
(
count
)
}
Err
(
ConstEvalErr
{
kind
:
ErrKind
::
TypeckError
,
..
})
=>
Err
(
ErrorReported
),
Err
(
err
)
=>
{
let
mut
diag
=
err
.struct_error
(
tcx
,
count_expr
.span
,
reason
);
...
...
src/librustc/middle/mem_categorization.rs
浏览文件 @
8a9b78f5
...
...
@@ -876,7 +876,7 @@ pub fn cat_rvalue_node(&self,
// Always promote `[T; 0]` (even when e.g. borrowed mutably).
let
promotable
=
match
expr_ty
.sty
{
ty
::
TyArray
(
_
,
len
)
if
len
.
as_u64
()
==
0
=>
true
,
ty
::
TyArray
(
_
,
len
)
if
len
.
val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
()
==
0
=>
true
,
_
=>
promotable
,
};
...
...
src/librustc/mir/tcx.rs
浏览文件 @
8a9b78f5
...
...
@@ -70,7 +70,8 @@ pub fn projection_ty(self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
LvalueTy
::
Ty
{
ty
:
match
ty
.sty
{
ty
::
TyArray
(
inner
,
size
)
=>
{
let
len
=
size
.as_u64
()
-
(
from
as
u64
)
-
(
to
as
u64
);
let
size
=
size
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
();
let
len
=
size
-
(
from
as
u64
)
-
(
to
as
u64
);
tcx
.mk_array
(
inner
,
len
)
}
ty
::
TySlice
(
..
)
=>
ty
,
...
...
@@ -148,7 +149,7 @@ pub fn ty<'a, 'gcx, D>(&self, local_decls: &D, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> T
match
*
self
{
Rvalue
::
Use
(
ref
operand
)
=>
operand
.ty
(
local_decls
,
tcx
),
Rvalue
::
Repeat
(
ref
operand
,
count
)
=>
{
tcx
.mk_array
(
operand
.ty
(
local_decls
,
tcx
),
count
.as_u64
()
)
tcx
.mk_array
_const_usize
(
operand
.ty
(
local_decls
,
tcx
),
count
)
}
Rvalue
::
Ref
(
reg
,
bk
,
ref
lv
)
=>
{
let
lv_ty
=
lv
.ty
(
local_decls
,
tcx
)
.to_ty
(
tcx
);
...
...
src/librustc/ty/context.rs
浏览文件 @
8a9b78f5
...
...
@@ -21,6 +21,7 @@
use
hir
::
map
::
DefPathHash
;
use
lint
::{
self
,
Lint
};
use
ich
::{
self
,
StableHashingContext
,
NodeIdHashingMode
};
use
middle
::
const_val
::
ConstVal
;
use
middle
::
free_region
::
FreeRegionMap
;
use
middle
::
lang_items
;
use
middle
::
resolve_lifetime
::{
self
,
ObjectLifetimeDefault
};
...
...
@@ -49,7 +50,7 @@
StableHasherResult
};
use
arena
::{
TypedArena
,
DroplessArena
};
use
rustc_const_math
::
ConstUsize
;
use
rustc_const_math
::
{
ConstInt
,
ConstUsize
}
;
use
rustc_data_structures
::
indexed_vec
::
IndexVec
;
use
std
::
borrow
::
Borrow
;
use
std
::
cell
::{
Cell
,
RefCell
};
...
...
@@ -1757,7 +1758,14 @@ pub fn mk_nil_ptr(self) -> Ty<'tcx> {
pub
fn
mk_array
(
self
,
ty
:
Ty
<
'tcx
>
,
n
:
u64
)
->
Ty
<
'tcx
>
{
let
n
=
ConstUsize
::
new
(
n
,
self
.sess.target.usize_ty
)
.unwrap
();
self
.mk_ty
(
TyArray
(
ty
,
n
))
self
.mk_array_const_usize
(
ty
,
n
)
}
pub
fn
mk_array_const_usize
(
self
,
ty
:
Ty
<
'tcx
>
,
n
:
ConstUsize
)
->
Ty
<
'tcx
>
{
self
.mk_ty
(
TyArray
(
ty
,
self
.mk_const
(
ty
::
Const
{
val
:
ConstVal
::
Integral
(
ConstInt
::
Usize
(
n
)),
ty
:
self
.types.usize
})))
}
pub
fn
mk_slice
(
self
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
...
...
src/librustc/ty/error.rs
浏览文件 @
8a9b78f5
...
...
@@ -10,6 +10,7 @@
use
hir
::
def_id
::
DefId
;
use
infer
::
type_variable
;
use
middle
::
const_val
::
ConstVal
;
use
ty
::{
self
,
BoundRegion
,
DefIdTree
,
Region
,
Ty
,
TyCtxt
};
use
std
::
fmt
;
...
...
@@ -18,7 +19,7 @@
use
errors
::
DiagnosticBuilder
;
use
syntax_pos
::
Span
;
use
rustc_const_math
::
Const
Usize
;
use
rustc_const_math
::
Const
Int
;
use
hir
;
...
...
@@ -36,7 +37,7 @@ pub enum TypeError<'tcx> {
AbiMismatch
(
ExpectedFound
<
abi
::
Abi
>
),
Mutability
,
TupleSize
(
ExpectedFound
<
usize
>
),
FixedArraySize
(
ExpectedFound
<
ConstUsize
>
),
FixedArraySize
(
ExpectedFound
<
u64
>
),
ArgCount
,
RegionsDoesNotOutlive
(
Region
<
'tcx
>
,
Region
<
'tcx
>
),
...
...
@@ -181,7 +182,13 @@ pub fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> String {
ty
::
TyTuple
(
ref
tys
,
_
)
if
tys
.is_empty
()
=>
self
.to_string
(),
ty
::
TyAdt
(
def
,
_
)
=>
format!
(
"{} `{}`"
,
def
.descr
(),
tcx
.item_path_str
(
def
.did
)),
ty
::
TyArray
(
_
,
n
)
=>
format!
(
"array of {} elements"
,
n
),
ty
::
TyArray
(
_
,
n
)
=>
{
if
let
ConstVal
::
Integral
(
ConstInt
::
Usize
(
n
))
=
n
.val
{
format!
(
"array of {} elements"
,
n
)
}
else
{
"array"
.to_string
()
}
}
ty
::
TySlice
(
_
)
=>
"slice"
.to_string
(),
ty
::
TyRawPtr
(
_
)
=>
"*-ptr"
.to_string
(),
ty
::
TyRef
(
region
,
tymut
)
=>
{
...
...
src/librustc/ty/flags.rs
浏览文件 @
8a9b78f5
...
...
@@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
middle
::
const_val
::{
ConstVal
,
ConstAggregate
};
use
ty
::
subst
::
Substs
;
use
ty
::{
self
,
Ty
,
TypeFlags
,
TypeFoldable
};
...
...
@@ -145,7 +146,12 @@ fn add_sty(&mut self, st: &ty::TypeVariants) {
self
.add_region
(
r
);
}
&
ty
::
TyArray
(
tt
,
_
)
|
&
ty
::
TySlice
(
tt
)
=>
{
&
ty
::
TyArray
(
tt
,
len
)
=>
{
self
.add_ty
(
tt
);
self
.add_const
(
len
);
}
&
ty
::
TySlice
(
tt
)
=>
{
self
.add_ty
(
tt
)
}
...
...
@@ -202,6 +208,36 @@ fn add_region(&mut self, r: ty::Region) {
}
}
fn
add_const
(
&
mut
self
,
constant
:
&
ty
::
Const
)
{
self
.add_ty
(
constant
.ty
);
match
constant
.val
{
ConstVal
::
Integral
(
_
)
|
ConstVal
::
Float
(
_
)
|
ConstVal
::
Str
(
_
)
|
ConstVal
::
ByteStr
(
_
)
|
ConstVal
::
Bool
(
_
)
|
ConstVal
::
Char
(
_
)
|
ConstVal
::
Variant
(
_
)
=>
{}
ConstVal
::
Function
(
_
,
substs
)
=>
{
self
.add_substs
(
substs
);
}
ConstVal
::
Aggregate
(
ConstAggregate
::
Struct
(
fields
))
=>
{
for
&
(
_
,
v
)
in
fields
{
self
.add_const
(
v
);
}
}
ConstVal
::
Aggregate
(
ConstAggregate
::
Tuple
(
fields
))
|
ConstVal
::
Aggregate
(
ConstAggregate
::
Array
(
fields
))
=>
{
for
v
in
fields
{
self
.add_const
(
v
);
}
}
ConstVal
::
Aggregate
(
ConstAggregate
::
Repeat
(
v
,
_
))
=>
{
self
.add_const
(
v
);
}
}
}
fn
add_existential_projection
(
&
mut
self
,
projection
:
&
ty
::
ExistentialProjection
)
{
self
.add_substs
(
projection
.substs
);
self
.add_ty
(
projection
.ty
);
...
...
src/librustc/ty/inhabitedness/mod.rs
浏览文件 @
8a9b78f5
...
...
@@ -205,7 +205,7 @@ fn uninhabited_from_inner(
}))
},
TyArray
(
ty
,
len
)
=>
{
if
len
.
as_u64
()
==
0
{
if
len
.
val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
()
==
0
{
DefIdForest
::
empty
()
}
else
{
ty
.uninhabited_from
(
visited
,
tcx
)
...
...
src/librustc/ty/layout.rs
浏览文件 @
8a9b78f5
...
...
@@ -837,7 +837,7 @@ fn non_zero_field_in_type(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Is this a fixed-size array of something non-zero
// with at least one element?
(
_
,
&
ty
::
TyArray
(
ety
,
d
))
if
d
.
as_u64
()
>
0
=>
{
(
_
,
&
ty
::
TyArray
(
ety
,
d
))
if
d
.
val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
()
!=
0
=>
{
Struct
::
non_zero_field_paths
(
tcx
,
param_env
,
...
...
@@ -1177,7 +1177,7 @@ pub fn compute_uncached(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ty
::
TyArray
(
element
,
count
)
=>
{
let
element
=
element
.layout
(
tcx
,
param_env
)
?
;
let
element_size
=
element
.size
(
dl
);
let
count
=
count
.
as_u64
();
let
count
=
count
.
val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
();
if
element_size
.checked_mul
(
count
,
dl
)
.is_none
()
{
return
Err
(
LayoutError
::
SizeOverflow
(
ty
));
}
...
...
src/librustc/ty/relate.rs
浏览文件 @
8a9b78f5
...
...
@@ -428,10 +428,14 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
(
&
ty
::
TyArray
(
a_t
,
sz_a
),
&
ty
::
TyArray
(
b_t
,
sz_b
))
=>
{
let
t
=
relation
.relate
(
&
a_t
,
&
b_t
)
?
;
if
sz_a
==
sz_b
{
Ok
(
tcx
.mk_array
(
t
,
sz_a
.as_u64
()))
assert_eq!
(
sz_a
.ty
,
tcx
.types.usize
);
assert_eq!
(
sz_b
.ty
,
tcx
.types.usize
);
let
sz_a_u64
=
sz_a
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
();
let
sz_b_u64
=
sz_b
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
();
if
sz_a_u64
==
sz_b_u64
{
Ok
(
tcx
.mk_ty
(
ty
::
TyArray
(
t
,
sz_a
)))
}
else
{
Err
(
TypeError
::
FixedArraySize
(
expected_found
(
relation
,
&
sz_a
,
&
sz_b
)))
Err
(
TypeError
::
FixedArraySize
(
expected_found
(
relation
,
&
sz_a
_u64
,
&
sz_b_u64
)))
}
}
...
...
src/librustc/ty/structural_impls.rs
浏览文件 @
8a9b78f5
...
...
@@ -552,7 +552,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
fn
super_fold_with
<
'gcx
:
'tcx
,
F
:
TypeFolder
<
'gcx
,
'tcx
>>
(
&
self
,
folder
:
&
mut
F
)
->
Self
{
let
sty
=
match
self
.sty
{
ty
::
TyRawPtr
(
tm
)
=>
ty
::
TyRawPtr
(
tm
.fold_with
(
folder
)),
ty
::
TyArray
(
typ
,
sz
)
=>
ty
::
TyArray
(
typ
.fold_with
(
folder
),
sz
),
ty
::
TyArray
(
typ
,
sz
)
=>
ty
::
TyArray
(
typ
.fold_with
(
folder
),
sz
.fold_with
(
folder
)
),
ty
::
TySlice
(
typ
)
=>
ty
::
TySlice
(
typ
.fold_with
(
folder
)),
ty
::
TyAdt
(
tid
,
substs
)
=>
ty
::
TyAdt
(
tid
,
substs
.fold_with
(
folder
)),
ty
::
TyDynamic
(
ref
trait_ty
,
ref
region
)
=>
...
...
@@ -590,7 +590,7 @@ fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Se
fn
super_visit_with
<
V
:
TypeVisitor
<
'tcx
>>
(
&
self
,
visitor
:
&
mut
V
)
->
bool
{
match
self
.sty
{
ty
::
TyRawPtr
(
ref
tm
)
=>
tm
.visit_with
(
visitor
),
ty
::
TyArray
(
typ
,
_
sz
)
=>
typ
.visit_with
(
visitor
),
ty
::
TyArray
(
typ
,
sz
)
=>
typ
.visit_with
(
visitor
)
||
sz
.visit_with
(
visitor
),
ty
::
TySlice
(
typ
)
=>
typ
.visit_with
(
visitor
),
ty
::
TyAdt
(
_
,
substs
)
=>
substs
.visit_with
(
visitor
),
ty
::
TyDynamic
(
ref
trait_ty
,
ref
reg
)
=>
...
...
src/librustc/ty/sty.rs
浏览文件 @
8a9b78f5
...
...
@@ -27,8 +27,6 @@
use
syntax
::
symbol
::
keywords
;
use
util
::
nodemap
::
FxHashMap
;
use
rustc_const_math
::
ConstUsize
;
use
serialize
;
use
hir
;
...
...
@@ -112,7 +110,7 @@ pub enum TypeVariants<'tcx> {
TyStr
,
/// An array with the given length. Written as `[T; n]`.
TyArray
(
Ty
<
'tcx
>
,
ConstUsize
),
TyArray
(
Ty
<
'tcx
>
,
&
'tcx
ty
::
Const
<
'tcx
>
),
/// The pointee of an array slice. Written as `[T]`.
TySlice
(
Ty
<
'tcx
>
),
...
...
src/librustc/ty/util.rs
浏览文件 @
8a9b78f5
...
...
@@ -697,7 +697,9 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
TyInt
(
i
)
=>
self
.hash
(
i
),
TyUint
(
u
)
=>
self
.hash
(
u
),
TyFloat
(
f
)
=>
self
.hash
(
f
),
TyArray
(
_
,
n
)
=>
self
.hash
(
n
),
TyArray
(
_
,
n
)
=>
{
self
.hash
(
n
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
())
}
TyRawPtr
(
m
)
|
TyRef
(
_
,
m
)
=>
self
.hash
(
m
.mutbl
),
TyClosure
(
def_id
,
_
)
|
...
...
src/librustc/ty/walk.rs
浏览文件 @
8a9b78f5
...
...
@@ -11,6 +11,7 @@
//! An iterator over the type substructure.
//! WARNING: this does not keep track of the region depth.
use
middle
::
const_val
::{
ConstVal
,
ConstAggregate
};
use
ty
::{
self
,
Ty
};
use
rustc_data_structures
::
small_vec
::
SmallVec
;
use
rustc_data_structures
::
accumulate_vec
::
IntoIter
as
AccIntoIter
;
...
...
@@ -83,7 +84,11 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
ty
::
TyBool
|
ty
::
TyChar
|
ty
::
TyInt
(
_
)
|
ty
::
TyUint
(
_
)
|
ty
::
TyFloat
(
_
)
|
ty
::
TyStr
|
ty
::
TyInfer
(
_
)
|
ty
::
TyParam
(
_
)
|
ty
::
TyNever
|
ty
::
TyError
=>
{
}
ty
::
TyArray
(
ty
,
_
)
|
ty
::
TySlice
(
ty
)
=>
{
ty
::
TyArray
(
ty
,
len
)
=>
{
push_const
(
stack
,
len
);
stack
.push
(
ty
);
}
ty
::
TySlice
(
ty
)
=>
{
stack
.push
(
ty
);
}
ty
::
TyRawPtr
(
ref
mt
)
|
ty
::
TyRef
(
_
,
ref
mt
)
=>
{
...
...
@@ -122,13 +127,39 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
ty
::
TyFnDef
(
_
,
substs
)
=>
{
stack
.extend
(
substs
.types
()
.rev
());
}
ty
::
TyFnPtr
(
ft
)
=>
{
push_sig_subtypes
(
stack
,
ft
);
ty
::
TyFnPtr
(
sig
)
=>
{
stack
.push
(
sig
.skip_binder
()
.output
());
stack
.extend
(
sig
.skip_binder
()
.inputs
()
.iter
()
.cloned
()
.rev
());
}
}
}
fn
push_sig_subtypes
<
'tcx
>
(
stack
:
&
mut
TypeWalkerStack
<
'tcx
>
,
sig
:
ty
::
PolyFnSig
<
'tcx
>
)
{
stack
.push
(
sig
.skip_binder
()
.output
());
stack
.extend
(
sig
.skip_binder
()
.inputs
()
.iter
()
.cloned
()
.rev
());
fn
push_const
<
'tcx
>
(
stack
:
&
mut
TypeWalkerStack
<
'tcx
>
,
constant
:
&
'tcx
ty
::
Const
<
'tcx
>
)
{
match
constant
.val
{
ConstVal
::
Integral
(
_
)
|
ConstVal
::
Float
(
_
)
|
ConstVal
::
Str
(
_
)
|
ConstVal
::
ByteStr
(
_
)
|
ConstVal
::
Bool
(
_
)
|
ConstVal
::
Char
(
_
)
|
ConstVal
::
Variant
(
_
)
=>
{}
ConstVal
::
Function
(
_
,
substs
)
=>
{
stack
.extend
(
substs
.types
()
.rev
());
}
ConstVal
::
Aggregate
(
ConstAggregate
::
Struct
(
fields
))
=>
{
for
&
(
_
,
v
)
in
fields
.iter
()
.rev
()
{
push_const
(
stack
,
v
);
}
}
ConstVal
::
Aggregate
(
ConstAggregate
::
Tuple
(
fields
))
|
ConstVal
::
Aggregate
(
ConstAggregate
::
Array
(
fields
))
=>
{
for
v
in
fields
.iter
()
.rev
()
{
push_const
(
stack
,
v
);
}
}
ConstVal
::
Aggregate
(
ConstAggregate
::
Repeat
(
v
,
_
))
=>
{
push_const
(
stack
,
v
);
}
}
stack
.push
(
constant
.ty
);
}
src/librustc/ty/wf.rs
浏览文件 @
8a9b78f5
...
...
@@ -207,6 +207,10 @@ fn compute_projection(&mut self, data: ty::ProjectionTy<'tcx>) {
}
}
/// Pushes the obligations required for a constant value to be WF
/// into `self.out`.
fn
compute_const
(
&
mut
self
,
_
constant
:
&
'tcx
ty
::
Const
<
'tcx
>
)
{}
fn
require_sized
(
&
mut
self
,
subty
:
Ty
<
'tcx
>
,
cause
:
traits
::
ObligationCauseCode
<
'tcx
>
)
{
if
!
subty
.has_escaping_regions
()
{
let
cause
=
self
.cause
(
cause
);
...
...
@@ -239,9 +243,14 @@ fn compute(&mut self, ty0: Ty<'tcx>) -> bool {
// WfScalar, WfParameter, etc
}
ty
::
TySlice
(
subty
)
|
ty
::
TyArray
(
subty
,
_
)
=>
{
ty
::
TySlice
(
subty
)
=>
{
self
.require_sized
(
subty
,
traits
::
SliceOrArrayElem
);
}
ty
::
TyArray
(
subty
,
len
)
=>
{
self
.require_sized
(
subty
,
traits
::
SliceOrArrayElem
);
assert_eq!
(
len
.ty
,
self
.infcx.tcx.types.usize
);
self
.compute_const
(
len
);
}
ty
::
TyTuple
(
ref
tys
,
_
)
=>
{
...
...
src/librustc/util/ppaux.rs
浏览文件 @
8a9b78f5
...
...
@@ -10,6 +10,7 @@
use
hir
::
def_id
::
DefId
;
use
hir
::
map
::
definitions
::
DefPathData
;
use
middle
::
const_val
::
ConstVal
;
use
middle
::
region
::{
self
,
BlockRemainder
};
use
ty
::
subst
::{
self
,
Subst
};
use
ty
::{
BrAnon
,
BrEnv
,
BrFresh
,
BrNamed
};
...
...
@@ -24,6 +25,7 @@
use
std
::
fmt
;
use
std
::
usize
;
use
rustc_const_math
::
ConstInt
;
use
syntax
::
abi
::
Abi
;
use
syntax
::
ast
::
CRATE_NODE_ID
;
use
syntax
::
symbol
::
Symbol
;
...
...
@@ -886,7 +888,18 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!
(
f
,
"]"
)
}),
TyArray
(
ty
,
sz
)
=>
write!
(
f
,
"[{}; {}]"
,
ty
,
sz
),
TyArray
(
ty
,
sz
)
=>
{
write!
(
f
,
"[{}; "
,
ty
)
?
;
match
sz
.val
{
ConstVal
::
Integral
(
ConstInt
::
Usize
(
sz
))
=>
{
write!
(
f
,
"{}"
,
sz
)
?
;
}
_
=>
{
write!
(
f
,
"{:?}"
,
sz
)
?
;
}
}
write!
(
f
,
"]"
)
}
TySlice
(
ty
)
=>
write!
(
f
,
"[{}]"
,
ty
)
}
}
...
...
src/librustc_const_eval/_match.rs
浏览文件 @
8a9b78f5
...
...
@@ -422,11 +422,12 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
(
0
..
pcx
.max_slice_length
+
1
)
.map
(|
length
|
Slice
(
length
))
.collect
()
}
}
ty
::
TyArray
(
ref
sub_ty
,
length
)
=>
{
if
length
.as_u64
()
>
0
&&
cx
.is_uninhabited
(
sub_ty
)
{
ty
::
TyArray
(
ref
sub_ty
,
len
)
=>
{
let
len
=
len
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
();
if
len
!=
0
&&
cx
.is_uninhabited
(
sub_ty
)
{
vec!
[]
}
else
{
vec!
[
Slice
(
len
gth
.as_u64
()
)]
vec!
[
Slice
(
len
)]
}
}
ty
::
TyAdt
(
def
,
substs
)
if
def
.is_enum
()
&&
def
.variants
.len
()
!=
1
=>
{
...
...
@@ -729,7 +730,9 @@ fn pat_constructors<'tcx>(_cx: &mut MatchCheckCtxt,
PatternKind
::
Range
{
lo
,
hi
,
end
}
=>
Some
(
vec!
[
ConstantRange
(
lo
,
hi
,
end
)]),
PatternKind
::
Array
{
..
}
=>
match
pcx
.ty.sty
{
ty
::
TyArray
(
_
,
length
)
=>
Some
(
vec!
[
Slice
(
length
.as_u64
())]),
ty
::
TyArray
(
_
,
length
)
=>
Some
(
vec!
[
Slice
(
length
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
())
]),
_
=>
span_bug!
(
pat
.span
,
"bad ty {:?} for array pattern"
,
pcx
.ty
)
},
PatternKind
::
Slice
{
ref
prefix
,
ref
slice
,
ref
suffix
}
=>
{
...
...
src/librustc_const_eval/eval.rs
浏览文件 @
8a9b78f5
...
...
@@ -456,7 +456,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
}
hir
::
ExprRepeat
(
ref
elem
,
_
)
=>
{
let
n
=
match
ty
.sty
{
ty
::
TyArray
(
_
,
n
)
=>
n
.
as_u64
(),
ty
::
TyArray
(
_
,
n
)
=>
n
.
val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
(),
_
=>
span_bug!
(
e
.span
,
"typeck error"
)
};
mk_const
(
Aggregate
(
Repeat
(
cx
.eval
(
elem
)
?
,
n
)))
...
...
@@ -635,8 +635,13 @@ fn cast_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Err
(
ErrKind
::
UnimplementedConstVal
(
"casting a bytestr to a raw ptr"
))
},
ty
::
TyRef
(
_
,
ty
::
TypeAndMut
{
ref
ty
,
mutbl
:
hir
::
MutImmutable
})
=>
match
ty
.sty
{
ty
::
TyArray
(
ty
,
n
)
if
ty
==
tcx
.types.u8
&&
n
.as_u64
()
==
b
.data
.len
()
as
u64
=>
{
Ok
(
val
)
ty
::
TyArray
(
ty
,
n
)
=>
{
let
n
=
n
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
();
if
ty
==
tcx
.types.u8
&&
n
==
b
.data
.len
()
as
u64
{
Ok
(
val
)
}
else
{
Err
(
CannotCast
)
}
}
ty
::
TySlice
(
_
)
=>
{
Err
(
ErrKind
::
UnimplementedConstVal
(
"casting a bytestr to slice"
))
...
...
src/librustc_const_eval/pattern.rs
浏览文件 @
8a9b78f5
...
...
@@ -537,7 +537,8 @@ fn slice_or_array_pattern(
ty
::
TyArray
(
_
,
len
)
=>
{
// fixed-length array
assert
!
(
len
.as_u64
()
>=
prefix
.len
()
as
u64
+
suffix
.len
()
as
u64
);
let
len
=
len
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
();
assert
!
(
len
>=
prefix
.len
()
as
u64
+
suffix
.len
()
as
u64
);
PatternKind
::
Array
{
prefix
:
prefix
,
slice
:
slice
,
suffix
:
suffix
}
}
...
...
src/librustc_mir/shim.rs
浏览文件 @
8a9b78f5
...
...
@@ -292,7 +292,10 @@ fn build_clone_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
match
self_ty
.sty
{
_
if
is_copy
=>
builder
.copy_shim
(),
ty
::
TyArray
(
ty
,
len
)
=>
builder
.array_shim
(
ty
,
len
.as_u64
()),
ty
::
TyArray
(
ty
,
len
)
=>
{
let
len
=
len
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
();
builder
.array_shim
(
ty
,
len
)
}
ty
::
TyTuple
(
tys
,
_
)
=>
builder
.tuple_shim
(
tys
),
_
=>
{
bug!
(
"clone shim for `{:?}` which is not `Copy` and is not an aggregate"
,
self_ty
);
...
...
src/librustc_mir/transform/qualify_consts.rs
浏览文件 @
8a9b78f5
...
...
@@ -696,7 +696,8 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
_
=>
false
}
}
else
if
let
ty
::
TyArray
(
_
,
len
)
=
ty
.sty
{
len
.as_u64
()
==
0
&&
self
.mode
==
Mode
::
Fn
len
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
()
==
0
&&
self
.mode
==
Mode
::
Fn
}
else
{
false
};
...
...
src/librustc_mir/transform/type_check.rs
浏览文件 @
8a9b78f5
...
...
@@ -209,7 +209,7 @@ fn sanitize_projection(&mut self,
LvalueTy
::
Ty
{
ty
:
match
base_ty
.sty
{
ty
::
TyArray
(
inner
,
size
)
=>
{
let
size
=
size
.
as_u64
();
let
size
=
size
.
val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
();
let
min_size
=
(
from
as
u64
)
+
(
to
as
u64
);
if
let
Some
(
rest_size
)
=
size
.checked_sub
(
min_size
)
{
tcx
.mk_array
(
inner
,
rest_size
)
...
...
src/librustc_trans/base.rs
浏览文件 @
8a9b78f5
...
...
@@ -201,7 +201,9 @@ pub fn unsized_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>,
->
ValueRef
{
let
(
source
,
target
)
=
ccx
.tcx
()
.struct_lockstep_tails
(
source
,
target
);
match
(
&
source
.sty
,
&
target
.sty
)
{
(
&
ty
::
TyArray
(
_
,
len
),
&
ty
::
TySlice
(
_
))
=>
C_usize
(
ccx
,
len
.as_u64
()),
(
&
ty
::
TyArray
(
_
,
len
),
&
ty
::
TySlice
(
_
))
=>
{
C_usize
(
ccx
,
len
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
())
}
(
&
ty
::
TyDynamic
(
..
),
&
ty
::
TyDynamic
(
..
))
=>
{
// For now, upcasts are limited to changes in marker
// traits, and hence never actually require an actual
...
...
src/librustc_trans/debuginfo/metadata.rs
浏览文件 @
8a9b78f5
...
...
@@ -530,7 +530,8 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
MetadataCreationResult
::
new
(
basic_type_metadata
(
cx
,
t
),
false
)
}
ty
::
TyArray
(
typ
,
len
)
=>
{
fixed_vec_metadata
(
cx
,
unique_type_id
,
typ
,
Some
(
len
.as_u64
()),
usage_site_span
)
let
len
=
len
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
();
fixed_vec_metadata
(
cx
,
unique_type_id
,
typ
,
Some
(
len
),
usage_site_span
)
}
ty
::
TySlice
(
typ
)
=>
{
fixed_vec_metadata
(
cx
,
unique_type_id
,
typ
,
None
,
usage_site_span
)
...
...
src/librustc_trans/debuginfo/type_names.rs
浏览文件 @
8a9b78f5
...
...
@@ -96,7 +96,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
ty
::
TyArray
(
inner_type
,
len
)
=>
{
output
.push
(
'['
);
push_debuginfo_type_name
(
cx
,
inner_type
,
true
,
output
);
output
.push_str
(
&
format!
(
"; {}"
,
len
));
output
.push_str
(
&
format!
(
"; {}"
,
len
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
()
));
output
.push
(
']'
);
},
ty
::
TySlice
(
inner_type
)
=>
{
...
...
src/librustc_trans/mir/constant.rs
浏览文件 @
8a9b78f5
...
...
@@ -200,7 +200,9 @@ fn to_const(&self, span: Span) -> Const<'tcx> {
pub
fn
len
<
'a
>
(
&
self
,
ccx
:
&
CrateContext
<
'a
,
'tcx
>
)
->
ValueRef
{
match
self
.ty.sty
{
ty
::
TyArray
(
_
,
n
)
=>
C_usize
(
ccx
,
n
.as_u64
()),
ty
::
TyArray
(
_
,
n
)
=>
{
C_usize
(
ccx
,
n
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
())
}
ty
::
TySlice
(
_
)
|
ty
::
TyStr
=>
{
assert
!
(
self
.llextra
!=
ptr
::
null_mut
());
self
.llextra
...
...
src/librustc_trans/mir/lvalue.rs
浏览文件 @
8a9b78f5
...
...
@@ -106,7 +106,9 @@ pub fn alloca(bcx: &Builder<'a, 'tcx>, ty: Ty<'tcx>, name: &str) -> LvalueRef<'t
pub
fn
len
(
&
self
,
ccx
:
&
CrateContext
<
'a
,
'tcx
>
)
->
ValueRef
{
let
ty
=
self
.ty
.to_ty
(
ccx
.tcx
());
match
ty
.sty
{
ty
::
TyArray
(
_
,
n
)
=>
common
::
C_usize
(
ccx
,
n
.as_u64
()),
ty
::
TyArray
(
_
,
n
)
=>
{
common
::
C_usize
(
ccx
,
n
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
())
}
ty
::
TySlice
(
_
)
|
ty
::
TyStr
=>
{
assert
!
(
self
.llextra
!=
ptr
::
null_mut
());
self
.llextra
...
...
src/librustc_trans/mir/rvalue.rs
浏览文件 @
8a9b78f5
...
...
@@ -521,7 +521,8 @@ fn evaluate_array_len(&mut self,
if
let
LocalRef
::
Operand
(
Some
(
op
))
=
self
.locals
[
index
]
{
if
common
::
type_is_zero_size
(
bcx
.ccx
,
op
.ty
)
{
if
let
ty
::
TyArray
(
_
,
n
)
=
op
.ty.sty
{
return
common
::
C_usize
(
bcx
.ccx
,
n
.as_u64
());
let
n
=
n
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
();
return
common
::
C_usize
(
bcx
.ccx
,
n
);
}
}
}
...
...
src/librustc_trans/trans_item.rs
浏览文件 @
8a9b78f5
...
...
@@ -446,7 +446,8 @@ pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String) {
ty
::
TyArray
(
inner_type
,
len
)
=>
{
output
.push
(
'['
);
self
.push_type_name
(
inner_type
,
output
);
write!
(
output
,
"; {}"
,
len
)
.unwrap
();
write!
(
output
,
"; {}"
,
len
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
())
.unwrap
();
output
.push
(
']'
);
},
ty
::
TySlice
(
inner_type
)
=>
{
...
...
src/librustc_trans/type_of.rs
浏览文件 @
8a9b78f5
...
...
@@ -149,7 +149,8 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
ty
::
TyArray
(
ty
,
size
)
=>
{
let
llty
=
in_memory_type_of
(
cx
,
ty
);
Type
::
array
(
&
llty
,
size
.as_u64
())
let
size
=
size
.val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
();
Type
::
array
(
&
llty
,
size
)
}
// Unsized slice types (and str) have the type of their element, and
...
...
src/librustc_typeck/astconv.rs
浏览文件 @
8a9b78f5
...
...
@@ -1083,7 +1083,7 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
}
hir
::
TyArray
(
ref
ty
,
length
)
=>
{
if
let
Ok
(
length
)
=
eval_length
(
tcx
,
length
,
"array length"
)
{
tcx
.mk_
array
(
self
.ast_ty_to_ty
(
&
ty
),
length
.as_u64
(
))
tcx
.mk_
ty
(
ty
::
TyArray
(
self
.ast_ty_to_ty
(
&
ty
),
length
))
}
else
{
self
.tcx
()
.types.err
}
...
...
src/librustc_typeck/check/_match.rs
浏览文件 @
8a9b78f5
...
...
@@ -264,7 +264,7 @@ pub fn check_pat_arg(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>, is_arg: boo
let
expected_ty
=
self
.structurally_resolved_type
(
pat
.span
,
expected
);
let
(
inner_ty
,
slice_ty
)
=
match
expected_ty
.sty
{
ty
::
TyArray
(
inner_ty
,
size
)
=>
{
let
size
=
size
.
as_u64
();
let
size
=
size
.
val
.to_const_int
()
.unwrap
()
.to_u64
()
.unwrap
();
let
min_len
=
before
.len
()
as
u64
+
after
.len
()
as
u64
;
if
slice
.is_none
()
{
if
min_len
!=
size
{
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
8a9b78f5
...
...
@@ -3923,7 +3923,10 @@ fn check_expr_kind(&self,
};
if
let
Ok
(
count
)
=
count
{
if
count
.as_u64
()
>
1
{
let
zero_or_one
=
count
.val
.to_const_int
()
.and_then
(|
count
|
{
count
.to_u64
()
.map
(|
count
|
count
<=
1
)
})
.unwrap_or
(
false
);
if
!
zero_or_one
{
// For [foo, ..n] where n > 1, `foo` must have
// Copy type:
let
lang_item
=
self
.tcx
.require_lang_item
(
lang_items
::
CopyTraitLangItem
);
...
...
src/librustdoc/clean/mod.rs
浏览文件 @
8a9b78f5
...
...
@@ -27,6 +27,7 @@
use
syntax
::
symbol
::
keywords
;
use
syntax_pos
::{
self
,
DUMMY_SP
,
Pos
};
use
rustc
::
middle
::
const_val
::
ConstVal
;
use
rustc
::
middle
::
privacy
::
AccessLevels
;
use
rustc
::
middle
::
resolve_lifetime
as
rl
;
use
rustc
::
middle
::
lang_items
;
...
...
@@ -40,6 +41,7 @@
use
rustc
::
hir
;
use
rustc_const_math
::
ConstInt
;
use
std
::{
mem
,
slice
,
vec
};
use
std
::
path
::
PathBuf
;
use
std
::
rc
::
Rc
;
...
...
@@ -1785,7 +1787,12 @@ fn clean(&self, cx: &DocContext) -> Type {
TyArray
(
ref
ty
,
length
)
=>
{
use
rustc
::
middle
::
const_val
::
eval_length
;
let
n
=
eval_length
(
cx
.tcx
,
length
,
"array length"
)
.unwrap
();
Array
(
box
ty
.clean
(
cx
),
n
.to_string
())
let
n
=
if
let
ConstVal
::
Integral
(
ConstInt
::
Usize
(
n
))
=
n
.val
{
n
.to_string
()
}
else
{
format!
(
"{:?}"
,
n
)
};
Array
(
box
ty
.clean
(
cx
),
n
)
},
TyTup
(
ref
tys
)
=>
Tuple
(
tys
.clean
(
cx
)),
TyPath
(
hir
::
QPath
::
Resolved
(
None
,
ref
path
))
=>
{
...
...
@@ -1895,7 +1902,14 @@ fn clean(&self, cx: &DocContext) -> Type {
ty
::
TyFloat
(
float_ty
)
=>
Primitive
(
float_ty
.into
()),
ty
::
TyStr
=>
Primitive
(
PrimitiveType
::
Str
),
ty
::
TySlice
(
ty
)
=>
Slice
(
box
ty
.clean
(
cx
)),
ty
::
TyArray
(
ty
,
n
)
=>
Array
(
box
ty
.clean
(
cx
),
n
.to_string
()),
ty
::
TyArray
(
ty
,
n
)
=>
{
let
n
=
if
let
ConstVal
::
Integral
(
ConstInt
::
Usize
(
n
))
=
n
.val
{
n
.to_string
()
}
else
{
format!
(
"{:?}"
,
n
)
};
Array
(
box
ty
.clean
(
cx
),
n
)
}
ty
::
TyRawPtr
(
mt
)
=>
RawPointer
(
mt
.mutbl
.clean
(
cx
),
box
mt
.ty
.clean
(
cx
)),
ty
::
TyRef
(
r
,
mt
)
=>
BorrowedRef
{
lifetime
:
r
.clean
(
cx
),
...
...
src/librustdoc/lib.rs
浏览文件 @
8a9b78f5
...
...
@@ -32,6 +32,7 @@
extern
crate
libc
;
extern
crate
rustc
;
extern
crate
rustc_data_structures
;
extern
crate
rustc_const_math
;
extern
crate
rustc_trans
;
extern
crate
rustc_driver
;
extern
crate
rustc_resolve
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录