Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
362123dd
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,发现更多精彩内容 >>
提交
362123dd
编写于
9月 26, 2020
作者:
O
Oliver Scherer
提交者:
oli
11月 04, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Split the "raw integer bytes" part out of `Scalar`
上级
56293097
变更
17
显示空白变更内容
内联
并排
Showing
17 changed file
with
325 addition
and
184 deletion
+325
-184
compiler/rustc_codegen_llvm/src/common.rs
compiler/rustc_codegen_llvm/src/common.rs
+4
-4
compiler/rustc_middle/src/lib.rs
compiler/rustc_middle/src/lib.rs
+1
-0
compiler/rustc_middle/src/mir/interpret/mod.rs
compiler/rustc_middle/src/mir/interpret/mod.rs
+1
-1
compiler/rustc_middle/src/mir/interpret/value.rs
compiler/rustc_middle/src/mir/interpret/value.rs
+21
-86
compiler/rustc_middle/src/mir/mod.rs
compiler/rustc_middle/src/mir/mod.rs
+3
-4
compiler/rustc_middle/src/ty/consts/int.rs
compiler/rustc_middle/src/ty/consts/int.rs
+227
-12
compiler/rustc_middle/src/ty/mod.rs
compiler/rustc_middle/src/ty/mod.rs
+1
-1
compiler/rustc_middle/src/ty/print/pretty.rs
compiler/rustc_middle/src/ty/print/pretty.rs
+24
-33
compiler/rustc_mir/src/const_eval/eval_queries.rs
compiler/rustc_mir/src/const_eval/eval_queries.rs
+2
-2
compiler/rustc_mir/src/const_eval/machine.rs
compiler/rustc_mir/src/const_eval/machine.rs
+5
-5
compiler/rustc_mir/src/interpret/operand.rs
compiler/rustc_mir/src/interpret/operand.rs
+6
-9
compiler/rustc_mir/src/interpret/place.rs
compiler/rustc_mir/src/interpret/place.rs
+2
-6
compiler/rustc_mir/src/transform/const_prop.rs
compiler/rustc_mir/src/transform/const_prop.rs
+4
-3
compiler/rustc_mir/src/transform/simplify_comparison_integral.rs
...r/rustc_mir/src/transform/simplify_comparison_integral.rs
+8
-4
src/librustdoc/clean/utils.rs
src/librustdoc/clean/utils.rs
+5
-4
src/test/ui/symbol-names/impl1.rs
src/test/ui/symbol-names/impl1.rs
+2
-2
src/tools/clippy/clippy_lints/src/consts.rs
src/tools/clippy/clippy_lints/src/consts.rs
+9
-8
未找到文件。
compiler/rustc_codegen_llvm/src/common.rs
浏览文件 @
362123dd
...
...
@@ -12,7 +12,7 @@
use
rustc_codegen_ssa
::
traits
::
*
;
use
rustc_middle
::
bug
;
use
rustc_middle
::
mir
::
interpret
::{
Allocation
,
GlobalAlloc
,
Scalar
};
use
rustc_middle
::
ty
::
layout
::
TyAndLayout
;
use
rustc_middle
::
ty
::
{
layout
::
TyAndLayout
,
ScalarInt
}
;
use
rustc_span
::
symbol
::
Symbol
;
use
rustc_target
::
abi
::{
self
,
AddressSpace
,
HasDataLayout
,
LayoutOf
,
Pointer
,
Size
};
...
...
@@ -230,12 +230,12 @@ fn const_to_opt_u128(&self, v: &'ll Value, sign_ext: bool) -> Option<u128> {
fn
scalar_to_backend
(
&
self
,
cv
:
Scalar
,
layout
:
&
abi
::
Scalar
,
llty
:
&
'll
Type
)
->
&
'll
Value
{
let
bitsize
=
if
layout
.is_bool
()
{
1
}
else
{
layout
.value
.size
(
self
)
.bits
()
};
match
cv
{
Scalar
::
Raw
{
size
:
0
,
..
}
=>
{
Scalar
::
Raw
(
ScalarInt
::
ZST
)
=>
{
assert_eq!
(
0
,
layout
.value
.size
(
self
)
.bytes
());
self
.const_undef
(
self
.type_ix
(
0
))
}
Scalar
::
Raw
{
data
,
size
}
=>
{
assert_eq!
(
size
as
u64
,
layout
.value
.size
(
self
)
.bytes
(
));
Scalar
::
Raw
(
int
)
=>
{
let
data
=
int
.assert_bits
(
layout
.value
.size
(
self
));
let
llval
=
self
.const_uint_big
(
self
.type_ix
(
bitsize
),
data
);
if
layout
.value
==
Pointer
{
unsafe
{
llvm
::
LLVMConstIntToPtr
(
llval
,
llty
)
}
...
...
compiler/rustc_middle/src/lib.rs
浏览文件 @
362123dd
...
...
@@ -24,6 +24,7 @@
#![doc(html_root_url
=
"https://doc.rust-lang.org/nightly/nightly-rustc/"
)]
#![feature(array_windows)]
#![feature(assoc_char_funcs)]
#![feature(backtrace)]
#![feature(bool_to_option)]
#![feature(box_patterns)]
...
...
compiler/rustc_middle/src/mir/interpret/mod.rs
浏览文件 @
362123dd
...
...
@@ -71,7 +71,7 @@
#[macro_export]
macro_rules!
throw_ub
{
(
$
(
$tt:tt
)
*
)
=>
{
Err
::
<!
,
_
>
(
err_ub!
(
$
(
$tt
)
*
))
?
};
(
$
(
$tt:tt
)
*
)
=>
{
Err
::
<!
,
_
>
(
$crate
::
err_ub!
(
$
(
$tt
)
*
))
?
};
}
#[macro_export]
...
...
compiler/rustc_middle/src/mir/interpret/value.rs
浏览文件 @
362123dd
...
...
@@ -8,9 +8,9 @@
use
rustc_macros
::
HashStable
;
use
rustc_target
::
abi
::{
HasDataLayout
,
Size
,
TargetDataLayout
};
use
crate
::
ty
::{
ParamEnv
,
Ty
,
TyCtxt
};
use
crate
::
ty
::{
ParamEnv
,
ScalarInt
,
Ty
,
TyCtxt
};
use
super
::{
sign_extend
,
truncate
,
AllocId
,
Allocation
,
InterpResult
,
Pointer
,
PointerArithmetic
};
use
super
::{
sign_extend
,
AllocId
,
Allocation
,
InterpResult
,
Pointer
,
PointerArithmetic
};
/// Represents the result of const evaluation via the `eval_to_allocation` query.
#[derive(Clone,
HashStable,
TyEncodable,
TyDecodable)]
...
...
@@ -103,12 +103,7 @@ pub fn from_machine_usize(i: u64, cx: &impl HasDataLayout) -> Self {
#[derive(HashStable)]
pub
enum
Scalar
<
Tag
=
()
>
{
/// The raw bytes of a simple value.
Raw
{
/// The first `size` bytes of `data` are the value.
/// Do not try to read less or more bytes than that. The remaining bytes must be 0.
data
:
u128
,
size
:
u8
,
},
Raw
(
ScalarInt
),
/// A pointer into an `Allocation`. An `Allocation` in the `memory` module has a list of
/// relocations, but a `Scalar` is only large enough to contain one, so we just represent the
...
...
@@ -125,16 +120,7 @@ impl<Tag: fmt::Debug> fmt::Debug for Scalar<Tag> {
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
<
'_
>
)
->
fmt
::
Result
{
match
self
{
Scalar
::
Ptr
(
ptr
)
=>
write!
(
f
,
"{:?}"
,
ptr
),
&
Scalar
::
Raw
{
data
,
size
}
=>
{
Scalar
::
check_data
(
data
,
size
);
if
size
==
0
{
write!
(
f
,
"<ZST>"
)
}
else
{
// Format as hex number wide enough to fit any value of the given `size`.
// So data=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014".
write!
(
f
,
"0x{:>0width$x}"
,
data
,
width
=
(
size
*
2
)
as
usize
)
}
}
Scalar
::
Raw
(
int
)
=>
write!
(
f
,
"{:?}"
,
int
),
}
}
}
...
...
@@ -163,21 +149,6 @@ fn from(f: Double) -> Self {
}
impl
Scalar
<
()
>
{
/// Make sure the `data` fits in `size`.
/// This is guaranteed by all constructors here, but since the enum variants are public,
/// it could still be violated (even though no code outside this file should
/// construct `Scalar`s).
#[inline(always)]
fn
check_data
(
data
:
u128
,
size
:
u8
)
{
debug_assert_eq!
(
truncate
(
data
,
Size
::
from_bytes
(
u64
::
from
(
size
))),
data
,
"Scalar value {:#x} exceeds size of {} bytes"
,
data
,
size
);
}
/// Tag this scalar with `new_tag` if it is a pointer, leave it unchanged otherwise.
///
/// Used by `MemPlace::replace_tag`.
...
...
@@ -185,7 +156,7 @@ fn check_data(data: u128, size: u8) {
pub
fn
with_tag
<
Tag
>
(
self
,
new_tag
:
Tag
)
->
Scalar
<
Tag
>
{
match
self
{
Scalar
::
Ptr
(
ptr
)
=>
Scalar
::
Ptr
(
ptr
.with_tag
(
new_tag
)),
Scalar
::
Raw
{
data
,
size
}
=>
Scalar
::
Raw
{
data
,
size
}
,
Scalar
::
Raw
(
int
)
=>
Scalar
::
Raw
(
int
)
,
}
}
}
...
...
@@ -198,18 +169,18 @@ impl<'tcx, Tag> Scalar<Tag> {
pub
fn
erase_tag
(
self
)
->
Scalar
{
match
self
{
Scalar
::
Ptr
(
ptr
)
=>
Scalar
::
Ptr
(
ptr
.erase_tag
()),
Scalar
::
Raw
{
data
,
size
}
=>
Scalar
::
Raw
{
data
,
size
}
,
Scalar
::
Raw
(
int
)
=>
Scalar
::
Raw
(
int
)
,
}
}
#[inline]
pub
fn
null_ptr
(
cx
:
&
impl
HasDataLayout
)
->
Self
{
Scalar
::
Raw
{
data
:
0
,
size
:
cx
.data_layout
()
.pointer_size
.bytes
()
as
u8
}
Scalar
::
Raw
(
ScalarInt
::
null
(
cx
.data_layout
()
.pointer_size
))
}
#[inline]
pub
fn
zst
()
->
Self
{
Scalar
::
Raw
{
data
:
0
,
size
:
0
}
Scalar
::
Raw
(
ScalarInt
::
zst
())
}
#[inline(always)]
...
...
@@ -220,10 +191,7 @@ fn ptr_op(
f_ptr
:
impl
FnOnce
(
Pointer
<
Tag
>
)
->
InterpResult
<
'tcx
,
Pointer
<
Tag
>>
,
)
->
InterpResult
<
'tcx
,
Self
>
{
match
self
{
Scalar
::
Raw
{
data
,
size
}
=>
{
assert_eq!
(
u64
::
from
(
size
),
dl
.pointer_size
.bytes
());
Ok
(
Scalar
::
Raw
{
data
:
u128
::
from
(
f_int
(
u64
::
try_from
(
data
)
.unwrap
())
?
),
size
})
}
Scalar
::
Raw
(
int
)
=>
Ok
(
Scalar
::
Raw
(
int
.ptr_sized_op
(
dl
,
f_int
)
?
)),
Scalar
::
Ptr
(
ptr
)
=>
Ok
(
Scalar
::
Ptr
(
f_ptr
(
ptr
)
?
)),
}
}
...
...
@@ -264,24 +232,17 @@ pub fn ptr_wrapping_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> Self
#[inline]
pub
fn
from_bool
(
b
:
bool
)
->
Self
{
// Guaranteed to be truncated and does not need sign extension.
Scalar
::
Raw
{
data
:
b
as
u128
,
size
:
1
}
Scalar
::
Raw
(
b
.into
())
}
#[inline]
pub
fn
from_char
(
c
:
char
)
->
Self
{
// Guaranteed to be truncated and does not need sign extension.
Scalar
::
Raw
{
data
:
c
as
u128
,
size
:
4
}
Scalar
::
Raw
(
c
.into
())
}
#[inline]
pub
fn
try_from_uint
(
i
:
impl
Into
<
u128
>
,
size
:
Size
)
->
Option
<
Self
>
{
let
i
=
i
.into
();
if
truncate
(
i
,
size
)
==
i
{
Some
(
Scalar
::
Raw
{
data
:
i
,
size
:
size
.bytes
()
as
u8
})
}
else
{
None
}
ScalarInt
::
try_from_uint
(
i
,
size
)
.map
(
Scalar
::
Raw
)
}
#[inline]
...
...
@@ -293,26 +254,22 @@ pub fn from_uint(i: impl Into<u128>, size: Size) -> Self {
#[inline]
pub
fn
from_u8
(
i
:
u8
)
->
Self
{
// Guaranteed to be truncated and does not need sign extension.
Scalar
::
Raw
{
data
:
i
.into
(),
size
:
1
}
Scalar
::
Raw
(
i
.into
())
}
#[inline]
pub
fn
from_u16
(
i
:
u16
)
->
Self
{
// Guaranteed to be truncated and does not need sign extension.
Scalar
::
Raw
{
data
:
i
.into
(),
size
:
2
}
Scalar
::
Raw
(
i
.into
())
}
#[inline]
pub
fn
from_u32
(
i
:
u32
)
->
Self
{
// Guaranteed to be truncated and does not need sign extension.
Scalar
::
Raw
{
data
:
i
.into
(),
size
:
4
}
Scalar
::
Raw
(
i
.into
())
}
#[inline]
pub
fn
from_u64
(
i
:
u64
)
->
Self
{
// Guaranteed to be truncated and does not need sign extension.
Scalar
::
Raw
{
data
:
i
.into
(),
size
:
8
}
Scalar
::
Raw
(
i
.into
())
}
#[inline]
...
...
@@ -322,14 +279,7 @@ pub fn from_machine_usize(i: u64, cx: &impl HasDataLayout) -> Self {
#[inline]
pub
fn
try_from_int
(
i
:
impl
Into
<
i128
>
,
size
:
Size
)
->
Option
<
Self
>
{
let
i
=
i
.into
();
// `into` performed sign extension, we have to truncate
let
truncated
=
truncate
(
i
as
u128
,
size
);
if
sign_extend
(
truncated
,
size
)
as
i128
==
i
{
Some
(
Scalar
::
Raw
{
data
:
truncated
,
size
:
size
.bytes
()
as
u8
})
}
else
{
None
}
ScalarInt
::
try_from_int
(
i
,
size
)
.map
(
Scalar
::
Raw
)
}
#[inline]
...
...
@@ -366,14 +316,12 @@ pub fn from_machine_isize(i: i64, cx: &impl HasDataLayout) -> Self {
#[inline]
pub
fn
from_f32
(
f
:
Single
)
->
Self
{
// We trust apfloat to give us properly truncated data.
Scalar
::
Raw
{
data
:
f
.to_bits
(),
size
:
4
}
Scalar
::
Raw
(
f
.into
())
}
#[inline]
pub
fn
from_f64
(
f
:
Double
)
->
Self
{
// We trust apfloat to give us properly truncated data.
Scalar
::
Raw
{
data
:
f
.to_bits
(),
size
:
8
}
Scalar
::
Raw
(
f
.into
())
}
/// This is very rarely the method you want! You should dispatch on the type
...
...
@@ -388,11 +336,7 @@ pub fn to_bits_or_ptr(
)
->
Result
<
u128
,
Pointer
<
Tag
>>
{
assert_ne!
(
target_size
.bytes
(),
0
,
"you should never look at the bits of a ZST"
);
match
self
{
Scalar
::
Raw
{
data
,
size
}
=>
{
assert_eq!
(
target_size
.bytes
(),
u64
::
from
(
size
));
Scalar
::
check_data
(
data
,
size
);
Ok
(
data
)
}
Scalar
::
Raw
(
int
)
=>
Ok
(
int
.assert_bits
(
target_size
)),
Scalar
::
Ptr
(
ptr
)
=>
{
assert_eq!
(
target_size
,
cx
.data_layout
()
.pointer_size
);
Err
(
ptr
)
...
...
@@ -406,16 +350,7 @@ pub fn to_bits_or_ptr(
fn
to_bits
(
self
,
target_size
:
Size
)
->
InterpResult
<
'tcx
,
u128
>
{
assert_ne!
(
target_size
.bytes
(),
0
,
"you should never look at the bits of a ZST"
);
match
self
{
Scalar
::
Raw
{
data
,
size
}
=>
{
if
target_size
.bytes
()
!=
u64
::
from
(
size
)
{
throw_ub!
(
ScalarSizeMismatch
{
target_size
:
target_size
.bytes
(),
data_size
:
u64
::
from
(
size
),
});
}
Scalar
::
check_data
(
data
,
size
);
Ok
(
data
)
}
Scalar
::
Raw
(
int
)
=>
int
.to_bits
(
target_size
),
Scalar
::
Ptr
(
_
)
=>
throw_unsup!
(
ReadPointerAsBytes
),
}
}
...
...
compiler/rustc_middle/src/mir/mod.rs
浏览文件 @
362123dd
...
...
@@ -28,7 +28,6 @@
use
rustc_serialize
::{
Decodable
,
Encodable
};
use
rustc_span
::
symbol
::
Symbol
;
use
rustc_span
::{
Span
,
DUMMY_SP
};
use
rustc_target
::
abi
;
use
rustc_target
::
asm
::
InlineAsmRegOrRegClass
;
use
std
::
borrow
::
Cow
;
use
std
::
fmt
::{
self
,
Debug
,
Display
,
Formatter
,
Write
};
...
...
@@ -1952,10 +1951,10 @@ pub fn const_from_scalar(
.layout_of
(
param_env_and_ty
)
.unwrap_or_else
(|
e
|
panic!
(
"could not compute layout for {:?}: {:?}"
,
ty
,
e
))
.size
;
let
scalar_size
=
abi
::
Size
::
from_bytes
(
match
val
{
Scalar
::
Raw
{
size
,
..
}
=>
size
,
let
scalar_size
=
match
val
{
Scalar
::
Raw
(
int
)
=>
int
.size
()
,
_
=>
panic!
(
"Invalid scalar type {:?}"
,
val
),
}
)
;
};
scalar_size
==
type_size
});
Operand
::
Constant
(
box
Constant
{
...
...
compiler/rustc_middle/src/ty/consts/int.rs
浏览文件 @
362123dd
use
crate
::
mir
::
interpret
::
truncate
;
use
rustc_target
::
abi
::
Size
;
use
crate
::
mir
::
interpret
::{
sign_extend
,
truncate
,
InterpErrorInfo
,
InterpResult
};
use
crate
::
throw_ub
;
use
rustc_apfloat
::
ieee
::{
Double
,
Single
};
use
rustc_apfloat
::
Float
;
use
rustc_macros
::
HashStable
;
use
rustc_target
::
abi
::{
Size
,
TargetDataLayout
};
use
std
::
convert
::{
TryFrom
,
TryInto
};
use
std
::
fmt
;
#[derive(Copy,
Clone)]
/// A type for representing any integer. Only used for printing.
// FIXME: Use this for the integer-tree representation needed for type level ints and
// const generics?
pub
struct
ConstInt
{
///
Number of bytes of the integer. Only 1, 2, 4, 8, 16 are legal values
.
size
:
u8
,
///
The "untyped" variant of `ConstInt`
.
int
:
ScalarInt
,
/// Whether the value is of a signed integer type.
signed
:
bool
,
/// Whether the value is a `usize` or `isize` type.
is_ptr_sized_integral
:
bool
,
/// Raw memory of the integer. All bytes beyond the `size` are unused and must be zero.
raw
:
u128
,
}
impl
ConstInt
{
pub
fn
new
(
raw
:
u128
,
size
:
Size
,
signed
:
bool
,
is_ptr_sized_integral
:
bool
)
->
Self
{
assert
!
(
raw
<=
truncate
(
u128
::
MAX
,
size
));
Self
{
raw
,
size
:
size
.bytes
()
as
u8
,
signed
,
is_ptr_sized_integral
}
pub
fn
new
(
int
:
ScalarInt
,
signed
:
bool
,
is_ptr_sized_integral
:
bool
)
->
Self
{
Self
{
int
,
signed
,
is_ptr_sized_integral
}
}
}
impl
std
::
fmt
::
Debug
for
ConstInt
{
fn
fmt
(
&
self
,
fmt
:
&
mut
std
::
fmt
::
Formatter
<
'_
>
)
->
std
::
fmt
::
Result
{
let
Self
{
size
,
signed
,
raw
,
is_ptr_sized_integral
}
=
*
self
;
let
Self
{
int
,
signed
,
is_ptr_sized_integral
}
=
*
self
;
let
size
=
int
.size
()
.bytes
();
let
raw
=
int
.data
();
if
signed
{
let
bit_size
=
size
*
8
;
let
min
=
1u128
<<
(
bit_size
-
1
);
...
...
@@ -109,3 +112,215 @@ fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
}
}
}
// FIXME: reuse in `super::int::ConstInt` and `Scalar::Bits`
/// The raw bytes of a simple value.
#[derive(Clone,
Copy,
Eq,
PartialEq,
Ord,
PartialOrd,
TyEncodable,
TyDecodable,
Hash)]
#[derive(HashStable)]
pub
struct
ScalarInt
{
/// The first `size` bytes of `data` are the value.
/// Do not try to read less or more bytes than that. The remaining bytes must be 0.
///
/// This is an array in order to allow this type to be optimally embedded in enums
/// (like Scalar).
bytes
:
[
u8
;
16
],
size
:
u8
,
}
impl
ScalarInt
{
pub
const
TRUE
:
ScalarInt
=
ScalarInt
{
bytes
:
1_u128
.to_ne_bytes
(),
size
:
1
};
pub
const
FALSE
:
ScalarInt
=
ScalarInt
{
bytes
:
0_u128
.to_ne_bytes
(),
size
:
1
};
pub
const
ZST
:
ScalarInt
=
ScalarInt
{
bytes
:
0_u128
.to_ne_bytes
(),
size
:
0
};
fn
data
(
self
)
->
u128
{
u128
::
from_ne_bytes
(
self
.bytes
)
}
#[inline]
pub
fn
size
(
self
)
->
Size
{
Size
::
from_bytes
(
self
.size
)
}
/// Make sure the `data` fits in `size`.
/// This is guaranteed by all constructors here, but since the enum variants are public,
/// it could still be violated (even though no code outside this file should
/// construct `Scalar`s).
#[inline(always)]
fn
check_data
(
self
)
{
debug_assert_eq!
(
truncate
(
self
.data
(),
self
.size
()),
self
.data
(),
"Scalar value {:#x} exceeds size of {} bytes"
,
self
.data
(),
self
.size
);
}
#[inline]
pub
fn
zst
()
->
Self
{
Self
::
null
(
Size
::
ZERO
)
}
#[inline]
pub
fn
null
(
size
:
Size
)
->
Self
{
Self
{
bytes
:
[
0
;
16
],
size
:
size
.bytes
()
as
u8
}
}
pub
(
crate
)
fn
ptr_sized_op
<
'tcx
>
(
self
,
dl
:
&
TargetDataLayout
,
f_int
:
impl
FnOnce
(
u64
)
->
InterpResult
<
'tcx
,
u64
>
,
)
->
InterpResult
<
'tcx
,
Self
>
{
assert_eq!
(
u64
::
from
(
self
.size
),
dl
.pointer_size
.bytes
());
Ok
(
Self
{
bytes
:
u128
::
from
(
f_int
(
u64
::
try_from
(
self
.data
())
.unwrap
())
?
)
.to_ne_bytes
(),
size
:
self
.size
,
})
}
#[inline]
pub
fn
try_from_uint
(
i
:
impl
Into
<
u128
>
,
size
:
Size
)
->
Option
<
Self
>
{
let
data
=
i
.into
();
if
truncate
(
data
,
size
)
==
data
{
Some
(
Self
{
bytes
:
data
.to_ne_bytes
(),
size
:
size
.bytes
()
as
u8
})
}
else
{
None
}
}
#[inline]
pub
fn
try_from_int
(
i
:
impl
Into
<
i128
>
,
size
:
Size
)
->
Option
<
Self
>
{
let
i
=
i
.into
();
// `into` performed sign extension, we have to truncate
let
truncated
=
truncate
(
i
as
u128
,
size
);
if
sign_extend
(
truncated
,
size
)
as
i128
==
i
{
Some
(
Self
{
bytes
:
truncated
.to_ne_bytes
(),
size
:
size
.bytes
()
as
u8
})
}
else
{
None
}
}
#[inline]
pub
fn
assert_bits
(
self
,
target_size
:
Size
)
->
u128
{
assert_ne!
(
target_size
.bytes
(),
0
,
"you should never look at the bits of a ZST"
);
assert_eq!
(
target_size
.bytes
(),
u64
::
from
(
self
.size
));
self
.check_data
();
self
.data
()
}
#[inline]
pub
fn
to_bits
(
self
,
target_size
:
Size
)
->
InterpResult
<
'static
,
u128
>
{
assert_ne!
(
target_size
.bytes
(),
0
,
"you should never look at the bits of a ZST"
);
if
target_size
.bytes
()
!=
u64
::
from
(
self
.size
)
{
throw_ub!
(
ScalarSizeMismatch
{
target_size
:
target_size
.bytes
(),
data_size
:
u64
::
from
(
self
.size
),
});
}
self
.check_data
();
Ok
(
self
.data
())
}
}
macro_rules!
from
{
(
$
(
$ty:ty
),
*
)
=>
{
$
(
impl
From
<
$ty
>
for
ScalarInt
{
#[inline]
fn
from
(
u
:
$ty
)
->
Self
{
Self
{
bytes
:
u128
::
from
(
u
)
.to_ne_bytes
(),
size
:
std
::
mem
::
size_of
::
<
$ty
>
()
as
u8
,
}
}
}
)
*
}
}
macro_rules!
try_from
{
(
$
(
$ty:ty
),
*
)
=>
{
$
(
impl
TryFrom
<
ScalarInt
>
for
$ty
{
type
Error
=
InterpErrorInfo
<
'static
>
;
#[inline]
fn
try_from
(
int
:
ScalarInt
)
->
InterpResult
<
'static
,
Self
>
{
int
.to_bits
(
Size
::
from_bytes
(
std
::
mem
::
size_of
::
<
$ty
>
()))
.map
(|
u
|
u
.try_into
()
.unwrap
())
}
}
)
*
}
}
from!
(
u8
,
u16
,
u32
,
u64
,
u128
,
bool
);
try_from!
(
u8
,
u16
,
u32
,
u64
,
u128
);
impl
From
<
char
>
for
ScalarInt
{
#[inline]
fn
from
(
c
:
char
)
->
Self
{
Self
{
bytes
:
(
c
as
u128
)
.to_ne_bytes
(),
size
:
std
::
mem
::
size_of
::
<
char
>
()
as
u8
}
}
}
impl
TryFrom
<
ScalarInt
>
for
char
{
type
Error
=
InterpErrorInfo
<
'static
>
;
#[inline]
fn
try_from
(
int
:
ScalarInt
)
->
InterpResult
<
'static
,
Self
>
{
int
.to_bits
(
Size
::
from_bytes
(
std
::
mem
::
size_of
::
<
char
>
()))
.map
(|
u
|
char
::
from_u32
(
u
.try_into
()
.unwrap
())
.unwrap
())
}
}
impl
From
<
Single
>
for
ScalarInt
{
#[inline]
fn
from
(
f
:
Single
)
->
Self
{
// We trust apfloat to give us properly truncated data.
Self
{
bytes
:
f
.to_bits
()
.to_ne_bytes
(),
size
:
4
}
}
}
impl
TryFrom
<
ScalarInt
>
for
Single
{
type
Error
=
InterpErrorInfo
<
'static
>
;
#[inline]
fn
try_from
(
int
:
ScalarInt
)
->
InterpResult
<
'static
,
Self
>
{
int
.to_bits
(
Size
::
from_bytes
(
4
))
.map
(
Self
::
from_bits
)
}
}
impl
From
<
Double
>
for
ScalarInt
{
#[inline]
fn
from
(
f
:
Double
)
->
Self
{
// We trust apfloat to give us properly truncated data.
Self
{
bytes
:
f
.to_bits
()
.to_ne_bytes
(),
size
:
8
}
}
}
impl
TryFrom
<
ScalarInt
>
for
Double
{
type
Error
=
InterpErrorInfo
<
'static
>
;
#[inline]
fn
try_from
(
int
:
ScalarInt
)
->
InterpResult
<
'static
,
Self
>
{
int
.to_bits
(
Size
::
from_bytes
(
8
))
.map
(
Self
::
from_bits
)
}
}
impl
fmt
::
Debug
for
ScalarInt
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
<
'_
>
)
->
fmt
::
Result
{
if
self
.size
==
0
{
self
.check_data
();
write!
(
f
,
"<ZST>"
)
}
else
{
write!
(
f
,
"0x{:x}"
,
self
)
}
}
}
impl
fmt
::
LowerHex
for
ScalarInt
{
fn
fmt
(
&
self
,
f
:
&
mut
fmt
::
Formatter
<
'_
>
)
->
fmt
::
Result
{
self
.check_data
();
// Format as hex number wide enough to fit any value of the given `size`.
// So data=20, size=1 will be "0x14", but with size=4 it'll be "0x00000014".
write!
(
f
,
"{:01$x}"
,
self
.data
(),
self
.size
as
usize
*
2
)
}
}
compiler/rustc_middle/src/ty/mod.rs
浏览文件 @
362123dd
...
...
@@ -87,7 +87,7 @@
pub
use
self
::
query
::
queries
;
pub
use
self
::
consts
::{
Const
,
ConstInt
,
ConstKind
,
InferConst
};
pub
use
self
::
consts
::{
Const
,
ConstInt
,
ConstKind
,
InferConst
,
ScalarInt
};
pub
mod
_
match
;
pub
mod
adjustment
;
...
...
compiler/rustc_middle/src/ty/print/pretty.rs
浏览文件 @
362123dd
use
crate
::
middle
::
cstore
::{
ExternCrate
,
ExternCrateSource
};
use
crate
::
mir
::
interpret
::{
AllocId
,
ConstValue
,
GlobalAlloc
,
Pointer
,
Scalar
};
use
crate
::
ty
::
layout
::
IntegerExt
;
use
crate
::
ty
::
subst
::{
GenericArg
,
GenericArgKind
,
Subst
};
use
crate
::
ty
::{
self
,
ConstInt
,
DefIdTree
,
ParamConst
,
Ty
,
TyCtxt
,
TypeFoldable
};
use
crate
::
ty
::{
self
,
ConstInt
,
DefIdTree
,
ParamConst
,
ScalarInt
,
Ty
,
TyCtxt
,
TypeFoldable
};
use
rustc_apfloat
::
ieee
::{
Double
,
Single
};
use
rustc_apfloat
::
Float
;
use
rustc_ast
as
ast
;
use
rustc_attr
::{
SignedInt
,
UnsignedInt
};
use
rustc_data_structures
::
fx
::
FxHashMap
;
use
rustc_hir
as
hir
;
use
rustc_hir
::
def
::{
self
,
CtorKind
,
DefKind
,
Namespace
};
...
...
@@ -15,12 +12,13 @@
use
rustc_hir
::
ItemKind
;
use
rustc_session
::
config
::
TrimmedDefPaths
;
use
rustc_span
::
symbol
::{
kw
,
Ident
,
Symbol
};
use
rustc_target
::
abi
::
{
Integer
,
Size
}
;
use
rustc_target
::
abi
::
Size
;
use
rustc_target
::
spec
::
abi
::
Abi
;
use
std
::
cell
::
Cell
;
use
std
::
char
;
use
std
::
collections
::
BTreeMap
;
use
std
::
convert
::
TryFrom
;
use
std
::
fmt
::{
self
,
Write
as
_
};
use
std
::
ops
::{
ControlFlow
,
Deref
,
DerefMut
};
...
...
@@ -960,11 +958,7 @@ fn pretty_print_const_scalar(
ty
::
Array
(
ty
::
TyS
{
kind
:
ty
::
Uint
(
ast
::
UintTy
::
U8
),
..
},
ty
::
Const
{
val
:
ty
::
ConstKind
::
Value
(
ConstValue
::
Scalar
(
Scalar
::
Raw
{
data
,
..
})),
val
:
ty
::
ConstKind
::
Value
(
ConstValue
::
Scalar
(
int
)),
..
},
),
...
...
@@ -974,8 +968,9 @@ fn pretty_print_const_scalar(
),
)
=>
match
self
.tcx
()
.get_global_alloc
(
ptr
.alloc_id
)
{
Some
(
GlobalAlloc
::
Memory
(
alloc
))
=>
{
if
let
Ok
(
byte_str
)
=
alloc
.get_bytes
(
&
self
.tcx
(),
ptr
,
Size
::
from_bytes
(
*
data
))
{
let
bytes
=
int
.assert_bits
(
self
.tcx
()
.data_layout.pointer_size
);
let
size
=
Size
::
from_bytes
(
bytes
);
if
let
Ok
(
byte_str
)
=
alloc
.get_bytes
(
&
self
.tcx
(),
ptr
,
size
)
{
p!
(
pretty_print_byte_str
(
byte_str
))
}
else
{
p!
(
"<too short allocation>"
)
...
...
@@ -987,32 +982,28 @@ fn pretty_print_const_scalar(
None
=>
p!
(
"<dangling pointer>"
),
},
// Bool
(
Scalar
::
Raw
{
data
:
0
,
..
}
,
ty
::
Bool
)
=>
p!
(
"false"
),
(
Scalar
::
Raw
{
data
:
1
,
..
}
,
ty
::
Bool
)
=>
p!
(
"true"
),
(
Scalar
::
Raw
(
ScalarInt
::
FALSE
)
,
ty
::
Bool
)
=>
p!
(
"false"
),
(
Scalar
::
Raw
(
ScalarInt
::
TRUE
)
,
ty
::
Bool
)
=>
p!
(
"true"
),
// Float
(
Scalar
::
Raw
{
data
,
..
}
,
ty
::
Float
(
ast
::
FloatTy
::
F32
))
=>
{
p!
(
write
(
"{}f32"
,
Single
::
from_bits
(
data
)))
(
Scalar
::
Raw
(
int
)
,
ty
::
Float
(
ast
::
FloatTy
::
F32
))
=>
{
p!
(
write
(
"{}f32"
,
Single
::
try_from
(
int
)
.unwrap
(
)))
}
(
Scalar
::
Raw
{
data
,
..
}
,
ty
::
Float
(
ast
::
FloatTy
::
F64
))
=>
{
p!
(
write
(
"{}f64"
,
Double
::
from_bits
(
data
)))
(
Scalar
::
Raw
(
int
)
,
ty
::
Float
(
ast
::
FloatTy
::
F64
))
=>
{
p!
(
write
(
"{}f64"
,
Double
::
try_from
(
int
)
.unwrap
(
)))
}
// Int
(
Scalar
::
Raw
{
data
,
..
},
ty
::
Uint
(
ui
))
=>
{
let
size
=
Integer
::
from_attr
(
&
self
.tcx
(),
UnsignedInt
(
*
ui
))
.size
();
let
int
=
ConstInt
::
new
(
data
,
size
,
false
,
ty
.is_ptr_sized_integral
());
if
print_ty
{
p!
(
write
(
"{:#?}"
,
int
))
}
else
{
p!
(
write
(
"{:?}"
,
int
))
}
}
(
Scalar
::
Raw
{
data
,
..
},
ty
::
Int
(
i
))
=>
{
let
size
=
Integer
::
from_attr
(
&
self
.tcx
(),
SignedInt
(
*
i
))
.size
();
let
int
=
ConstInt
::
new
(
data
,
size
,
true
,
ty
.is_ptr_sized_integral
());
(
Scalar
::
Raw
(
int
),
ty
::
Uint
(
_
)
|
ty
::
Int
(
_
))
=>
{
let
int
=
ConstInt
::
new
(
int
,
matches!
(
ty
.kind
(),
ty
::
Int
(
_
)),
ty
.is_ptr_sized_integral
());
if
print_ty
{
p!
(
write
(
"{:#?}"
,
int
))
}
else
{
p!
(
write
(
"{:?}"
,
int
))
}
}
// Char
(
Scalar
::
Raw
{
data
,
..
},
ty
::
Char
)
if
char
::
from_u32
(
data
as
u32
)
.is_some
()
=>
{
p!
(
write
(
"{:?}"
,
char
::
from_u32
(
data
as
u32
)
.unwrap
()))
(
Scalar
::
Raw
(
int
),
ty
::
Char
)
if
char
::
try_from
(
int
)
.is_ok
()
=>
{
p!
(
write
(
"{:?}"
,
char
::
try_from
(
int
)
.unwrap
()))
}
// Raw pointers
(
Scalar
::
Raw
{
data
,
..
},
ty
::
RawPtr
(
_
))
=>
{
(
Scalar
::
Raw
(
int
),
ty
::
RawPtr
(
_
))
=>
{
let
data
=
int
.assert_bits
(
self
.tcx
()
.data_layout.pointer_size
);
self
=
self
.typed_value
(
|
mut
this
|
{
write!
(
this
,
"0x{:x}"
,
data
)
?
;
...
...
@@ -1034,14 +1025,14 @@ fn pretty_print_const_scalar(
)
?
;
}
// For function type zsts just printing the path is enough
(
Scalar
::
Raw
{
size
:
0
,
..
}
,
ty
::
FnDef
(
d
,
s
))
=>
p!
(
print_value_path
(
*
d
,
s
)),
(
Scalar
::
Raw
(
ScalarInt
::
ZST
)
,
ty
::
FnDef
(
d
,
s
))
=>
p!
(
print_value_path
(
*
d
,
s
)),
// Nontrivial types with scalar bit representation
(
Scalar
::
Raw
{
data
,
size
}
,
_
)
=>
{
(
Scalar
::
Raw
(
int
)
,
_
)
=>
{
let
print
=
|
mut
this
:
Self
|
{
if
size
==
0
{
if
int
.size
()
==
Size
::
ZERO
{
write!
(
this
,
"transmute(())"
)
?
;
}
else
{
write!
(
this
,
"transmute(0x{:
01$x})"
,
data
,
size
as
usize
*
2
)
?
;
write!
(
this
,
"transmute(0x{:
x})"
,
int
)
?
;
}
Ok
(
this
)
};
...
...
compiler/rustc_mir/src/const_eval/eval_queries.rs
浏览文件 @
362123dd
...
...
@@ -137,10 +137,10 @@ pub(super) fn op_to_const<'tcx>(
let
alloc
=
ecx
.tcx
.global_alloc
(
ptr
.alloc_id
)
.unwrap_memory
();
ConstValue
::
ByRef
{
alloc
,
offset
:
ptr
.offset
}
}
Scalar
::
Raw
{
data
,
..
}
=>
{
Scalar
::
Raw
(
int
)
=>
{
assert
!
(
mplace
.layout
.is_zst
());
assert_eq!
(
u64
::
try_from
(
data
)
.unwrap
()
%
mplace
.layout.align.abi
.bytes
(),
u64
::
try_from
(
int
)
.unwrap
()
%
mplace
.layout.align.abi
.bytes
(),
0
,
"this MPlaceTy must come from a validated constant, thus we can assume the
\
alignment is correct"
,
...
...
compiler/rustc_mir/src/const_eval/machine.rs
浏览文件 @
362123dd
use
rustc_middle
::
mir
;
use
rustc_middle
::
ty
::
layout
::
HasTyCtxt
;
use
rustc_middle
::
ty
::{
self
,
Ty
};
use
rustc_middle
::
ty
::{
self
,
ScalarInt
,
Ty
};
use
std
::
borrow
::
Borrow
;
use
std
::
collections
::
hash_map
::
Entry
;
use
std
::
hash
::
Hash
;
...
...
@@ -194,13 +194,13 @@ fn guaranteed_eq(&mut self, a: Scalar, b: Scalar) -> bool {
fn
guaranteed_ne
(
&
mut
self
,
a
:
Scalar
,
b
:
Scalar
)
->
bool
{
match
(
a
,
b
)
{
// Comparisons between integers are always known.
(
Scalar
::
Raw
{
..
},
Scalar
::
Raw
{
..
}
)
=>
a
!=
b
,
(
Scalar
::
Raw
(
_
),
Scalar
::
Raw
(
_
)
)
=>
a
!=
b
,
// Comparisons of abstract pointers with null pointers are known if the pointer
// is in bounds, because if they are in bounds, the pointer can't be null.
(
Scalar
::
Raw
{
data
:
0
,
..
},
Scalar
::
Ptr
(
ptr
))
|
(
Scalar
::
Ptr
(
ptr
),
Scalar
::
Raw
{
data
:
0
,
..
})
=>
!
self
.memory
.ptr_may_be_null
(
ptr
),
// Inequality with integers other than null can never be known for sure.
(
Scalar
::
Raw
{
..
},
Scalar
::
Ptr
(
_
))
|
(
Scalar
::
Ptr
(
_
),
Scalar
::
Raw
{
..
})
=>
false
,
(
Scalar
::
Raw
(
int
),
Scalar
::
Ptr
(
ptr
))
|
(
Scalar
::
Ptr
(
ptr
),
Scalar
::
Raw
(
int
))
=>
{
int
==
ScalarInt
::
null
(
int
.size
())
&&
!
self
.memory
.ptr_may_be_null
(
ptr
)
}
// FIXME: return `true` for at least some comparisons where we can reliably
// determine the result of runtime inequality tests at compile-time.
// Examples include comparison of addresses in different static items.
...
...
compiler/rustc_mir/src/interpret/operand.rs
浏览文件 @
362123dd
...
...
@@ -211,14 +211,11 @@ pub fn from_int(i: impl Into<i128>, layout: TyAndLayout<'tcx>) -> Self {
#[inline]
pub
fn
to_const_int
(
self
)
->
ConstInt
{
assert
!
(
self
.layout.ty
.is_integral
());
ConstInt
::
new
(
self
.to_scalar
()
.expect
(
"to_const_int doesn't work on scalar pairs"
)
.assert_bits
(
self
.layout.size
),
self
.layout.size
,
self
.layout.ty
.is_signed
(),
self
.layout.ty
.is_ptr_sized_integral
(),
)
let
int
=
match
self
.to_scalar
()
.expect
(
"to_const_int doesn't work on scalar pairs"
)
{
Scalar
::
Raw
(
int
)
=>
int
,
Scalar
::
Ptr
(
_
)
=>
bug!
(
"to_const_int doesn't work on pointers"
),
};
ConstInt
::
new
(
int
,
self
.layout.ty
.is_signed
(),
self
.layout.ty
.is_ptr_sized_integral
())
}
}
...
...
@@ -544,7 +541,7 @@ pub(super) fn eval_operands(
let
tag_scalar
=
|
scalar
|
->
InterpResult
<
'tcx
,
_
>
{
Ok
(
match
scalar
{
Scalar
::
Ptr
(
ptr
)
=>
Scalar
::
Ptr
(
self
.global_base_pointer
(
ptr
)
?
),
Scalar
::
Raw
{
data
,
size
}
=>
Scalar
::
Raw
{
data
,
size
}
,
Scalar
::
Raw
(
int
)
=>
Scalar
::
Raw
(
int
)
,
})
};
// Early-return cases.
...
...
compiler/rustc_mir/src/interpret/place.rs
浏览文件 @
362123dd
...
...
@@ -721,12 +721,8 @@ fn write_immediate_no_validate(
dest
.layout.size
,
"Size mismatch when writing pointer"
),
Immediate
::
Scalar
(
ScalarMaybeUninit
::
Scalar
(
Scalar
::
Raw
{
size
,
..
}))
=>
{
assert_eq!
(
Size
::
from_bytes
(
size
),
dest
.layout.size
,
"Size mismatch when writing bits"
)
Immediate
::
Scalar
(
ScalarMaybeUninit
::
Scalar
(
Scalar
::
Raw
(
int
)))
=>
{
assert_eq!
(
int
.size
(),
dest
.layout.size
,
"Size mismatch when writing bits"
)
}
Immediate
::
Scalar
(
ScalarMaybeUninit
::
Uninit
)
=>
{}
// uninit can have any size
Immediate
::
ScalarPair
(
_
,
_
)
=>
{
...
...
compiler/rustc_mir/src/transform/const_prop.rs
浏览文件 @
362123dd
...
...
@@ -19,7 +19,9 @@
};
use
rustc_middle
::
ty
::
layout
::{
HasTyCtxt
,
LayoutError
,
TyAndLayout
};
use
rustc_middle
::
ty
::
subst
::{
InternalSubsts
,
Subst
};
use
rustc_middle
::
ty
::{
self
,
ConstInt
,
ConstKind
,
Instance
,
ParamEnv
,
Ty
,
TyCtxt
,
TypeFoldable
};
use
rustc_middle
::
ty
::{
self
,
ConstInt
,
ConstKind
,
Instance
,
ParamEnv
,
ScalarInt
,
Ty
,
TyCtxt
,
TypeFoldable
,
};
use
rustc_session
::
lint
;
use
rustc_span
::{
def_id
::
DefId
,
Span
};
use
rustc_target
::
abi
::{
HasDataLayout
,
LayoutOf
,
Size
,
TargetDataLayout
};
...
...
@@ -578,8 +580,7 @@ fn check_binary_op(
Some
(
l
)
=>
l
.to_const_int
(),
// Invent a dummy value, the diagnostic ignores it anyway
None
=>
ConstInt
::
new
(
1
,
left_size
,
ScalarInt
::
try_from_uint
(
1_u8
,
left_size
)
.unwrap
(),
left_ty
.is_signed
(),
left_ty
.is_ptr_sized_integral
(),
),
...
...
compiler/rustc_mir/src/transform/simplify_comparison_integral.rs
浏览文件 @
362123dd
...
...
@@ -26,22 +26,26 @@
pub
struct
SimplifyComparisonIntegral
;
impl
<
'tcx
>
MirPass
<
'tcx
>
for
SimplifyComparisonIntegral
{
fn
run_pass
(
&
self
,
_
:
TyCtxt
<
'tcx
>
,
body
:
&
mut
Body
<
'tcx
>
)
{
fn
run_pass
(
&
self
,
tcx
:
TyCtxt
<
'tcx
>
,
body
:
&
mut
Body
<
'tcx
>
)
{
trace!
(
"Running SimplifyComparisonIntegral on {:?}"
,
body
.source
);
let
helper
=
OptimizationFinder
{
body
};
let
opts
=
helper
.find_optimizations
();
let
mut
storage_deads_to_insert
=
vec!
[];
let
mut
storage_deads_to_remove
:
Vec
<
(
usize
,
BasicBlock
)
>
=
vec!
[];
let
param_env
=
tcx
.param_env
(
body
.source
.def_id
());
for
opt
in
opts
{
trace!
(
"SUCCESS: Applying {:?}"
,
opt
);
// replace terminator with a switchInt that switches on the integer directly
let
bbs
=
&
mut
body
.basic_blocks_mut
();
let
bb
=
&
mut
bbs
[
opt
.bb_idx
];
// We only use the bits for the untyped, not length checked `values` field. Thus we are
// not using any of the convenience wrappers here and directly access the bits.
let
new_value
=
match
opt
.branch_value_scalar
{
Scalar
::
Raw
{
data
,
..
}
=>
data
,
Scalar
::
Raw
(
int
)
=>
{
let
layout
=
tcx
.layout_of
(
param_env
.and
(
opt
.branch_value_ty
))
.expect
(
"if we have an evaluated constant we must know the layout"
);
int
.assert_bits
(
layout
.size
)
}
Scalar
::
Ptr
(
_
)
=>
continue
,
};
const
FALSE
:
u128
=
0
;
...
...
src/librustdoc/clean/utils.rs
浏览文件 @
362123dd
...
...
@@ -14,7 +14,7 @@
use
rustc_hir
as
hir
;
use
rustc_hir
::
def
::{
DefKind
,
Res
};
use
rustc_hir
::
def_id
::{
DefId
,
LOCAL_CRATE
};
use
rustc_middle
::
mir
::
interpret
::{
sign_extend
,
ConstValue
,
Scalar
};
use
rustc_middle
::
mir
::
interpret
::{
sign_extend
,
ConstValue
};
use
rustc_middle
::
ty
::
subst
::{
GenericArgKind
,
SubstsRef
};
use
rustc_middle
::
ty
::{
self
,
DefIdTree
,
Ty
};
use
rustc_span
::
symbol
::{
kw
,
sym
,
Symbol
};
...
...
@@ -499,12 +499,13 @@ fn print_const_with_custom_print_scalar(cx: &DocContext<'_>, ct: &'tcx ty::Const
// Use a slightly different format for integer types which always shows the actual value.
// For all other types, fallback to the original `pretty_print_const`.
match
(
ct
.val
,
ct
.ty
.kind
())
{
(
ty
::
ConstKind
::
Value
(
ConstValue
::
Scalar
(
Scalar
::
Raw
{
data
,
..
}
)),
ty
::
Uint
(
ui
))
=>
{
format!
(
"{}{}"
,
format_integer_with_underscore_sep
(
&
data
.to_string
()),
ui
.name_str
())
(
ty
::
ConstKind
::
Value
(
ConstValue
::
Scalar
(
int
)),
ty
::
Uint
(
ui
))
=>
{
format!
(
"{}{}"
,
format_integer_with_underscore_sep
(
&
int
.to_string
()),
ui
.name_str
())
}
(
ty
::
ConstKind
::
Value
(
ConstValue
::
Scalar
(
Scalar
::
Raw
{
data
,
..
}
)),
ty
::
Int
(
i
))
=>
{
(
ty
::
ConstKind
::
Value
(
ConstValue
::
Scalar
(
int
)),
ty
::
Int
(
i
))
=>
{
let
ty
=
cx
.tcx
.lift
(
ct
.ty
)
.unwrap
();
let
size
=
cx
.tcx
.layout_of
(
ty
::
ParamEnv
::
empty
()
.and
(
ty
))
.unwrap
()
.size
;
let
data
=
int
.assert_bits
(
size
);
let
sign_extended_data
=
sign_extend
(
data
,
size
)
as
i128
;
format!
(
...
...
src/test/ui/symbol-names/impl1.rs
浏览文件 @
362123dd
...
...
@@ -3,8 +3,8 @@
// revisions: legacy v0
//[legacy]compile-flags: -Z symbol-mangling-version=legacy
//[v0]compile-flags: -Z symbol-mangling-version=v0
//[legacy]normalize-stderr-32bit: "h
ee444285569b39c2
" -> "SYMBOL_HASH"
//[legacy]normalize-stderr-64bit: "h
310ea0259fc3d32d
" -> "SYMBOL_HASH"
//[legacy]normalize-stderr-32bit: "h
30edc7aa010c48ae
" -> "SYMBOL_HASH"
//[legacy]normalize-stderr-64bit: "h
56362331c4f93d19
" -> "SYMBOL_HASH"
#![feature(optin_builtin_traits,
rustc_attrs)]
#![allow(dead_code)]
...
...
src/tools/clippy/clippy_lints/src/consts.rs
浏览文件 @
362123dd
...
...
@@ -8,8 +8,9 @@
use
rustc_hir
::{
BinOp
,
BinOpKind
,
Block
,
Expr
,
ExprKind
,
HirId
,
QPath
,
UnOp
};
use
rustc_lint
::
LateContext
;
use
rustc_middle
::
ty
::
subst
::{
Subst
,
SubstsRef
};
use
rustc_middle
::
ty
::{
self
,
Ty
,
TyCtxt
};
use
rustc_middle
::
ty
::{
self
,
Ty
,
TyCtxt
,
ScalarInt
};
use
rustc_middle
::{
bug
,
span_bug
};
use
rustc_middle
::
mir
::
interpret
::
Scalar
;
use
rustc_span
::
symbol
::
Symbol
;
use
std
::
cmp
::
Ordering
::{
self
,
Equal
};
use
std
::
convert
::
TryInto
;
...
...
@@ -500,21 +501,21 @@ fn binop(&mut self, op: BinOp, left: &Expr<'_>, right: &Expr<'_>) -> Option<Cons
}
pub
fn
miri_to_const
(
result
:
&
ty
::
Const
<
'_
>
)
->
Option
<
Constant
>
{
use
rustc_middle
::
mir
::
interpret
::{
ConstValue
,
Scalar
};
use
rustc_middle
::
mir
::
interpret
::{
ConstValue
};
match
result
.val
{
ty
::
ConstKind
::
Value
(
ConstValue
::
Scalar
(
Scalar
::
Raw
{
data
:
d
,
..
}
))
=>
{
ty
::
ConstKind
::
Value
(
ConstValue
::
Scalar
(
Scalar
::
Raw
(
int
)
))
=>
{
match
result
.ty
.kind
()
{
ty
::
Bool
=>
Some
(
Constant
::
Bool
(
d
==
1
)),
ty
::
Uint
(
_
)
|
ty
::
Int
(
_
)
=>
Some
(
Constant
::
Int
(
d
)),
ty
::
Bool
=>
Some
(
Constant
::
Bool
(
int
==
ScalarInt
::
TRUE
)),
ty
::
Uint
(
_
)
|
ty
::
Int
(
_
)
=>
Some
(
Constant
::
Int
(
int
.assert_bits
(
int
.size
())
)),
ty
::
Float
(
FloatTy
::
F32
)
=>
Some
(
Constant
::
F32
(
f32
::
from_bits
(
d
.try_into
()
.expect
(
"invalid f32 bit representation"
),
int
.try_into
()
.expect
(
"invalid f32 bit representation"
),
))),
ty
::
Float
(
FloatTy
::
F64
)
=>
Some
(
Constant
::
F64
(
f64
::
from_bits
(
d
.try_into
()
.expect
(
"invalid f64 bit representation"
),
int
.try_into
()
.expect
(
"invalid f64 bit representation"
),
))),
ty
::
RawPtr
(
type_and_mut
)
=>
{
if
let
ty
::
Uint
(
_
)
=
type_and_mut
.ty
.kind
()
{
return
Some
(
Constant
::
RawPtr
(
d
));
return
Some
(
Constant
::
RawPtr
(
int
.assert_bits
(
int
.size
())
));
}
None
},
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录