@@ -10,7 +10,7 @@ use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem};
1010use rustc_middle:: mir:: AssertMessage ;
1111use rustc_middle:: mir:: interpret:: ReportedErrorInfo ;
1212use rustc_middle:: query:: TyCtxtAt ;
13- use rustc_middle:: ty:: layout:: { HasTypingEnv , TyAndLayout } ;
13+ use rustc_middle:: ty:: layout:: { HasTypingEnv , TyAndLayout , ValidityRequirement } ;
1414use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
1515use rustc_middle:: { bug, mir} ;
1616use rustc_span:: { Span , Symbol , sym} ;
@@ -23,8 +23,8 @@ use crate::fluent_generated as fluent;
2323use crate :: interpret:: {
2424 self , AllocId , AllocInit , AllocRange , ConstAllocation , CtfeProvenance , FnArg , Frame ,
2525 GlobalAlloc , ImmTy , InterpCx , InterpResult , OpTy , PlaceTy , Pointer , RangeSet , Scalar ,
26- compile_time_machine, interp_ok, throw_exhaust, throw_inval, throw_ub, throw_ub_custom ,
27- throw_unsup, throw_unsup_format,
26+ compile_time_machine, err_inval , interp_ok, throw_exhaust, throw_inval, throw_ub,
27+ throw_ub_custom , throw_unsup, throw_unsup_format,
2828} ;
2929
3030/// When hitting this many interpreted terminators we emit a deny by default lint
@@ -462,6 +462,44 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
462462 // (We know the value here in the machine of course, but this is the runtime of that code,
463463 // not the optimization stage.)
464464 sym:: is_val_statically_known => ecx. write_scalar ( Scalar :: from_bool ( false ) , dest) ?,
465+
466+ // We handle these here since Miri does not want to have them.
467+ sym:: assert_inhabited
468+ | sym:: assert_zero_valid
469+ | sym:: assert_mem_uninitialized_valid => {
470+ let ty = instance. args . type_at ( 0 ) ;
471+ let requirement = ValidityRequirement :: from_intrinsic ( intrinsic_name) . unwrap ( ) ;
472+
473+ let should_panic = !ecx
474+ . tcx
475+ . check_validity_requirement ( ( requirement, ecx. typing_env ( ) . as_query_input ( ty) ) )
476+ . map_err ( |_| err_inval ! ( TooGeneric ) ) ?;
477+
478+ if should_panic {
479+ let layout = ecx. layout_of ( ty) ?;
480+
481+ let msg = match requirement {
482+ // For *all* intrinsics we first check `is_uninhabited` to give a more specific
483+ // error message.
484+ _ if layout. is_uninhabited ( ) => format ! (
485+ "aborted execution: attempted to instantiate uninhabited type `{ty}`"
486+ ) ,
487+ ValidityRequirement :: Inhabited => bug ! ( "handled earlier" ) ,
488+ ValidityRequirement :: Zero => format ! (
489+ "aborted execution: attempted to zero-initialize type `{ty}`, which is invalid"
490+ ) ,
491+ ValidityRequirement :: UninitMitigated0x01Fill => format ! (
492+ "aborted execution: attempted to leave type `{ty}` uninitialized, which is invalid"
493+ ) ,
494+ ValidityRequirement :: Uninit => bug ! ( "assert_uninit_valid doesn't exist" ) ,
495+ } ;
496+
497+ Self :: panic_nounwind ( ecx, & msg) ?;
498+ // Skip the `return_to_block` at the end (we panicked, we do not return).
499+ return interp_ok ( None ) ;
500+ }
501+ }
502+
465503 _ => {
466504 // We haven't handled the intrinsic, let's see if we can use a fallback body.
467505 if ecx. tcx . intrinsic ( instance. def_id ( ) ) . unwrap ( ) . must_be_overridden {
0 commit comments