@@ -63,38 +63,46 @@ pub fn provide(providers: &mut Providers) {
63
63
64
64
use crate :: const_eval:: CompileTimeInterpreter ;
65
65
use crate :: interpret:: { InterpCx , MemoryKind , OpTy } ;
66
+ use rustc_middle:: ty:: layout:: LayoutCx ;
66
67
use rustc_middle:: ty:: { layout:: TyAndLayout , ParamEnv , TyCtxt } ;
67
68
use rustc_session:: Limit ;
68
69
use rustc_span:: Span ;
70
+ use rustc_target:: abi:: InitKind ;
69
71
70
- pub fn is_uninit_valid < ' tcx > ( tcx : TyCtxt < ' tcx > , root_span : Span , ty : TyAndLayout < ' tcx > ) -> bool {
71
- let machine = CompileTimeInterpreter :: new ( Limit :: new ( 0 ) , false ) ;
72
- let mut cx = InterpCx :: new ( tcx, root_span, ParamEnv :: reveal_all ( ) , machine) ;
73
- let allocated = cx
74
- . allocate ( ty, MemoryKind :: Machine ( const_eval:: MemoryKind :: Heap ) )
75
- . expect ( "failed to allocate for uninit check" ) ;
76
- let ot: OpTy < ' _ , _ > = allocated. into ( ) ;
77
- cx. validate_operand ( & ot) . is_ok ( )
78
- }
79
-
80
- pub fn is_zero_valid < ' tcx > ( tcx : TyCtxt < ' tcx > , root_span : Span , ty : TyAndLayout < ' tcx > ) -> bool {
81
- let machine = CompileTimeInterpreter :: new ( Limit :: new ( 0 ) , false ) ;
72
+ pub fn might_permit_raw_init < ' tcx > (
73
+ tcx : TyCtxt < ' tcx > ,
74
+ root_span : Span ,
75
+ ty : TyAndLayout < ' tcx > ,
76
+ strict : bool ,
77
+ kind : InitKind ,
78
+ ) -> bool {
79
+ if strict {
80
+ let machine = CompileTimeInterpreter :: new ( Limit :: new ( 0 ) , false ) ;
82
81
83
- let mut cx = InterpCx :: new ( tcx, root_span, ParamEnv :: reveal_all ( ) , machine) ;
82
+ let mut cx = InterpCx :: new ( tcx, root_span, ParamEnv :: reveal_all ( ) , machine) ;
84
83
85
- // We could panic here... Or we could just return "yeah it's valid whatever". Or let
86
- // codegen_panic_intrinsic return an error that halts compilation.
87
- // I'm not exactly sure *when* this can fail. OOM?
88
- let allocated = cx
89
- . allocate ( ty, MemoryKind :: Machine ( const_eval:: MemoryKind :: Heap ) )
90
- . expect ( "failed to allocate for uninit check" ) ;
84
+ // We could panic here... Or we could just return "yeah it's valid whatever". Or let
85
+ // codegen_panic_intrinsic return an error that halts compilation.
86
+ // I'm not exactly sure *when* this can fail. OOM?
87
+ let allocated = cx
88
+ . allocate ( ty, MemoryKind :: Machine ( const_eval:: MemoryKind :: Heap ) )
89
+ . expect ( "failed to allocate for uninit check" ) ;
91
90
92
- // Again, unclear what to do here if it fails.
93
- cx. write_bytes_ptr ( allocated. ptr , std:: iter:: repeat ( 0_u8 ) . take ( ty. layout . size ( ) . bytes_usize ( ) ) )
94
- . expect ( "failed to write bytes for zero valid check" ) ;
91
+ if kind == InitKind :: Zero {
92
+ // Again, unclear what to do here if it fails.
93
+ cx. write_bytes_ptr (
94
+ allocated. ptr ,
95
+ std:: iter:: repeat ( 0_u8 ) . take ( ty. layout . size ( ) . bytes_usize ( ) ) ,
96
+ )
97
+ . expect ( "failed to write bytes for zero valid check" ) ;
98
+ }
95
99
96
- let ot: OpTy < ' _ , _ > = allocated. into ( ) ;
100
+ let ot: OpTy < ' _ , _ > = allocated. into ( ) ;
97
101
98
- // Assume that if it failed, it's a validation failure.
99
- cx. validate_operand ( & ot) . is_ok ( )
102
+ // Assume that if it failed, it's a validation failure.
103
+ cx. validate_operand ( & ot) . is_ok ( )
104
+ } else {
105
+ let layout_cx = LayoutCx { tcx, param_env : ParamEnv :: reveal_all ( ) } ;
106
+ !ty. might_permit_raw_init ( & layout_cx, kind)
107
+ }
100
108
}
0 commit comments