1
- use rustc_middle:: ty:: layout:: { InitKind , LayoutCx , LayoutError , LayoutOf , TyAndLayout } ;
1
+ use rustc_middle:: ty:: layout:: { LayoutCx , LayoutError , LayoutOf , TyAndLayout , ValidityRequirement } ;
2
2
use rustc_middle:: ty:: { ParamEnv , ParamEnvAnd , Ty , TyCtxt } ;
3
3
use rustc_session:: Limit ;
4
4
use rustc_target:: abi:: { Abi , FieldsShape , Scalar , Variants } ;
@@ -18,16 +18,23 @@ use crate::interpret::{InterpCx, MemoryKind, OpTy};
18
18
/// Rust UB as long as there is no risk of miscompilations. The `strict_init_checks` can be set to
19
19
/// do a full check against Rust UB instead (in which case we will also ignore the 0x01-filling and
20
20
/// to the full uninit check).
21
- pub fn might_permit_raw_init < ' tcx > (
21
+ pub fn check_validity_requirement < ' tcx > (
22
22
tcx : TyCtxt < ' tcx > ,
23
- kind : InitKind ,
23
+ kind : ValidityRequirement ,
24
24
param_env_and_ty : ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
25
25
) -> Result < bool , LayoutError < ' tcx > > {
26
+ let layout = tcx. layout_of ( param_env_and_ty) ?;
27
+
28
+ // There is nothing strict or lax about inhabitedness.
29
+ if kind == ValidityRequirement :: Inhabited {
30
+ return Ok ( !layout. abi . is_uninhabited ( ) ) ;
31
+ }
32
+
26
33
if tcx. sess . opts . unstable_opts . strict_init_checks {
27
- might_permit_raw_init_strict ( tcx . layout_of ( param_env_and_ty ) ? , tcx, kind)
34
+ might_permit_raw_init_strict ( layout , tcx, kind)
28
35
} else {
29
36
let layout_cx = LayoutCx { tcx, param_env : param_env_and_ty. param_env } ;
30
- might_permit_raw_init_lax ( tcx . layout_of ( param_env_and_ty ) ? , & layout_cx, kind)
37
+ might_permit_raw_init_lax ( layout , & layout_cx, kind)
31
38
}
32
39
}
33
40
@@ -36,7 +43,7 @@ pub fn might_permit_raw_init<'tcx>(
36
43
fn might_permit_raw_init_strict < ' tcx > (
37
44
ty : TyAndLayout < ' tcx > ,
38
45
tcx : TyCtxt < ' tcx > ,
39
- kind : InitKind ,
46
+ kind : ValidityRequirement ,
40
47
) -> Result < bool , LayoutError < ' tcx > > {
41
48
let machine = CompileTimeInterpreter :: new (
42
49
Limit :: new ( 0 ) ,
@@ -50,7 +57,7 @@ fn might_permit_raw_init_strict<'tcx>(
50
57
. allocate ( ty, MemoryKind :: Machine ( crate :: const_eval:: MemoryKind :: Heap ) )
51
58
. expect ( "OOM: failed to allocate for uninit check" ) ;
52
59
53
- if kind == InitKind :: Zero {
60
+ if kind == ValidityRequirement :: Zero {
54
61
cx. write_bytes_ptr (
55
62
allocated. ptr ,
56
63
std:: iter:: repeat ( 0_u8 ) . take ( ty. layout . size ( ) . bytes_usize ( ) ) ,
@@ -72,15 +79,18 @@ fn might_permit_raw_init_strict<'tcx>(
72
79
fn might_permit_raw_init_lax < ' tcx > (
73
80
this : TyAndLayout < ' tcx > ,
74
81
cx : & LayoutCx < ' tcx , TyCtxt < ' tcx > > ,
75
- init_kind : InitKind ,
82
+ init_kind : ValidityRequirement ,
76
83
) -> Result < bool , LayoutError < ' tcx > > {
77
84
let scalar_allows_raw_init = move |s : Scalar | -> bool {
78
85
match init_kind {
79
- InitKind :: Zero => {
86
+ ValidityRequirement :: Inhabited => {
87
+ bug ! ( "ValidityRequirement::Inhabited should have been handled above" )
88
+ }
89
+ ValidityRequirement :: Zero => {
80
90
// The range must contain 0.
81
91
s. valid_range ( cx) . contains ( 0 )
82
92
}
83
- InitKind :: UninitMitigated0x01Fill => {
93
+ ValidityRequirement :: UninitMitigated0x01Fill => {
84
94
// The range must include an 0x01-filled buffer.
85
95
let mut val: u128 = 0x01 ;
86
96
for _ in 1 ..s. size ( cx) . bytes ( ) {
0 commit comments