11use rustc_abi:: { BackendRepr , FieldsShape , Scalar , Variants } ;
2- use rustc_middle:: bug ;
2+ use rustc_middle:: query :: TyCtxtAt ;
33use rustc_middle:: ty:: layout:: {
44 HasTyCtxt , LayoutCx , LayoutError , LayoutOf , TyAndLayout , ValidityRequirement ,
55} ;
6- use rustc_middle:: ty:: { PseudoCanonicalInput , Ty , TyCtxt } ;
6+ use rustc_middle:: ty:: { PseudoCanonicalInput , ScalarInt , Ty , TyCtxt } ;
7+ use rustc_middle:: { bug, span_bug, ty} ;
78
89use crate :: const_eval:: { CanAccessMutGlobal , CheckAlignment , CompileTimeMachine } ;
910use crate :: interpret:: { InterpCx , MemoryKind } ;
@@ -34,7 +35,7 @@ pub fn check_validity_requirement<'tcx>(
3435
3536 let layout_cx = LayoutCx :: new ( tcx, input. typing_env ) ;
3637 if kind == ValidityRequirement :: Uninit || tcx. sess . opts . unstable_opts . strict_init_checks {
37- check_validity_requirement_strict ( layout, & layout_cx, kind)
38+ Ok ( check_validity_requirement_strict ( layout, & layout_cx, kind) )
3839 } else {
3940 check_validity_requirement_lax ( layout, & layout_cx, kind)
4041 }
@@ -46,7 +47,7 @@ fn check_validity_requirement_strict<'tcx>(
4647 ty : TyAndLayout < ' tcx > ,
4748 cx : & LayoutCx < ' tcx > ,
4849 kind : ValidityRequirement ,
49- ) -> Result < bool , & ' tcx LayoutError < ' tcx > > {
50+ ) -> bool {
5051 let machine = CompileTimeMachine :: new ( CanAccessMutGlobal :: No , CheckAlignment :: Error ) ;
5152
5253 let mut cx = InterpCx :: new ( cx. tcx ( ) , rustc_span:: DUMMY_SP , cx. typing_env , machine) ;
@@ -69,14 +70,13 @@ fn check_validity_requirement_strict<'tcx>(
6970 // due to this.
7071 // The value we are validating is temporary and discarded at the end of this function, so
7172 // there is no point in reseting provenance and padding.
72- Ok ( cx
73- . validate_operand (
74- & allocated. into ( ) ,
75- /*recursive*/ false ,
76- /*reset_provenance_and_padding*/ false ,
77- )
78- . discard_err ( )
79- . is_some ( ) )
73+ cx. validate_operand (
74+ & allocated. into ( ) ,
75+ /*recursive*/ false ,
76+ /*reset_provenance_and_padding*/ false ,
77+ )
78+ . discard_err ( )
79+ . is_some ( )
8080}
8181
8282/// Implements the 'lax' (default) version of the [`check_validity_requirement`] checks; see that
@@ -168,3 +168,31 @@ fn check_validity_requirement_lax<'tcx>(
168168
169169 Ok ( true )
170170}
171+
172+ pub ( crate ) fn validate_scalar_in_layout < ' tcx > (
173+ tcx : TyCtxtAt < ' tcx > ,
174+ scalar : ScalarInt ,
175+ ty : Ty < ' tcx > ,
176+ ) -> bool {
177+ let machine = CompileTimeMachine :: new ( CanAccessMutGlobal :: No , CheckAlignment :: Error ) ;
178+
179+ let typing_env = ty:: TypingEnv :: fully_monomorphized ( ) ;
180+ let mut cx = InterpCx :: new ( tcx. tcx , tcx. span , typing_env, machine) ;
181+
182+ let Ok ( layout) = cx. layout_of ( ty) else {
183+ span_bug ! ( tcx. span, "could not compute layout of {scalar:?}:{ty:?}" )
184+ } ;
185+ let allocated = cx
186+ . allocate ( layout, MemoryKind :: Machine ( crate :: const_eval:: MemoryKind :: Heap ) )
187+ . expect ( "OOM: failed to allocate for uninit check" ) ;
188+
189+ cx. write_scalar ( scalar, & allocated) . unwrap ( ) ;
190+
191+ cx. validate_operand (
192+ & allocated. into ( ) ,
193+ /*recursive*/ false ,
194+ /*reset_provenance_and_padding*/ false ,
195+ )
196+ . discard_err ( )
197+ . is_some ( )
198+ }
0 commit comments