Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
02dbb35b
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,发现更多精彩内容 >>
提交
02dbb35b
编写于
12月 23, 2019
作者:
O
Oliver Scherer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Deduplicate and clean up pretty printing logic
上级
15812785
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
286 addition
and
147 deletion
+286
-147
src/librustc/mir/mod.rs
src/librustc/mir/mod.rs
+8
-8
src/librustc/ty/print/pretty.rs
src/librustc/ty/print/pretty.rs
+215
-77
src/librustc_mir/interpret/intrinsics/type_name.rs
src/librustc_mir/interpret/intrinsics/type_name.rs
+1
-0
src/librustc_mir/interpret/operand.rs
src/librustc_mir/interpret/operand.rs
+39
-42
src/test/mir-opt/const-promotion-extern-static.rs
src/test/mir-opt/const-promotion-extern-static.rs
+2
-2
src/test/mir-opt/const_prop/discriminant.rs
src/test/mir-opt/const_prop/discriminant.rs
+1
-1
src/test/mir-opt/const_prop/issue-66971.rs
src/test/mir-opt/const_prop/issue-66971.rs
+1
-1
src/test/mir-opt/const_prop/read_immutable_static.rs
src/test/mir-opt/const_prop/read_immutable_static.rs
+2
-2
src/test/mir-opt/simplify-locals-removes-unused-consts.rs
src/test/mir-opt/simplify-locals-removes-unused-consts.rs
+8
-8
src/test/ui/const-generics/raw-ptr-const-param.rs
src/test/ui/const-generics/raw-ptr-const-param.rs
+3
-0
src/test/ui/const-generics/raw-ptr-const-param.stderr
src/test/ui/const-generics/raw-ptr-const-param.stderr
+5
-5
src/test/ui/consts/offset_from_ub.stderr
src/test/ui/consts/offset_from_ub.stderr
+1
-1
未找到文件。
src/librustc/mir/mod.rs
浏览文件 @
02dbb35b
...
...
@@ -2562,15 +2562,15 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
impl
<
'tcx
>
Display
for
Constant
<
'tcx
>
{
fn
fmt
(
&
self
,
fmt
:
&
mut
Formatter
<
'_
>
)
->
fmt
::
Result
{
use
crate
::
ty
::
print
::
PrettyPrinter
;
write!
(
fmt
,
"const "
)
?
;
// FIXME make the default pretty printing of raw pointers more detailed. Here we output the
// debug representation of raw pointers, so that the raw pointers in the mir dump output are
// detailed and just not '{pointer}'.
if
let
ty
::
RawPtr
(
_
)
=
self
.literal.ty.kind
{
write!
(
fmt
,
"{:?} : {}"
,
self
.literal.val
,
self
.literal.ty
)
}
else
{
write!
(
fmt
,
"{}"
,
self
.literal
)
}
ty
::
tls
::
with
(|
tcx
|
{
let
literal
=
tcx
.lift
(
&
self
.literal
)
.unwrap
();
let
mut
cx
=
FmtPrinter
::
new
(
tcx
,
fmt
,
Namespace
::
ValueNS
);
cx
.print_alloc_ids
=
true
;
cx
.pretty_print_const
(
literal
,
true
)
?
;
Ok
(())
})
}
}
...
...
src/librustc/ty/print/pretty.rs
浏览文件 @
02dbb35b
use
crate
::
hir
::
map
::{
DefPathData
,
DisambiguatedDefPathData
};
use
crate
::
middle
::
cstore
::{
ExternCrate
,
ExternCrateSource
};
use
crate
::
middle
::
region
;
use
crate
::
mir
::
interpret
::{
sign_extend
,
truncate
,
ConstValue
,
Scalar
};
use
crate
::
mir
::
interpret
::{
sign_extend
,
truncate
,
AllocId
,
ConstValue
,
Pointer
,
Scalar
};
use
crate
::
ty
::
layout
::{
Integer
,
IntegerExt
,
Size
};
use
crate
::
ty
::
subst
::{
GenericArg
,
GenericArgKind
,
Subst
};
use
crate
::
ty
::{
self
,
DefIdTree
,
ParamConst
,
Ty
,
TyCtxt
,
TypeFoldable
};
...
...
@@ -457,6 +457,22 @@ fn pretty_path_append_impl(
})
}
fn
print_type_ascribed
(
mut
self
,
f
:
impl
FnOnce
(
Self
)
->
Result
<
Self
,
Self
::
Error
>
,
ty
:
Ty
<
'tcx
>
,
print_ty
:
bool
,
)
->
Result
<
Self
::
Const
,
Self
::
Error
>
{
self
.write_str
(
"{"
)
?
;
self
=
f
(
self
)
?
;
if
print_ty
{
self
.write_str
(
": "
)
?
;
self
=
self
.print_type
(
ty
)
?
;
}
self
.write_str
(
"}"
)
?
;
Ok
(
self
)
}
fn
pretty_print_type
(
mut
self
,
ty
:
Ty
<
'tcx
>
)
->
Result
<
Self
::
Type
,
Self
::
Error
>
{
define_scoped_cx!
(
self
);
...
...
@@ -893,32 +909,49 @@ fn pretty_print_const(
Ok
(
self
)
}
fn
pretty_print_const_
value
(
fn
pretty_print_const_
scalar
(
mut
self
,
ct
:
ConstValue
<
'tcx
>
,
scalar
:
Scalar
,
ty
:
Ty
<
'tcx
>
,
print_ty
:
bool
,
)
->
Result
<
Self
::
Const
,
Self
::
Error
>
{
define_scoped_cx!
(
self
);
if
self
.tcx
()
.sess
.verbose
()
{
p!
(
write
(
"ConstValue({:?}: {:?})"
,
ct
,
ty
));
return
Ok
(
self
);
}
let
u8
=
self
.tcx
()
.types.u8
;
match
(
ct
,
&
ty
.kind
)
{
(
ConstValue
::
Scalar
(
Scalar
::
Raw
{
data
,
..
}),
ty
::
Bool
)
=>
{
p!
(
write
(
"{}"
,
if
data
==
0
{
"false"
}
else
{
"true"
}))
}
(
ConstValue
::
Scalar
(
Scalar
::
Raw
{
data
,
..
}),
ty
::
Float
(
ast
::
FloatTy
::
F32
))
=>
{
match
(
scalar
,
&
ty
.kind
)
{
// Single element arrays print their element (they are `#[transparent]`) enclosed in
// square brackets.
(
_
,
ty
::
Array
(
t
,
n
))
if
n
.eval_usize
(
self
.tcx
(),
ty
::
ParamEnv
::
empty
())
==
1
=>
{
p!
(
write
(
"["
));
self
=
self
.pretty_print_const_scalar
(
scalar
,
t
,
print_ty
)
?
;
p!
(
write
(
"]"
));
}
// Byte strings (&[u8; N])
(
Scalar
::
Ptr
(
ptr
),
ty
::
Ref
(
_
,
ty
::
TyS
{
kind
:
ty
::
Array
(
t
,
n
),
..
},
_
))
if
*
t
==
self
.tcx
()
.types.u8
=>
{
let
n
=
n
.eval_usize
(
self
.tcx
(),
ty
::
ParamEnv
::
empty
());
let
byte_str
=
self
.tcx
()
.alloc_map
.lock
()
.unwrap_memory
(
ptr
.alloc_id
)
.get_bytes
(
&
self
.tcx
(),
ptr
,
Size
::
from_bytes
(
n
))
.unwrap
();
p!
(
pretty_print_byte_str
(
byte_str
));
}
// Bool
(
Scalar
::
Raw
{
data
:
0
,
..
},
ty
::
Bool
)
=>
p!
(
write
(
"false"
)),
(
Scalar
::
Raw
{
data
:
1
,
..
},
ty
::
Bool
)
=>
p!
(
write
(
"true"
)),
(
Scalar
::
Raw
{
data
,
..
},
ty
::
Bool
)
=>
p!
(
write
(
"{}_bool"
,
data
)),
// Float
(
Scalar
::
Raw
{
data
,
..
},
ty
::
Float
(
ast
::
FloatTy
::
F32
))
=>
{
p!
(
write
(
"{}f32"
,
Single
::
from_bits
(
data
)))
}
(
ConstValue
::
Scalar
(
Scalar
::
Raw
{
data
,
..
})
,
ty
::
Float
(
ast
::
FloatTy
::
F64
))
=>
{
(
Scalar
::
Raw
{
data
,
..
}
,
ty
::
Float
(
ast
::
FloatTy
::
F64
))
=>
{
p!
(
write
(
"{}f64"
,
Double
::
from_bits
(
data
)))
}
(
ConstValue
::
Scalar
(
Scalar
::
Raw
{
data
,
..
}),
ty
::
Uint
(
ui
))
=>
{
// Int
(
Scalar
::
Raw
{
data
,
..
},
ty
::
Uint
(
ui
))
=>
{
let
bit_size
=
Integer
::
from_attr
(
&
self
.tcx
(),
UnsignedInt
(
*
ui
))
.size
();
let
max
=
truncate
(
u128
::
MAX
,
bit_size
);
...
...
@@ -929,7 +962,7 @@ fn pretty_print_const_value(
p!
(
write
(
"{}{}"
,
data
,
ui_str
))
};
}
(
ConstValue
::
Scalar
(
Scalar
::
Raw
{
data
,
..
})
,
ty
::
Int
(
i
))
=>
{
(
Scalar
::
Raw
{
data
,
..
}
,
ty
::
Int
(
i
))
=>
{
let
bit_size
=
Integer
::
from_attr
(
&
self
.tcx
(),
SignedInt
(
*
i
))
.size
()
.bits
()
as
u128
;
let
min
=
1u128
<<
(
bit_size
-
1
);
let
max
=
min
-
1
;
...
...
@@ -943,76 +976,140 @@ fn pretty_print_const_value(
_
=>
p!
(
write
(
"{}{}"
,
sign_extend
(
data
,
size
)
as
i128
,
i_str
)),
}
}
(
ConstValue
::
Scalar
(
Scalar
::
Raw
{
data
,
..
}),
ty
::
Char
)
=>
{
p!
(
write
(
"{:?}"
,
::
std
::
char
::
from_u32
(
data
as
u32
)
.unwrap
()))
// Char
(
Scalar
::
Raw
{
data
,
..
},
ty
::
Char
)
=>
match
::
std
::
char
::
from_u32
(
data
as
u32
)
{
Some
(
c
)
=>
p!
(
write
(
"{:?}"
,
c
)),
None
=>
p!
(
write
(
"{}_char"
,
data
)),
},
// References and pointers
(
Scalar
::
Raw
{
data
:
0
,
..
},
ty
::
RawPtr
(
_
))
=>
p!
(
write
(
"{{null pointer}}"
)),
// This is UB, but we still print it
(
Scalar
::
Raw
{
data
:
0
,
..
},
ty
::
Ref
(
_
,
ty
,
_
))
=>
{
p!
(
write
(
"{{null reference to "
),
print
(
ty
),
write
(
"}}"
))
}
(
ConstValue
::
Scalar
(
_
),
ty
::
RawPtr
(
_
))
=>
p!
(
write
(
"{{pointer}}"
)),
(
ConstValue
::
Scalar
(
Scalar
::
Ptr
(
ptr
)),
ty
::
FnPtr
(
_
))
=>
{
(
Scalar
::
Raw
{
data
,
..
},
ty
::
Ref
(
..
))
|
(
Scalar
::
Raw
{
data
,
..
},
ty
::
RawPtr
(
_
))
=>
{
let
pointer_width
=
self
.tcx
()
.data_layout.pointer_size
.bytes
();
p!
(
write
(
"0x{:01$x}"
,
data
,
pointer_width
as
usize
*
2
))
}
(
Scalar
::
Ptr
(
ptr
),
ty
::
FnPtr
(
_
))
=>
{
let
instance
=
{
let
alloc_map
=
self
.tcx
()
.alloc_map
.lock
();
alloc_map
.unwrap_fn
(
ptr
.alloc_id
)
};
p!
(
print_value_path
(
instance
.def_id
(),
instance
.substs
));
}
_
=>
{
let
printed
=
if
let
ty
::
Ref
(
_
,
ref_ty
,
_
)
=
ty
.kind
{
let
byte_str
=
match
(
ct
,
&
ref_ty
.kind
)
{
(
ConstValue
::
Scalar
(
Scalar
::
Ptr
(
ptr
)),
ty
::
Array
(
t
,
n
))
if
*
t
==
u8
=>
{
let
n
=
n
.eval_usize
(
self
.tcx
(),
ty
::
ParamEnv
::
empty
());
Some
(
self
.tcx
()
.alloc_map
.lock
()
.unwrap_memory
(
ptr
.alloc_id
)
.get_bytes
(
&
self
.tcx
(),
ptr
,
Size
::
from_bytes
(
n
))
.unwrap
(),
)
}
(
ConstValue
::
Slice
{
data
,
start
,
end
},
ty
::
Slice
(
t
))
if
*
t
==
u8
=>
{
// The `inspect` here is okay since we checked the bounds, and there are
// no relocations (we have an active slice reference here). We don't use
// this result to affect interpreter execution.
Some
(
data
.inspect_with_undef_and_ptr_outside_interpreter
(
start
..
end
))
}
_
=>
None
,
};
// For zsts just print their type as their value gives no extra information
(
Scalar
::
Raw
{
size
:
0
,
..
},
_
)
=>
p!
(
print
(
ty
)),
// Nontrivial types with scalar bit representation
(
Scalar
::
Raw
{
data
,
size
},
_
)
=>
{
self
=
self
.print_type_ascribed
(
|
mut
this
|
{
write!
(
this
,
"0x{:01$x}"
,
data
,
size
as
usize
*
2
)
?
;
Ok
(
this
)
},
ty
,
print_ty
,
)
?
}
// Any pointer values not covered by a branch above
(
Scalar
::
Ptr
(
p
),
_
)
=>
{
self
=
self
.pretty_print_const_pointer
(
p
,
ty
,
print_ty
)
?
;
}
}
Ok
(
self
)
}
if
let
Some
(
byte_str
)
=
byte_str
{
p!
(
write
(
"b
\"
"
));
for
&
c
in
byte_str
{
for
e
in
std
::
ascii
::
escape_default
(
c
)
{
self
.write_char
(
e
as
char
)
?
;
}
}
p!
(
write
(
"
\"
"
));
true
}
else
if
let
(
ConstValue
::
Slice
{
data
,
start
,
end
},
ty
::
Str
)
=
(
ct
,
&
ref_ty
.kind
)
{
// The `inspect` here is okay since we checked the bounds, and there are no
// relocations (we have an active `str` reference here). We don't use this
// result to affect interpreter execution.
let
slice
=
data
.inspect_with_undef_and_ptr_outside_interpreter
(
start
..
end
);
let
s
=
::
std
::
str
::
from_utf8
(
slice
)
.expect
(
"non utf8 str from miri"
);
p!
(
write
(
"{:?}"
,
s
));
true
}
else
{
false
}
}
else
{
false
};
if
!
printed
{
// fallback
p!
(
write
(
"{:?}"
,
ct
));
if
print_ty
{
p!
(
write
(
": "
),
print
(
ty
));
}
}
/// This is overridden for MIR printing because we only want to hide alloc ids from users, not
/// from MIR where it is actually useful.
fn
pretty_print_const_pointer
(
self
,
_
:
Pointer
,
ty
:
Ty
<
'tcx
>
,
print_ty
:
bool
,
)
->
Result
<
Self
::
Const
,
Self
::
Error
>
{
self
.print_type_ascribed
(
|
mut
this
|
{
this
.write_str
(
"pointer"
)
?
;
Ok
(
this
)
},
ty
,
print_ty
,
)
}
fn
pretty_print_byte_str
(
mut
self
,
byte_str
:
&
'tcx
[
u8
])
->
Result
<
Self
::
Const
,
Self
::
Error
>
{
define_scoped_cx!
(
self
);
p!
(
write
(
"b
\"
"
));
for
&
c
in
byte_str
{
for
e
in
std
::
ascii
::
escape_default
(
c
)
{
self
.write_char
(
e
as
char
)
?
;
}
};
}
p!
(
write
(
"
\"
"
));
Ok
(
self
)
}
fn
pretty_print_const_value
(
mut
self
,
ct
:
ConstValue
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
print_ty
:
bool
,
)
->
Result
<
Self
::
Const
,
Self
::
Error
>
{
define_scoped_cx!
(
self
);
if
self
.tcx
()
.sess
.verbose
()
{
p!
(
write
(
"ConstValue({:?}: {:?})"
,
ct
,
ty
));
return
Ok
(
self
);
}
let
u8_type
=
self
.tcx
()
.types.u8
;
match
(
ct
,
&
ty
.kind
)
{
(
ConstValue
::
Scalar
(
scalar
),
_
)
=>
self
.pretty_print_const_scalar
(
scalar
,
ty
,
print_ty
),
(
ConstValue
::
Slice
{
data
,
start
,
end
},
ty
::
Ref
(
_
,
ty
::
TyS
{
kind
:
ty
::
Slice
(
t
),
..
},
_
),
)
if
*
t
==
u8_type
=>
{
// The `inspect` here is okay since we checked the bounds, and there are
// no relocations (we have an active slice reference here). We don't use
// this result to affect interpreter execution.
let
byte_str
=
data
.inspect_with_undef_and_ptr_outside_interpreter
(
start
..
end
);
self
.pretty_print_byte_str
(
byte_str
)
}
(
ConstValue
::
Slice
{
data
,
start
,
end
},
ty
::
Ref
(
_
,
ty
::
TyS
{
kind
:
ty
::
Str
,
..
},
_
),
)
=>
{
// The `inspect` here is okay since we checked the bounds, and there are no
// relocations (we have an active `str` reference here). We don't use this
// result to affect interpreter execution.
let
slice
=
data
.inspect_with_undef_and_ptr_outside_interpreter
(
start
..
end
);
let
s
=
::
std
::
str
::
from_utf8
(
slice
)
.expect
(
"non utf8 str from miri"
);
p!
(
write
(
"{:?}"
,
s
));
Ok
(
self
)
}
(
ConstValue
::
ByRef
{
alloc
,
offset
},
ty
::
Array
(
t
,
n
))
if
*
t
==
u8_type
=>
{
let
n
=
n
.eval_usize
(
self
.tcx
(),
ty
::
ParamEnv
::
empty
());
let
n
=
Size
::
from_bytes
(
n
);
let
ptr
=
Pointer
::
new
(
AllocId
(
0
),
offset
);
let
byte_str
=
alloc
.get_bytes
(
&
self
.tcx
(),
ptr
,
n
)
.unwrap
();
p!
(
write
(
"*"
));
p!
(
pretty_print_byte_str
(
byte_str
));
Ok
(
self
)
}
// FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
// their fields instead of just dumping the memory.
_
=>
{
// fallback
p!
(
write
(
"{:?}"
,
ct
));
if
print_ty
{
p!
(
write
(
": "
),
print
(
ty
));
}
Ok
(
self
)
}
}
}
}
// HACK(eddyb) boxed to avoid moving around a large struct by-value.
...
...
@@ -1024,6 +1121,7 @@ pub struct FmtPrinterData<'a, 'tcx, F> {
empty_path
:
bool
,
in_value
:
bool
,
pub
print_alloc_ids
:
bool
,
used_region_names
:
FxHashSet
<
Symbol
>
,
region_index
:
usize
,
...
...
@@ -1054,6 +1152,7 @@ pub fn new(tcx: TyCtxt<'tcx>, fmt: F, ns: Namespace) -> Self {
fmt
,
empty_path
:
false
,
in_value
:
ns
==
Namespace
::
ValueNS
,
print_alloc_ids
:
false
,
used_region_names
:
Default
::
default
(),
region_index
:
0
,
binder_depth
:
0
,
...
...
@@ -1382,6 +1481,45 @@ fn region_should_not_be_omitted(&self, region: ty::Region<'_>) -> bool {
ty
::
ReStatic
|
ty
::
ReEmpty
(
_
)
|
ty
::
ReClosureBound
(
_
)
=>
true
,
}
}
fn
pretty_print_const_pointer
(
self
,
p
:
Pointer
,
ty
:
Ty
<
'tcx
>
,
print_ty
:
bool
,
)
->
Result
<
Self
::
Const
,
Self
::
Error
>
{
self
.print_type_ascribed
(
|
mut
this
|
{
define_scoped_cx!
(
this
);
if
this
.print_alloc_ids
{
p!
(
write
(
"{:?}"
,
p
));
}
else
{
p!
(
write
(
"pointer"
));
}
Ok
(
this
)
},
ty
,
print_ty
,
)
}
fn
print_type_ascribed
(
mut
self
,
f
:
impl
FnOnce
(
Self
)
->
Result
<
Self
,
Self
::
Error
>
,
ty
:
Ty
<
'tcx
>
,
print_ty
:
bool
,
)
->
Result
<
Self
::
Const
,
Self
::
Error
>
{
self
.write_str
(
"{"
)
?
;
self
=
f
(
self
)
?
;
if
print_ty
{
self
.write_str
(
": "
)
?
;
let
was_in_value
=
std
::
mem
::
replace
(
&
mut
self
.in_value
,
false
);
self
=
self
.print_type
(
ty
)
?
;
self
.in_value
=
was_in_value
;
}
self
.write_str
(
"}"
)
?
;
Ok
(
self
)
}
}
// HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`.
...
...
src/librustc_mir/interpret/intrinsics/type_name.rs
浏览文件 @
02dbb35b
...
...
@@ -157,6 +157,7 @@ fn path_generic_args(
}
}
}
impl
PrettyPrinter
<
'tcx
>
for
AbsolutePathPrinter
<
'tcx
>
{
fn
region_should_not_be_omitted
(
&
self
,
_
region
:
ty
::
Region
<
'_
>
)
->
bool
{
false
...
...
src/librustc_mir/interpret/operand.rs
浏览文件 @
02dbb35b
...
...
@@ -3,18 +3,20 @@
use
std
::
convert
::{
TryFrom
,
TryInto
};
use
rustc
::
ty
::
layout
::{
self
,
HasDataLayout
,
IntegerExt
,
LayoutOf
,
PrimitiveExt
,
Size
,
TyLayout
,
VariantIdx
,
};
use
rustc
::{
mir
,
ty
};
use
super
::{
InterpCx
,
MPlaceTy
,
Machine
,
MemPlace
,
Place
,
PlaceTy
};
pub
use
rustc
::
mir
::
interpret
::
ScalarMaybeUndef
;
use
rustc
::
mir
::
interpret
::{
sign_extend
,
truncate
,
AllocId
,
ConstValue
,
GlobalId
,
InterpResult
,
Pointer
,
Scalar
,
};
use
rustc_ast
::
ast
;
use
rustc
::
ty
::
layout
::{
self
,
HasDataLayout
,
IntegerExt
,
LayoutOf
,
PrimitiveExt
,
Size
,
TyLayout
,
VariantIdx
,
};
use
rustc
::
ty
::
print
::{
FmtPrinter
,
PrettyPrinter
,
Printer
};
use
rustc
::
ty
::
Ty
;
use
rustc
::{
mir
,
ty
};
use
rustc_hir
::
def
::
Namespace
;
use
rustc_macros
::
HashStable
;
use
std
::
fmt
::
Write
;
/// An `Immediate` represents a single immediate self-contained Rust value.
///
...
...
@@ -92,47 +94,42 @@ pub struct ImmTy<'tcx, Tag = ()> {
pub
layout
:
TyLayout
<
'tcx
>
,
}
// `Tag: Copy` because some methods on `Scalar` consume them by value
impl
<
Tag
:
Copy
>
std
::
fmt
::
Display
for
ImmTy
<
'tcx
,
Tag
>
{
fn
fmt
(
&
self
,
fmt
:
&
mut
std
::
fmt
::
Formatter
<
'_
>
)
->
std
::
fmt
::
Result
{
match
&
self
.imm
{
// We cannot use `to_bits_or_ptr` as we do not have a `tcx`.
// So we use `is_bits` and circumvent a bunch of sanity checking -- but
// this is anyway only for printing.
Immediate
::
Scalar
(
ScalarMaybeUndef
::
Scalar
(
s
))
if
s
.is_ptr
()
=>
{
fmt
.write_str
(
"{pointer}"
)
fn
fmt
(
&
self
,
f
:
&
mut
std
::
fmt
::
Formatter
<
'_
>
)
->
std
::
fmt
::
Result
{
/// Helper function for printing a scalar to a FmtPrinter
fn
p
<
'a
,
'tcx
,
F
:
std
::
fmt
::
Write
,
Tag
>
(
mut
cx
:
FmtPrinter
<
'a
,
'tcx
,
F
>
,
s
:
ScalarMaybeUndef
<
Tag
>
,
ty
:
Ty
<
'tcx
>
,
)
->
Result
<
FmtPrinter
<
'a
,
'tcx
,
F
>
,
std
::
fmt
::
Error
>
{
match
s
{
ScalarMaybeUndef
::
Scalar
(
s
)
=>
{
cx
.pretty_print_const_scalar
(
s
.erase_tag
(),
ty
,
true
)
}
ScalarMaybeUndef
::
Undef
=>
{
cx
.write_str
(
"{undef "
)
?
;
cx
=
cx
.print_type
(
ty
)
?
;
cx
.write_str
(
"}"
)
?
;
Ok
(
cx
)
}
}
Immediate
::
Scalar
(
ScalarMaybeUndef
::
Scalar
(
s
))
=>
{
let
s
=
s
.assert_bits
(
self
.layout.size
);
match
self
.layout.ty.kind
{
ty
::
Int
(
_
)
=>
{
return
write!
(
fmt
,
"{}"
,
super
::
sign_extend
(
s
,
self
.layout.size
)
as
i128
,);
}
ty
::
Uint
(
_
)
=>
return
write!
(
fmt
,
"{}"
,
s
),
ty
::
Bool
if
s
==
0
=>
return
fmt
.write_str
(
"false"
),
ty
::
Bool
if
s
==
1
=>
return
fmt
.write_str
(
"true"
),
ty
::
Char
=>
{
if
let
Some
(
c
)
=
u32
::
try_from
(
s
)
.ok
()
.and_then
(
std
::
char
::
from_u32
)
{
return
write!
(
fmt
,
"{}"
,
c
);
}
}
ty
::
Float
(
ast
::
FloatTy
::
F32
)
=>
{
if
let
Ok
(
u
)
=
u32
::
try_from
(
s
)
{
return
write!
(
fmt
,
"{}"
,
f32
::
from_bits
(
u
));
}
}
ty
::
Float
(
ast
::
FloatTy
::
F64
)
=>
{
if
let
Ok
(
u
)
=
u64
::
try_from
(
s
)
{
return
write!
(
fmt
,
"{}"
,
f64
::
from_bits
(
u
));
}
}
ty
::
tls
::
with
(|
tcx
|
{
match
self
.imm
{
Immediate
::
Scalar
(
s
)
=>
{
if
let
Some
(
ty
)
=
tcx
.lift
(
&
self
.layout.ty
)
{
let
cx
=
FmtPrinter
::
new
(
tcx
,
f
,
Namespace
::
ValueNS
);
p
(
cx
,
s
,
ty
)
?
;
return
Ok
(());
}
_
=>
{}
write!
(
f
,
"{:?}: {}"
,
s
.erase_tag
(),
self
.layout.ty
)
}
Immediate
::
ScalarPair
(
a
,
b
)
=>
{
// FIXME(oli-obk): at least print tuples and slices nicely
write!
(
f
,
"({:?}, {:?}): {}"
,
a
.erase_tag
(),
b
.erase_tag
(),
self
.layout.ty
,)
}
write!
(
fmt
,
"{:x}"
,
s
)
}
Immediate
::
Scalar
(
ScalarMaybeUndef
::
Undef
)
=>
fmt
.write_str
(
"{undef}"
),
Immediate
::
ScalarPair
(
..
)
=>
fmt
.write_str
(
"{wide pointer or tuple}"
),
}
})
}
}
...
...
src/test/mir-opt/const-promotion-extern-static.rs
浏览文件 @
02dbb35b
...
...
@@ -14,7 +14,7 @@ fn main() {}
// START rustc.FOO.PromoteTemps.before.mir
// bb0: {
// ...
// _5 = const
Scalar(alloc1+0) : &i32
;
// _5 = const
{alloc1+0: &i32}
;
// _4 = &(*_5);
// _3 = [move _4];
// _2 = &_3;
...
...
@@ -31,7 +31,7 @@ fn main() {}
// START rustc.BAR.PromoteTemps.before.mir
// bb0: {
// ...
// _5 = const
Scalar(alloc0+0) : &i32
;
// _5 = const
{alloc0+0: &i32}
;
// _4 = &(*_5);
// _3 = [move _4];
// _2 = &_3;
...
...
src/test/mir-opt/const_prop/discriminant.rs
浏览文件 @
02dbb35b
...
...
@@ -31,7 +31,7 @@ fn main() {
// START rustc.main.ConstProp.after.mir
// bb0: {
// ...
// _3 = const
Scalar(0x01) : std::option::Option<bool>
;
// _3 = const
{0x01: std::option::Option<bool>}
;
// _4 = const 1isize;
// switchInt(const 1isize) -> [1isize: bb2, otherwise: bb1];
// }
...
...
src/test/mir-opt/const_prop/issue-66971.rs
浏览文件 @
02dbb35b
...
...
@@ -29,7 +29,7 @@ fn main() {
// START rustc.main.ConstProp.after.mir
// bb0: {
// ...
// _3 = const
Scalar(<ZST>) :
();
// _3 = const ();
// _2 = (move _3, const 0u8, const 0u8);
// ...
// _1 = const encode(move _2) -> bb1;
...
...
src/test/mir-opt/const_prop/read_immutable_static.rs
浏览文件 @
02dbb35b
...
...
@@ -10,10 +10,10 @@ fn main() {
// START rustc.main.ConstProp.before.mir
// bb0: {
// ...
// _3 = const
Scalar(alloc0+0) : &u8
;
// _3 = const
{alloc0+0: &u8}
;
// _2 = (*_3);
// ...
// _5 = const
Scalar(alloc0+0) : &u8
;
// _5 = const
{alloc0+0: &u8}
;
// _4 = (*_5);
// _1 = Add(move _2, move _4);
// ...
...
...
src/test/mir-opt/simplify-locals-removes-unused-consts.rs
浏览文件 @
02dbb35b
...
...
@@ -35,28 +35,28 @@ fn main() {
// bb0: {
// StorageLive(_1);
// StorageLive(_2);
// _2 = const
Scalar(<ZST>) :
();
// _2 = const ();
// StorageLive(_3);
// _3 = const
Scalar(<ZST>) :
();
// _1 = const
Scalar(<ZST>) :
((), ());
// _3 = const ();
// _1 = const ((), ());
// StorageDead(_3);
// StorageDead(_2);
// StorageDead(_1);
// StorageLive(_4);
// StorageLive(_6);
// _6 = const
Scalar(<ZST>) :
();
// _6 = const ();
// StorageLive(_7);
// _7 = const
Scalar(<ZST>) :
();
// _7 = const ();
// StorageDead(_7);
// StorageDead(_6);
// _4 = const use_zst(const
Scalar(<ZST>) :
((), ())) -> bb1;
// _4 = const use_zst(const ((), ())) -> bb1;
// }
// bb1: {
// StorageDead(_4);
// StorageLive(_8);
// StorageLive(_10);
// StorageLive(_11);
// _11 = const
Scalar(0x28) : Temp
;
// _11 = const
{0x28 : Temp}
;
// _10 = const 40u8;
// StorageDead(_10);
// _8 = const use_u8(const 42u8) -> bb2;
...
...
@@ -75,7 +75,7 @@ fn main() {
// }
// bb0: {
// StorageLive(_1);
// _1 = const use_zst(const
Scalar(<ZST>) :
((), ())) -> bb1;
// _1 = const use_zst(const ((), ())) -> bb1;
// }
// bb1: {
// StorageDead(_1);
...
...
src/test/ui/const-generics/raw-ptr-const-param.rs
浏览文件 @
02dbb35b
// normalize-stderr-64bit "0x00000000" -> "0x[PREFIX]"
// normalize-stderr-32bit "0x" -> "0x[PREFIX]"
#![feature(const_generics,
const_compare_raw_pointers)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
...
...
src/test/ui/const-generics/raw-ptr-const-param.stderr
浏览文件 @
02dbb35b
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/raw-ptr-const-param.rs:
1
:12
--> $DIR/raw-ptr-const-param.rs:
4
:12
|
LL | #![feature(const_generics, const_compare_raw_pointers)]
| ^^^^^^^^^^^^^^
...
...
@@ -7,15 +7,15 @@ LL | #![feature(const_generics, const_compare_raw_pointers)]
= note: `#[warn(incomplete_features)]` on by default
error[E0308]: mismatched types
--> $DIR/raw-ptr-const-param.rs:
7
:38
--> $DIR/raw-ptr-const-param.rs:
10
:38
|
LL | let _: Const<{15 as *const _}> = Const::<{10 as *const _}>;
| ----------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `
{pointer}`, found `{pointer}
`
| ----------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `
0x[PREFIX]0000000f`, found `0x[PREFIX]0000000a
`
| |
| expected due to this
|
= note: expected struct `Const<
{pointer}
>`
found struct `Const<
{pointer}
>`
= note: expected struct `Const<
0x[PREFIX]0000000f
>`
found struct `Const<
0x[PREFIX]0000000a
>`
error: aborting due to previous error
...
...
src/test/ui/consts/offset_from_ub.stderr
浏览文件 @
02dbb35b
...
...
@@ -43,7 +43,7 @@ error: any use of this value will cause an error
LL | intrinsics::ptr_offset_from(self, origin)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| exact_div: 1
cannot be divided by 2
without remainder
| exact_div: 1
isize cannot be divided by 2isize
without remainder
| inside call to `std::ptr::const_ptr::<impl *const u16>::offset_from` at $DIR/offset_from_ub.rs:36:14
|
::: $DIR/offset_from_ub.rs:31:1
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录