@@ -10,19 +10,22 @@ use std::num::NonZero;
1010use either:: { Left , Right } ;
1111
1212use hir:: def:: DefKind ;
13+ use hir:: def_id:: DefId ;
1314use rustc_ast:: Mutability ;
1415use rustc_data_structures:: fx:: FxHashSet ;
1516use rustc_hir as hir;
1617use rustc_middle:: mir:: interpret:: {
1718 ExpectedKind , InterpError , InvalidMetaKind , Misalignment , PointerKind , Provenance ,
1819 ValidationErrorInfo , ValidationErrorKind , ValidationErrorKind :: * ,
1920} ;
20- use rustc_middle:: ty ;
21+ use rustc_middle:: query :: TyCtxtAt ;
2122use rustc_middle:: ty:: layout:: { LayoutOf , TyAndLayout } ;
23+ use rustc_middle:: { mir, ty} ;
2224use rustc_span:: symbol:: { sym, Symbol } ;
2325use rustc_target:: abi:: {
2426 Abi , FieldIdx , Scalar as ScalarAbi , Size , VariantIdx , Variants , WrappingRange ,
2527} ;
28+ use rustc_target:: spec:: abi:: Abi as CallAbi ;
2629
2730use std:: hash:: Hash ;
2831
@@ -37,6 +40,7 @@ use super::InterpError::UndefinedBehavior as Ub;
3740use super :: InterpError :: Unsupported as Unsup ;
3841use super :: UndefinedBehaviorInfo :: * ;
3942use super :: UnsupportedOpInfo :: * ;
43+ use super :: { FnArg , Frame } ;
4044
4145macro_rules! throw_validation_failure {
4246 ( $where: expr, $kind: expr) => { {
@@ -967,7 +971,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
967971 let mut visitor = ValidityVisitor { path, ref_tracking, ctfe_mode, ecx : self } ;
968972
969973 // Run it.
970- match self . run_for_validation ( || visitor. visit_value ( op) ) {
974+ match visitor. visit_value ( op) {
971975 Ok ( ( ) ) => Ok ( ( ) ) ,
972976 // Pass through validation failures and "invalid program" issues.
973977 Err ( err)
@@ -1022,3 +1026,154 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
10221026 self . validate_operand_internal ( op, vec ! [ ] , None , None )
10231027 }
10241028}
1029+
1030+ pub struct ValidationMachine < ' a , ' mir , ' tcx > (
1031+ pub & ' a InterpCx < ' mir , ' tcx , crate :: const_eval:: CompileTimeInterpreter < ' mir , ' tcx > > ,
1032+ ) ;
1033+
1034+ impl < ' a , ' mir , ' tcx > std:: ops:: Deref for ValidationMachine < ' a , ' mir , ' tcx > {
1035+ type Target = crate :: const_eval:: CompileTimeInterpreter < ' mir , ' tcx > ;
1036+
1037+ fn deref ( & self ) -> & Self :: Target {
1038+ & self . 0 . machine
1039+ }
1040+ }
1041+
1042+ impl < ' a , ' mir , ' tcx > Machine < ' mir , ' tcx > for ValidationMachine < ' a , ' mir , ' tcx > {
1043+ super :: compile_time_machine!( <' mir, ' tcx>) ;
1044+
1045+ type MemoryKind = crate :: const_eval:: MemoryKind ;
1046+
1047+ const PANIC_ON_ALLOC_FAIL : bool = false ; // will be raised as a proper error
1048+
1049+ #[ inline( always) ]
1050+ fn enforce_alignment ( ecx : & InterpCx < ' mir , ' tcx , Self > ) -> bool {
1051+ Machine :: enforce_alignment ( ecx. machine . 0 )
1052+ }
1053+
1054+ #[ inline( always) ]
1055+ fn enforce_validity ( ecx : & InterpCx < ' mir , ' tcx , Self > , layout : TyAndLayout < ' tcx > ) -> bool {
1056+ ecx. tcx . sess . opts . unstable_opts . extra_const_ub_checks || layout. abi . is_uninhabited ( )
1057+ }
1058+
1059+ fn load_mir (
1060+ _ecx : & InterpCx < ' mir , ' tcx , Self > ,
1061+ instance : ty:: InstanceDef < ' tcx > ,
1062+ ) -> InterpResult < ' tcx , & ' tcx mir:: Body < ' tcx > > {
1063+ unreachable ! ( "validation tried to load mir of {instance:?}" )
1064+ }
1065+
1066+ fn find_mir_or_eval_fn (
1067+ _ecx : & mut InterpCx < ' mir , ' tcx , Self > ,
1068+ orig_instance : ty:: Instance < ' tcx > ,
1069+ _abi : CallAbi ,
1070+ _args : & [ FnArg < ' tcx > ] ,
1071+ _dest : & MPlaceTy < ' tcx > ,
1072+ _ret : Option < mir:: BasicBlock > ,
1073+ _unwind : mir:: UnwindAction , // unwinding is not supported in consts
1074+ ) -> InterpResult < ' tcx , Option < ( & ' mir mir:: Body < ' tcx > , ty:: Instance < ' tcx > ) > > {
1075+ unreachable ! ( "validation tried to evaluate mir of {orig_instance:?}" )
1076+ }
1077+
1078+ fn panic_nounwind ( _ecx : & mut InterpCx < ' mir , ' tcx , Self > , msg : & str ) -> InterpResult < ' tcx > {
1079+ unreachable ! ( "validation tried to panic: {msg}" )
1080+ }
1081+
1082+ fn call_intrinsic (
1083+ _ecx : & mut InterpCx < ' mir , ' tcx , Self > ,
1084+ instance : ty:: Instance < ' tcx > ,
1085+ _args : & [ OpTy < ' tcx > ] ,
1086+ _dest : & MPlaceTy < ' tcx , Self :: Provenance > ,
1087+ _target : Option < mir:: BasicBlock > ,
1088+ _unwind : mir:: UnwindAction ,
1089+ ) -> InterpResult < ' tcx > {
1090+ unreachable ! ( "validation tried to evaluate intrinsic {instance:?}" )
1091+ }
1092+
1093+ fn assert_panic (
1094+ _ecx : & mut InterpCx < ' mir , ' tcx , Self > ,
1095+ msg : & mir:: AssertMessage < ' tcx > ,
1096+ _unwind : mir:: UnwindAction ,
1097+ ) -> InterpResult < ' tcx > {
1098+ unreachable ! ( "validation tried to panic: {msg:?}" )
1099+ }
1100+
1101+ fn binary_ptr_op (
1102+ _ecx : & InterpCx < ' mir , ' tcx , Self > ,
1103+ _bin_op : mir:: BinOp ,
1104+ _left : & ImmTy < ' tcx > ,
1105+ _right : & ImmTy < ' tcx > ,
1106+ ) -> InterpResult < ' tcx , ( ImmTy < ' tcx > , bool ) > {
1107+ unreachable ! ( "validation does not do binary pointer ops" ) ;
1108+ }
1109+
1110+ fn increment_const_eval_counter ( _ecx : & mut InterpCx < ' mir , ' tcx , Self > ) -> InterpResult < ' tcx > {
1111+ unreachable ! ( "validation does not interpret statements" )
1112+ }
1113+
1114+ #[ inline( always) ]
1115+ fn expose_ptr ( _ecx : & mut InterpCx < ' mir , ' tcx , Self > , _ptr : Pointer ) -> InterpResult < ' tcx > {
1116+ unreachable ! ( "validation does not exposing pointers" )
1117+ }
1118+
1119+ #[ inline( always) ]
1120+ fn init_frame_extra (
1121+ _ecx : & mut InterpCx < ' mir , ' tcx , Self > ,
1122+ _frame : Frame < ' mir , ' tcx > ,
1123+ ) -> InterpResult < ' tcx , Frame < ' mir , ' tcx > > {
1124+ unreachable ! ( "validation does not create stack frames" )
1125+ }
1126+
1127+ #[ inline( always) ]
1128+ fn stack < ' b > (
1129+ ecx : & ' b InterpCx < ' mir , ' tcx , Self > ,
1130+ ) -> & ' b [ Frame < ' mir , ' tcx , Self :: Provenance , Self :: FrameExtra > ] {
1131+ ecx. machine . 0 . stack ( )
1132+ }
1133+
1134+ #[ inline( always) ]
1135+ fn stack_mut < ' b > (
1136+ _ecx : & ' b mut InterpCx < ' mir , ' tcx , Self > ,
1137+ ) -> & ' b mut Vec < Frame < ' mir , ' tcx , Self :: Provenance , Self :: FrameExtra > > {
1138+ unreachable ! ( "validation cannot mutate stack" )
1139+ }
1140+
1141+ fn before_access_global (
1142+ _tcx : TyCtxtAt < ' tcx > ,
1143+ _machine : & Self ,
1144+ _alloc_id : AllocId ,
1145+ _alloc : mir:: interpret:: ConstAllocation < ' tcx > ,
1146+ _static_def_id : Option < DefId > ,
1147+ is_write : bool ,
1148+ ) -> InterpResult < ' tcx > {
1149+ assert ! ( !is_write) ;
1150+ // Do nothing, validation may read globals.
1151+ Ok ( ( ) )
1152+ }
1153+
1154+ fn retag_ptr_value (
1155+ _ecx : & mut InterpCx < ' mir , ' tcx , Self > ,
1156+ kind : mir:: RetagKind ,
1157+ val : & ImmTy < ' tcx , mir:: interpret:: CtfeProvenance > ,
1158+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , mir:: interpret:: CtfeProvenance > > {
1159+ unreachable ! ( "validation does not retag pointers: {val:?}, {kind:?}" )
1160+ }
1161+
1162+ fn before_memory_write (
1163+ _tcx : TyCtxtAt < ' tcx > ,
1164+ _machine : & mut Self ,
1165+ _alloc_extra : & mut Self :: AllocExtra ,
1166+ ( _alloc_id, _immutable) : ( AllocId , bool ) ,
1167+ _range : mir:: interpret:: AllocRange ,
1168+ ) -> InterpResult < ' tcx > {
1169+ unreachable ! ( "validation does not write to memory" )
1170+ }
1171+
1172+ fn before_alloc_read (
1173+ _ecx : & InterpCx < ' mir , ' tcx , Self > ,
1174+ _alloc_id : AllocId ,
1175+ ) -> InterpResult < ' tcx > {
1176+ // Do nothing, validation may read all memory
1177+ Ok ( ( ) )
1178+ }
1179+ }
0 commit comments